diff --git a/defaults/main.yml b/defaults/main.yml index 447d61f0..277b3eae 100644 --- a/defaults/main.yml +++ b/defaults/main.yml @@ -44,10 +44,15 @@ octavia_legacy_policy: False # Options are 'present' and 'latest' octavia_package_state: "{{ package_state | default('latest') }}" +# Source git repo/branch settings octavia_git_repo: https://opendev.org/openstack/octavia octavia_git_install_branch: master octavia_upper_constraints_url: >- {{ requirements_git_url | default('https://releases.openstack.org/constraints/upper/' ~ requirements_git_install_branch | default('master')) }} + +octavia_ovn_octavia_provider_git_repo: https://opendev.org/openstack/ovn-octavia-provider +octavia_ovn_octavia_provider_git_install_branch: master + octavia_git_constraints: - "--constraint {{ octavia_upper_constraints_url }}" @@ -202,7 +207,10 @@ octavia_plugin_dirs: - /usr/lib/octavia - /usr/local/lib/octavia -# Common pip packages +### +### Python code details +### + octavia_pip_packages: - cryptography - keystonemiddleware @@ -220,19 +228,26 @@ octavia_pip_packages: - systemd-python - "tooz[{{ octavia_coordination_driver }}]" -# Memcached override -octavia_memcached_servers: "{{ memcached_servers }}" - # Specific pip packages provided by the user octavia_user_pip_packages: [] octavia_optional_oslomsg_amqp1_pip_packages: - oslo.messaging[amqp1] +octavia_optional_ovn_octavia_provider_pip_packages: + - "git+{{ octavia_ovn_octavia_provider_git_repo }}@{{ octavia_ovn_octavia_provider_git_install_branch }}#egg=ovn-octavia-provider" + + +# Memcached override +octavia_memcached_servers: "{{ memcached_servers }}" + octavia_api_init_overrides: {} octavia_worker_init_overrides: {} octavia_housekeeping_init_overrides: {} octavia_health_manager_init_overrides: {} +octavia_driver_agent_init_overrides: + Service: + Killmode: process ## Service Name-Group Mapping octavia_services: @@ -268,6 +283,14 @@ octavia_services: init_config_overrides: "{{ octavia_health_manager_init_overrides }}" execstarts: "{{ octavia_bin }}/octavia-health-manager" execreloads: "/bin/kill -HUP $MAINPID" + octavia-driver-agent: + group: octavia-api + service_name: octavia-driver-agent + service_en: "{{ octavia_ovn_enabled }}" + start_order: 5 + init_config_overrides: "{{ octavia_driver_agent_init_overrides }}" + execstarts: "{{ octavia_bin }}/octavia-driver-agent --config-file /etc/octavia/octavia.conf" + execreloads: "/bin/kill -HUP $MAINPID" # Required secrets for the role octavia_required_secrets: @@ -463,13 +486,28 @@ octavia_uwsgi_tls: key: "{{ octavia_api_ssl_key }}" # Set up the drivers +# Provider agents are optional and not required for a successful Octavia provider driver +# Possible options: amphora_agent, noop_agent, ovn +octavia_enabled_provider_agents: [] octavia_enabled_provider_drivers: - "amphorav2:'The Octavia Amphora v2 driver.'" + - "{{ (octavia_ovn_enabled | bool) | ternary(\"ovn:'The Octavia OVN provider driver.'\", False) }}" octavia_default_provider_driver: "amphorav2" octavia_amphora_driver: amphora_haproxy_rest_driver octavia_compute_driver: compute_nova_driver octavia_network_driver: allowed_address_pairs_driver +# OVN Defaults +octavia_ovn_enabled: "{{ neutron_plugin_type | default('ml2.ovn') == 'ml2.ovn' }}" +octavia_ovn_ssl: "{{ neutron_ovn_ssl | default(True) }}" +octavia_ovn_proto: "{{ (octavia_ovn_ssl) | ternary('ssl', 'tcp') }}" + +octavia_ovn_nb_connection: >- + {{ octavia_ovn_proto }}:{{ groups['neutron_ovn_northd'] | map('extract', hostvars, ['ansible_host']) | join(':6641,' + octavia_ovn_proto + ':') }}:6641 +octavia_ovn_sb_connection: >- + {{ octavia_ovn_proto }}:{{ groups['neutron_ovn_northd'] | map('extract', hostvars, ['ansible_host']) | join(':6642,' + octavia_ovn_proto + ':') }}:6642 + + # # Certificate generation # @@ -486,6 +524,7 @@ octavia_cert_dir: "{{ openstack_pki_dir | default(lookup('env', 'HOME') ~ '/open octavia_cert_keys_dir: "{{ octavia_cert_dir }}/certs/private/" octavia_cert_certs_dir: "{{ octavia_cert_dir }}/certs/certs/" octavia_cert_dir_owner: "{{ lookup('env', 'USER') }}" +octavia_cert_dest_dir: "/etc/octavia/certs" octavia_cert_client_req_common_name: 'www.example.com' # change this to something more real octavia_cert_client_req_country_name: 'US' @@ -499,6 +538,17 @@ octavia_generate_ca: True octavia_regenerate_client_cert: '' octavia_regenerate_ca: '' +# OVN server certificate +# The local address used for the ovn certificate +octavia_ovn_node_address: "{{ management_address | default('127.0.0.1') }}" +# OVN destination files for SSL certificates +octavia_ovn_pki_intermediate_cert_name: "{{ octavia_api_intermediate_cert_name }}" +octavia_ovn_pki_intermediate_chain_path: >- + {{ octavia_cert_dir ~ '/roots/' ~ octavia_ovn_pki_intermediate_cert_name ~ '/certs/' ~ octavia_ovn_pki_intermediate_cert_name ~ '-chain.crt' }} +octavia_ovn_ssl_cert: "octavia_ovn.pem" +octavia_ovn_ssl_key: "octavia_ovn.key" +octavia_ovn_ssl_ca_cert: "octavia_ovn-ca.pem" + octavia_cert_authorities: - name: "OctaviaServerRoot" country: "{{ octavia_cert_client_req_country_name }}" @@ -551,6 +601,13 @@ octavia_cert_certificates: - clientAuth - emailProtection condition: "{{ octavia_generate_certs | bool }}" + # OVN NB/SB communication + - name: "octavia_ovn_{{ ansible_facts['hostname'] }}" + provider: ownca + cn: "{{ ansible_facts['hostname'] }}" + san: "{{ 'DNS:' ~ ansible_facts['hostname'] ~ ',IP:' ~ octavia_ovn_node_address }}" + signed_by: "{{ octavia_ovn_pki_intermediate_cert_name }}" + condition: "{{ (octavia_ovn_ssl and octavia_ovn_enabled) }}" # Installation details for SSL certificates octavia_cert_install_certificates: @@ -569,37 +626,56 @@ octavia_cert_install_certificates: condition: "{{ octavia_backend_ssl | bool }}" # Server CA - src: "{{ octavia_ca_certificate | default(octavia_cert_dir ~ '/roots/OctaviaServerRoot/certs/OctaviaServerRoot.crt') }}" - dest: "/etc/octavia/certs/server_ca.pem" + dest: "{{ octavia_cert_dest_dir }}/server_ca.pem" owner: "{{ octavia_system_user_name }}" group: "{{ octavia_system_group_name }}" mode: "0640" condition: "{{ octavia_generate_certs | bool }}" - src: "{{ octavia_ca_private_key | default(octavia_cert_dir ~ '/roots/OctaviaServerRoot/private/OctaviaServerRoot.key.pem') }}" - dest: "/etc/octavia/certs/ca_key.pem" + dest: "{{ octavia_cert_dest_dir }}/ca_key.pem" owner: "{{ octavia_system_user_name }}" group: "{{ octavia_system_group_name }}" mode: "0640" condition: "{{ octavia_generate_certs | bool }}" # Client CA - src: "{{ octavia_client_ca | default(octavia_cert_dir ~ '/roots/OctaviaClientRoot/certs/OctaviaClientRoot.crt') }}" - dest: "/etc/octavia/certs/client_ca.pem" + dest: "{{ octavia_cert_dest_dir }}/client_ca.pem" owner: "{{ octavia_system_user_name }}" group: "{{ octavia_system_group_name }}" mode: "0640" condition: "{{ octavia_generate_certs | bool }}" # Client certificate - src: "{{ octavia_client_cert | default(octavia_cert_certs_dir ~ '/octavia_client.crt') }}" - dest: "/etc/octavia/certs/client.pem.crt" + dest: "{{ octavia_cert_dest_dir }}/client.pem.crt" owner: "{{ octavia_system_user_name }}" group: "{{ octavia_system_group_name }}" mode: "0640" condition: "{{ octavia_generate_certs | bool }}" - src: "{{ octavia_client_key | default(octavia_cert_keys_dir ~ '/octavia_client.key.pem') }}" - dest: "/etc/octavia/certs/client.pem.key" + dest: "{{ octavia_cert_dest_dir }}/client.pem.key" owner: "{{ octavia_system_user_name }}" group: "{{ octavia_system_group_name }}" mode: "0640" condition: "{{ octavia_generate_certs | bool }}" + # OVN certificates + - src: "{{ octavia_ovn_user_ssl_cert | default(octavia_cert_certs_dir ~ 'octavia_ovn_' ~ ansible_facts['hostname'] ~ '-chain.crt') }}" + dest: "{{ [octavia_cert_dest_dir, octavia_ovn_ssl_cert] | join('/') }}" + owner: "{{ octavia_system_user_name }}" + group: "{{ octavia_system_group_name }}" + mode: "0644" + condition: "{{ (octavia_ovn_ssl and octavia_ovn_enabled) }}" + - src: "{{ octavia_ovn_user_ssl_key | default(octavia_cert_keys_dir ~ 'octavia_ovn_' ~ ansible_facts['hostname'] ~ '.key.pem') }}" + dest: "{{ [octavia_cert_dest_dir, octavia_ovn_ssl_key] | join('/') }}" + owner: "{{ octavia_system_user_name }}" + group: "{{ octavia_system_group_name }}" + mode: "0600" + condition: "{{ (octavia_ovn_ssl and octavia_ovn_enabled) }}" + - src: "{{ octavia_ovn_user_ssl_ca_cert | default(octavia_ovn_pki_intermediate_chain_path) }}" + dest: "{{ [octavia_cert_dest_dir, octavia_ovn_ssl_ca_cert] | join('/') }}" + owner: "{{ octavia_system_user_name }}" + group: "{{ octavia_system_group_name }}" + mode: "0644" + condition: "{{ (octavia_ovn_ssl and octavia_ovn_enabled) }}" # Custom client CA # octavia_client_ca: "{{ octavia_cert_dir }}/ca_01.pem" @@ -612,7 +688,11 @@ octavia_cert_install_certificates: # octavia_ca_private_key: "{{ octavia_cert_dir }}/private/cakey.pem" octavia_ca_private_key_passphrase: "{{ octavia_cert_client_password }}" # octavia_ca_certificate: "{{ octavia_cert_dir }}/ca_server_01.pem" - +# Custom OVN certs +# octavia_ovnnb_user_ssl_cert: +# octavia_ovnnb_user_ssl_key: +# octavia_ovnsb_user_ssl_cert: +# octavia_ovnsb_user_ssl_key: # Quotas for the Octavia user - assuming active/passive topology octavia_num_instances: 10000 # 5000 LB in active/passive @@ -643,8 +723,8 @@ octavia_api_intermediate_cert_name: "{{ openstack_pki_service_intermediate_cert_ octavia_api_cert_san: "{{ openstack_pki_san | default('DNS:' ~ ansible_facts['hostname'] ~ ',IP:' ~ management_address) }}" # octavia destination files for SSL certificates -octavia_api_ssl_cert: /etc/octavia/certs/octavia-api.pem -octavia_api_ssl_key: /etc/octavia/certs/octavia-api.key +octavia_api_ssl_cert: "{{ octavia_cert_dest_dir }}/octavia-api.pem" +octavia_api_ssl_key: "{{ octavia_cert_dest_dir }}/octavia-api.key" # Define user-provided SSL certificates # octavia_api_user_ssl_cert: diff --git a/releasenotes/notes/octavia-ovn-provider-driver-3efd5e7e77291b78.yaml b/releasenotes/notes/octavia-ovn-provider-driver-3efd5e7e77291b78.yaml new file mode 100644 index 00000000..3a2d2994 --- /dev/null +++ b/releasenotes/notes/octavia-ovn-provider-driver-3efd5e7e77291b78.yaml @@ -0,0 +1,13 @@ +--- +features: + - | + A new parameter, `octavia_ovn_enabled`, is added to support the + Octavia OVN provider driver. The Octavia OVN provider driver + is an alternative to amphora and uses built-in support for + load balancing withing OVN/OVS. The `ml2.ovn` Neutron plugin + is required for this functionality. The OVN provider can be used + during load balancer creation by specifying the `--provider ovn` + argument for the `openstack loadbalancer create` command. + - | + Added new variable ``octavia_enabled_provider_agents`` that allows + to enable Provider Agents for Octavia. diff --git a/tasks/main.yml b/tasks/main.yml index e106f369..7e12f949 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -132,7 +132,7 @@ pki_certificates: "{{ octavia_cert_certificates }}" pki_install_certificates: "{{ octavia_cert_install_certificates }}" when: - - (octavia_generate_certs | bool) or (octavia_backend_ssl | bool) + - (octavia_generate_certs | bool) or (octavia_backend_ssl | bool) or (octavia_ovn_ssl | bool) tags: - always @@ -153,7 +153,6 @@ - octavia-config - octavia-install - - name: Importing octavia_install tasks import_tasks: octavia_install.yml tags: diff --git a/tasks/octavia_install.yml b/tasks/octavia_install.yml index 87f43837..2b99ef26 100644 --- a/tasks/octavia_install.yml +++ b/tasks/octavia_install.yml @@ -34,11 +34,7 @@ venv_install_destination_path: "{{ octavia_bin | dirname }}" venv_install_distro_package_list: "{{ octavia_distro_packages }}" venv_pip_install_args: "{{ octavia_pip_install_args }}" - venv_pip_packages: >- - {{ - octavia_pip_packages | union(octavia_user_pip_packages) + - (octavia_oslomsg_amqp1_enabled | bool) | ternary(octavia_optional_oslomsg_amqp1_pip_packages, []) - }} + venv_pip_packages: "{{ _octavia_venv_packages }}" venv_facts_when_changed: - section: "octavia" option: "venv_tag" diff --git a/templates/octavia.conf.j2 b/templates/octavia.conf.j2 index 0ea43b66..52878da9 100644 --- a/templates/octavia.conf.j2 +++ b/templates/octavia.conf.j2 @@ -16,7 +16,7 @@ auth_strategy = {{ octavia_auth_strategy }} allow_tls_terminated_listeners = {{ octavia_tls_listener_enabled }} default_provider_driver = {{ octavia_default_provider_driver }} -enabled_provider_drivers = {{ octavia_enabled_provider_drivers | join(',') }} +enabled_provider_drivers = {{ octavia_enabled_provider_drivers | select() | join(',') }} [oslo_messaging] topic = octavia_prov @@ -195,3 +195,22 @@ endpoint_type = {{ octavia_clients_endpoint }} [neutron] region_name = {{ keystone_service_region }} endpoint_type = {{ octavia_clients_endpoint }} + +{% if octavia_enabled_provider_agents | length > 0 %} +[driver_agent] +enabled_provider_agents = "{{ octavia_enabled_provider_agents | join(',') }} +{% endif %} + +{% if octavia_ovn_enabled %} +[ovn] +ovn_nb_connection = {{ octavia_ovn_nb_connection }} +ovn_sb_connection = {{ octavia_ovn_sb_connection }} +{% if octavia_ovn_ssl %} +ovn_sb_ca_cert={{ ["/etc/octavia/certs", octavia_ovn_ssl_ca_cert] | join('/') }} +ovn_sb_certificate={{ ["/etc/octavia/certs", octavia_ovn_ssl_cert] | join('/') }} +ovn_sb_private_key={{ ["/etc/octavia/certs", octavia_ovn_ssl_key] | join('/') }} +ovn_nb_ca_cert={{ ["/etc/octavia/certs", octavia_ovn_ssl_ca_cert] | join('/') }} +ovn_nb_certificate={{ ["/etc/octavia/certs", octavia_ovn_ssl_cert] | join('/') }} +ovn_nb_private_key={{ ["/etc/octavia/certs", octavia_ovn_ssl_key] | join('/') }} +{% endif %} +{% endif %} diff --git a/vars/debian.yml b/vars/debian.yml index 0e28c593..9ae4bbe7 100644 --- a/vars/debian.yml +++ b/vars/debian.yml @@ -31,5 +31,6 @@ octavia_service_distro_packages: - octavia-health-manager - octavia-housekeeping - octavia-worker + - "{{ octavia_ovn_enabled | ternary('python3-ovn-octavia-provider', '') }}" - python3-pymysql - python3-systemd diff --git a/vars/distro_install.yml b/vars/distro_install.yml index 1a1b4581..b6912b4e 100644 --- a/vars/distro_install.yml +++ b/vars/distro_install.yml @@ -1,4 +1,4 @@ --- -octavia_package_list: "{{ octavia_distro_packages + octavia_service_distro_packages }}" +octavia_package_list: "{{ (octavia_distro_packages + octavia_service_distro_packages) | select }}" _octavia_bin: "/usr/bin" diff --git a/vars/main.yml b/vars/main.yml index 0e5f13c9..790ae2a1 100644 --- a/vars/main.yml +++ b/vars/main.yml @@ -31,6 +31,14 @@ _octavia_oslomsg_notify_vhost_conf: >- octavia_oslomsg_notify_vhost, octavia_oslomsg_notify_vhost | selectattr('state', 'eq', 'present') | map(attribute='name') | first) }} +_octavia_venv_packages: >- + {%- set pkg_list = octavia_pip_packages | union(octavia_user_pip_packages) + + (octavia_oslomsg_amqp1_enabled | bool) | ternary(octavia_optional_oslomsg_amqp1_pip_packages, []) %} + {%- if octavia_ovn_enabled %} + {%- set _ = pkg_list.extend(octavia_optional_ovn_octavia_provider_pip_packages) %} + {%- endif %} + {{- pkg_list | unique }} + # # Compile a list of the services on a host based on whether # the host is in the host group and the service is enabled. diff --git a/vars/redhat.yml b/vars/redhat.yml index c232cd19..6e1e6879 100644 --- a/vars/redhat.yml +++ b/vars/redhat.yml @@ -28,4 +28,5 @@ octavia_service_distro_packages: - openstack-octavia-health-manager - openstack-octavia-housekeeping - openstack-octavia-worker + - "{{ octavia_ovn_enabled | ternary('python3-ovn-octavia-provider', '') }}" - python3-systemd diff --git a/zuul.d/jobs.yaml b/zuul.d/jobs.yaml new file mode 100644 index 00000000..474efb94 --- /dev/null +++ b/zuul.d/jobs.yaml @@ -0,0 +1,24 @@ +--- +# Copyright 2024, Cleura AB. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- job: + name: openstack-ansible-deploy-aio_lxc_ovnprovider-ubuntu-jammy + parent: openstack-ansible-deploy-aio + nodeset: ubuntu-jammy + +- job: + name: openstack-ansible-deploy-aio_lxc_ovnprovider-rockylinux-9 + parent: openstack-ansible-deploy-aio + nodeset: rockylinux-9 diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml index 68a6b22b..af5df09f 100644 --- a/zuul.d/project.yaml +++ b/zuul.d/project.yaml @@ -24,9 +24,13 @@ check: jobs: + - openstack-ansible-deploy-aio_lxc_ovnprovider-ubuntu-jammy + - openstack-ansible-deploy-aio_lxc_ovnprovider-rockylinux-9 - openstack-ansible-deploy-aio_metal-centos-9-stream: voting: false gate: jobs: + - openstack-ansible-deploy-aio_lxc_ovnprovider-ubuntu-jammy + - openstack-ansible-deploy-aio_lxc_ovnprovider-rockylinux-9 - openstack-ansible-deploy-aio_metal-centos-9-stream: voting: false