diff --git a/.gitreview b/.gitreview new file mode 100644 index 0000000..d84258b --- /dev/null +++ b/.gitreview @@ -0,0 +1,4 @@ +[gerrit] +host=review.opendev.org +port=29418 +project=openstack/charm-neutron-api-plugin-ovn.git diff --git a/.zuul.yaml b/.zuul.yaml new file mode 100644 index 0000000..7cb4023 --- /dev/null +++ b/.zuul.yaml @@ -0,0 +1,4 @@ +- project: + templates: + - openstack-python3-train-jobs + - openstack-cover-jobs diff --git a/src/config.yaml b/src/config.yaml new file mode 100644 index 0000000..8062957 --- /dev/null +++ b/src/config.yaml @@ -0,0 +1,94 @@ +options: + ovn-l3-scheduler: + type: string + default: leastloaded + description: > + The OVN L3 Scheduler type to use when scheduling router gateway ports. + + Available schedulers: + + - leastloaded - chassis with fewest gateway ports selected (default) + + - chance - chassis randomly selected + ovn-metadata-enabled: + type: boolean + default: True + description: > + Whether to use the metadata service. + + Note: The ``ovn-chassis:nova-compute - nova-compute:neutron-plugin`` + subordinate relation is a prerequisite for this to work. + enable-distributed-floating-ip: + type: boolean + default: False + description: > + This is for specifc use cases only, not generally recommended, see note + below. + + Perform NAT action for floating IPs locally on each chassis. + + Enabling this requires making external Layer3 connectivity available + globally and configuring bridge mappings on all chassis in the + deployment. + + Note: OVN gives you distributed East/West and highly available + North/South routing by default. You do not need to enable this option + to get that. This is for very specific use cases only. + + Enabling it will create a scaling problem at the physical network layer + that needs to be resolved with globally shared Layer2 (does not scale) or + tunneling at the top-of-rack switch layer (adds complexity) and is + generally not a recommended configuration. + geneve-vni-ranges: + type: string + default: "1001:2000" + description: > + Space-delimited list of : tuples enumerating ranges of + Geneve VNI IDs that are available for tenant network allocation. + dns-servers: + type: string + default: + description: > + Space-delimited list of DNS servers to use as forwarders if a subnets + ``dns_nameservers`` field is empty. + dhcp-default-lease-time: + type: int + default: 43200 + description: > + Default lease time (in seconds) to use with OVN's native DHCP service. + ovn-dhcp4-global-options: + type: string + default: + description: > + Dictionary of global DHCPv4 options which will be automatically set on + each subnet upon creation and on all existing subnets when Neutron + starts. + + An empty value for a DHCP option will cause that option to be unset + globally. + + EXAMPLES: + + - ntp_server:1.2.3.4,wpad:1.2.3.5 - Set ntp_server and wpad + + - ntp_server:,wpad:1.2.3.5 - Unset ntp_server and set wpad + + See the ovn-nb(5) man page for available options. + ovn-dhcp6-global-options: + type: string + default: + description: > + Dictionary of global DHCPv4 options which will be automatically set on + each subnet upon creation and on all existing subnets when Neutron + starts. + + An empty value for a DHCP option will cause that option to be unset + globally. + + EXAMPLES: + + - ntp_server:1.2.3.4,wpad:1.2.3.5 - Set ntp_server and wpad + + - ntp_server:,wpad:1.2.3.5 - Unset ntp_server and set wpad + + See the ovn-nb(5) man page for available options. diff --git a/src/layer.yaml b/src/layer.yaml index 9985d6c..145c25d 100644 --- a/src/layer.yaml +++ b/src/layer.yaml @@ -10,4 +10,10 @@ options: repo: https://github.com/openstack/charm-neutron-api-plugin-ovn config: deletes: + - debug - verbose + - ssl_ca + - ssl_cert + - ssl_key + - use-internal-endpoints + - use-syslog diff --git a/src/lib/charm/openstack/neutron_api_plugin_ovn.py b/src/lib/charm/openstack/neutron_api_plugin_ovn.py index 3a28702..e245ff4 100644 --- a/src/lib/charm/openstack/neutron_api_plugin_ovn.py +++ b/src/lib/charm/openstack/neutron_api_plugin_ovn.py @@ -38,7 +38,7 @@ def ovn_ca_cert(cls): class NeutronAPIPluginCharm(charms_openstack.charm.OpenStackCharm): - release = 'stein' + release = 'train' name = 'neutron-api-plugin-ovn' packages = ['python3-networking-ovn'] required_relations = ['neutron-plugin', 'ovsdb-cms'] diff --git a/src/metadata.yaml b/src/metadata.yaml index 4a89a24..9af97c1 100644 --- a/src/metadata.yaml +++ b/src/metadata.yaml @@ -9,7 +9,7 @@ tags: - networking series: - bionic - - disco + - eoan subordinate: true requires: container: diff --git a/src/reactive/neutron_api_plugin_ovn_handlers.py b/src/reactive/neutron_api_plugin_ovn_handlers.py index 4bcf7a0..71dc4f9 100644 --- a/src/reactive/neutron_api_plugin_ovn_handlers.py +++ b/src/reactive/neutron_api_plugin_ovn_handlers.py @@ -61,7 +61,42 @@ def configure_neutron(): tenant_network_types = neutron.neutron_config_data.get( 'tenant_network_types', '').split(',') tenant_network_types.insert(0, 'geneve') + + def _split_if_str(s): + _s = s or '' + return _s.split() + with charm.provide_charm_instance() as instance: + options = instance.adapters_instance.options + sections = { + 'ovn': [ + ('ovn_nb_connection', ','.join(ovsdb.db_nb_connection_strs)), + ('ovn_nb_private_key', options.ovn_key), + ('ovn_nb_certificate', options.ovn_cert), + ('ovn_nb_ca_cert', options.ovn_ca_cert), + ('ovn_sb_connection', ','.join(ovsdb.db_sb_connection_strs)), + ('ovn_sb_private_key', options.ovn_key), + ('ovn_sb_certificate', options.ovn_cert), + ('ovn_sb_ca_cert', options.ovn_ca_cert), + ('ovn_l3_scheduler', options.ovn_l3_scheduler), + ('ovn_metadata_enabled', options.ovn_metadata_enabled), + ('enable_distributed_floating_ip', + options.enable_distributed_floating_ip), + ('dns_servers', ','.join(_split_if_str(options.dns_servers))), + ('dhcp_default_lease_time', options.dhcp_default_lease_time), + ('ovn_dhcp4_global_options', + ','.join(_split_if_str( + options.ovn_dhcp4_global_options))), + ('ovn_dhcp6_global_options', + ','.join( + _split_if_str(options.ovn_dhcp6_global_options))), + ], + 'ml2_type_geneve': [ + ('vni_ranges', ','.join( + _split_if_str(options.geneve_vni_ranges))), + ('max_header_size', '38'), + ], + } neutron.configure_plugin( 'ovn', service_plugins=','.join(service_plugins), @@ -70,35 +105,7 @@ def configure_neutron(): subordinate_configuration={ 'neutron-api': { '/etc/neutron/plugins/ml2/ml2_conf.ini': { - 'sections': { - 'ovn': [ - ('ovn_nb_connection', - ','.join(ovsdb.db_nb_connection_strs)), - ('ovn_nb_private_key', - instance.adapters_instance.options.ovn_key), - ('ovn_nb_certificate', - instance.adapters_instance.options.ovn_cert), - ('ovn_nb_ca_cert', - instance.adapters_instance.options.ovn_ca_cert - ), - ('ovn_sb_connection', - ','.join(ovsdb.db_sb_connection_strs)), - ('ovn_sb_private_key', - instance.adapters_instance.options.ovn_key), - ('ovn_sb_certificate', - instance.adapters_instance.options.ovn_cert), - ('ovn_sb_ca_cert', - instance.adapters_instance.options.ovn_ca_cert - ), - # XXX config - ('ovn_l3_scheduler', 'leastloaded'), - ('ovn_metadata_enabled', 'true'), # XXX config - ], - 'ml2_type_geneve': [ - ('vni_ranges', '1000:2000'), # XXX config - ('max_header_size', '38'), - ], - }, + 'sections': sections, }, }, }, diff --git a/src/test-requirements.txt b/src/test-requirements.txt index 5a78c3e..3640c8b 100644 --- a/src/test-requirements.txt +++ b/src/test-requirements.txt @@ -8,4 +8,4 @@ flake8>=2.2.4,<=2.4.1 stestr>=2.2.0 requests>=2.18.4 git+https://github.com/openstack-charmers/zaza.git#egg=zaza -git+https://github.com/openstack-charmers/zaza-openstack-tests.git@add-ovn#egg=zaza.openstack +git+https://github.com/openstack-charmers/zaza-openstack-tests.git#egg=zaza.openstack diff --git a/src/tests/bundles/bionic-stein.yaml b/src/tests/bundles/bionic-train.yaml similarity index 86% rename from src/tests/bundles/bionic-stein.yaml rename to src/tests/bundles/bionic-train.yaml index 3c4e1a2..1c3ff2e 100644 --- a/src/tests/bundles/bionic-stein.yaml +++ b/src/tests/bundles/bionic-train.yaml @@ -4,20 +4,19 @@ applications: charm: cs:~openstack-charmers-next/keystone num_units: 1 options: - openstack-origin: cloud:bionic-stein + openstack-origin: cloud:bionic-train mysql: charm: cs:~openstack-charmers-next/percona-cluster num_units: 1 neutron-api: - series: bionic charm: cs:~openstack-charmers-next/neutron-api num_units: 3 options: manage-neutron-plugin-legacy-mode: false - openstack-origin: cloud:bionic-stein + openstack-origin: cloud:bionic-train neutron-api-plugin-ovn: series: bionic - charm: neutron-api-plugin-ovn + charm: cs:~openstack-charmers-next/neutron-api-plugin-ovn rabbitmq-server: charm: cs:~openstack-charmers-next/rabbitmq-server num_units: 1 @@ -25,11 +24,10 @@ applications: charm: cs:~openstack-charmers-next/vault num_units: 1 ovn-central: - series: bionic charm: cs:~openstack-charmers-next/ovn-central num_units: 3 options: - source: cloud:bionic-stein + source: cloud:bionic-train relations: - - mysql:shared-db - keystone:shared-db diff --git a/src/tests/bundles/eoan.yaml b/src/tests/bundles/eoan.yaml new file mode 100644 index 0000000..6f2d7e5 --- /dev/null +++ b/src/tests/bundles/eoan.yaml @@ -0,0 +1,53 @@ +series: eoan +applications: + keystone: + charm: cs:~openstack-charmers-next/keystone + num_units: 1 + options: + openstack-origin: distro + mysql: + charm: cs:~openstack-charmers-next/mysql-innodb-cluster + num_units: 3 + neutron-api: + charm: cs:~openstack-charmers-next/neutron-api + num_units: 3 + options: + manage-neutron-plugin-legacy-mode: false + openstack-origin: distro + neutron-api-plugin-ovn: + series: eoan + charm: cs:~openstack-charmers-next/neutron-api-plugin-ovn + rabbitmq-server: + charm: cs:~openstack-charmers-next/rabbitmq-server + num_units: 1 + vault: + charm: cs:~openstack-charmers-next/vault + num_units: 1 + ovn-central: + charm: cs:~openstack-charmers-next/ovn-central + num_units: 3 + options: + source: distro +relations: +- - mysql:shared-db + - keystone:shared-db +- - mysql:shared-db + - neutron-api:shared-db +- - neutron-api:amqp + - rabbitmq-server:amqp +- - neutron-api:identity-service + - keystone:identity-service +- - neutron-api-plugin-ovn:neutron-plugin + - neutron-api:neutron-plugin-api-subordinate +- - neutron-api-plugin-ovn:ovsdb-cms + - ovn-central:ovsdb-cms +- - vault:shared-db + - mysql:shared-db +- - ovn-central:certificates + - vault:certificates +- - neutron-api-plugin-ovn:certificates + - vault:certificates +- - keystone:certificates + - vault:certificates +- - neutron-api:certificates + - vault:certificates diff --git a/src/tests/tests.yaml b/src/tests/tests.yaml index eae5ced..c25e69b 100644 --- a/src/tests/tests.yaml +++ b/src/tests/tests.yaml @@ -1,11 +1,14 @@ charm_name: neutron-api-plugin-ovn smoke_bundles: -- bionic-stein +- bionic-train +gate_bundles: +- eoan +- bionic-train target_deploy_status: neutron-api-plugin-ovn: workload-status: waiting workload-status-message: "'ovsdb-cms' incomplete" - ovn: + ovn-central: workload-status: blocked workload-status-message: "'certificates' missing" vault: diff --git a/unit_tests/test_reactive_neutron_api_plugin_ovn_handlers.py b/unit_tests/test_reactive_neutron_api_plugin_ovn_handlers.py index 72e804d..68be18b 100644 --- a/unit_tests/test_reactive_neutron_api_plugin_ovn_handlers.py +++ b/unit_tests/test_reactive_neutron_api_plugin_ovn_handlers.py @@ -65,6 +65,10 @@ class TestOvnHandlers(test_utils.PatchHelper): self.charm self.provide_charm_instance().__exit__.return_value = None + def pmock(self, return_value=None): + p = mock.PropertyMock().return_value = return_value + return p + def test_flag_db_migration(self): self.patch_object(handlers.reactive, 'set_flag') handlers.flag_db_migration() @@ -81,6 +85,18 @@ class TestOvnHandlers(test_utils.PatchHelper): 'lbaasv2', 'gre,vlan,flat,local', ] + options = self.charm.adapters_instance.options + options.ovn_key = self.pmock('aKey') + options.ovn_cert = self.pmock('aCert') + options.ovn_ca_cert = self.pmock('aCaCert') + options.ovn_l3_scheduler = self.pmock('aSched') + options.ovn_metadata_enabled = self.pmock('aMetaData') + options.enable_distributed_floating_ip = self.pmock('dont') + options.dns_servers = self.pmock('dns1 dns2') + options.geneve_vni_ranges = self.pmock('vnia:vniA vnib:vniB') + options.dhcp_default_lease_time = self.pmock(42) + options.ovn_dhcp4_global_options = self.pmock('a:A4 b:B4') + options.ovn_dhcp6_global_options = self.pmock('a:A6 b:B6') handlers.configure_neutron() neutron.configure_plugin.assert_called_once_with( 'ovn', @@ -97,19 +113,24 @@ class TestOvnHandlers(test_utils.PatchHelper): 'ovn': [ ('ovn_nb_connection', ''), # FIXME - ('ovn_nb_private_key', mock.ANY), - ('ovn_nb_certificate', mock.ANY), - ('ovn_nb_ca_cert', mock.ANY), + ('ovn_nb_private_key', 'aKey'), + ('ovn_nb_certificate', 'aCert'), + ('ovn_nb_ca_cert', 'aCaCert'), ('ovn_sb_connection', ''), # FIXME - ('ovn_sb_private_key', mock.ANY), - ('ovn_sb_certificate', mock.ANY), - ('ovn_sb_ca_cert', mock.ANY), - ('ovn_l3_scheduler', 'leastloaded'), - ('ovn_metadata_enabled', 'true'), + ('ovn_sb_private_key', 'aKey'), + ('ovn_sb_certificate', 'aCert'), + ('ovn_sb_ca_cert', 'aCaCert'), + ('ovn_l3_scheduler', 'aSched'), + ('ovn_metadata_enabled', 'aMetaData'), + ('enable_distributed_floating_ip', 'dont'), + ('dns_servers', 'dns1,dns2'), + ('dhcp_default_lease_time', 42), + ('ovn_dhcp4_global_options', 'a:A4,b:B4'), + ('ovn_dhcp6_global_options', 'a:A6,b:B6'), ], 'ml2_type_geneve': [ - ('vni_ranges', '1000:2000'), + ('vni_ranges', 'vnia:vniA,vnib:vniB'), ('max_header_size', '38'), ], },