From 35c15317144b3f00d2e83954914f2178eb419c65 Mon Sep 17 00:00:00 2001 From: James Denton Date: Fri, 23 Dec 2022 04:02:55 +0000 Subject: [PATCH] Implement support for octavia-ovn-provider driver This patch is the second of two required to implement the octavia-ovn-provider driver for Octavia. A new var, octavia_ovn_enabled, can be used to install the driver and configure Octavia accordingly. This patch has also restructured the driver/plugin mechanism for the os_octavia role to better mirror that of os_neutron and to make future additions easier to implement. It also uses neutron's method of certificate delivery for the ovn certs. Depends-On: https://review.opendev.org/c/openstack/openstack-ansible/+/908292 Change-Id: Ic5963070f4f2504860ddf0829819ca2f301546b1 Signed-off-by: Matthew Thode --- defaults/main.yml | 104 ++++++++++++++++-- ...-ovn-provider-driver-3efd5e7e77291b78.yaml | 13 +++ tasks/main.yml | 3 +- tasks/octavia_install.yml | 6 +- templates/octavia.conf.j2 | 21 +++- vars/main.yml | 8 ++ 6 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 releasenotes/notes/octavia-ovn-provider-driver-3efd5e7e77291b78.yaml diff --git a/defaults/main.yml b/defaults/main.yml index 0abe9628..14160ca0 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 }}" @@ -195,7 +200,10 @@ octavia_plugin_dirs: - /usr/lib/octavia - /usr/local/lib/octavia -# Common pip packages +### +### Python code details +### + octavia_pip_packages: - cryptography - keystonemiddleware @@ -213,19 +221,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: @@ -261,6 +276,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: @@ -449,13 +472,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 # @@ -472,6 +510,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' @@ -485,6 +524,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 }}" @@ -537,6 +587,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: @@ -555,37 +612,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" @@ -598,7 +674,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 @@ -629,8 +709,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 6aaf89bd..16fd2d8f 100644 --- a/tasks/main.yml +++ b/tasks/main.yml @@ -129,7 +129,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 @@ -150,7 +150,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 ffe0255c..91ba45be 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 @@ -191,3 +191,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/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.