diff options
author | Rodolfo Alonso Hernandez <ralonsoh@redhat.com> | 2023-03-15 06:29:39 +0100 |
---|---|---|
committer | Rodolfo Alonso <ralonsoh@redhat.com> | 2023-03-21 17:07:51 +0000 |
commit | 92e55ab51f228fa26c530eed00eba1ee15508422 (patch) | |
tree | afeb8a9329b9940f68ead3eb00921a35386e1769 | |
parent | ed96c94d41dea3e238e32156c56d2642c94eb68b (diff) | |
download | neutron-92e55ab51f228fa26c530eed00eba1ee15508422.tar.gz |
[OVN] Explicitly define the fixed IPs for the metadata port
The metadata port fixed IPs depend on the subnets "enabled_dhcp" flag.
If the subnet has this flag disabled, the metadata port doesn't receive
an IP on the subnet CIDR.
The method ``create_metadata_port`` should explicitly define what fixed
IPs should request the metadata port during the creating depending on
the subnets "enabled_dhcp" flag.
Closes-Bug: #2011724
Change-Id: If362fab20ac03f8b62471b60c031f9349171ce93
(cherry picked from commit 9704dca84ea3ad21ecf9730eea03692daeddf382)
-rw-r--r-- | neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py | 27 | ||||
-rw-r--r-- | neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py | 68 |
2 files changed, 86 insertions, 9 deletions
diff --git a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py index ba6f4f4e4c..cc7041e6b4 100644 --- a/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py +++ b/neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py @@ -2329,17 +2329,26 @@ class OVNClient(object): return fixed_ip['ip_address'] def create_metadata_port(self, context, network): - if ovn_conf.is_ovn_metadata_enabled(): - metadata_port = self._find_metadata_port(context, network['id']) - if not metadata_port: - # Create a neutron port for DHCP/metadata services - port = {'port': - {'network_id': network['id'], + if not ovn_conf.is_ovn_metadata_enabled(): + return + + if self._find_metadata_port(context, network['id']): + return + + # Create a neutron port for DHCP/metadata services + filters = {'network_id': [network['id']]} + subnets = self._plugin.get_subnets(context, filters=filters) + fixed_ips = [{'subnet_id': s['id']} + for s in subnets if s['enable_dhcp']] + port = {'port': {'network_id': network['id'], 'tenant_id': network['project_id'], 'device_owner': const.DEVICE_OWNER_DISTRIBUTED, - 'device_id': 'ovnmeta-%s' % network['id']}} - # TODO(boden): rehome create_port into neutron-lib - p_utils.create_port(self._plugin, context, port) + 'device_id': 'ovnmeta-%s' % network['id'], + 'fixed_ips': fixed_ips, + } + } + # TODO(boden): rehome create_port into neutron-lib + p_utils.create_port(self._plugin, context, port) def update_metadata_port(self, context, network_id, subnet=None): """Update metadata port. diff --git a/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py new file mode 100644 index 0000000000..6a9b5a0938 --- /dev/null +++ b/neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py @@ -0,0 +1,68 @@ +# Copyright 2023 Red Hat, Inc. +# +# 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. + +from neutron_lib import constants + +from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf as ovn_config +from neutron.tests.functional import base + + +class TestOVNClient(base.TestOVNFunctionalBase): + + def test_create_metadata_port(self): + def check_metadata_port(enable_dhcp): + ports = self.plugin.get_ports( + self.context, filters={'network_id': [network['id']]}) + self.assertEqual(1, len(ports)) + if enable_dhcp: + self.assertEqual(1, len(ports[0]['fixed_ips'])) + else: + self.assertEqual(0, len(ports[0]['fixed_ips'])) + return ports + + ovn_config.cfg.CONF.set_override('ovn_metadata_enabled', True, + group='ovn') + ovn_client = self.mech_driver._ovn_client + for enable_dhcp in (True, False): + network_args = {'tenant_id': 'project_1', + 'name': 'test_net_1', + 'admin_state_up': True, + 'shared': False, + 'status': constants.NET_STATUS_ACTIVE} + network = self.plugin.create_network(self.context, + {'network': network_args}) + subnet_args = {'tenant_id': 'project_1', + 'name': 'test_snet_1', + 'network_id': network['id'], + 'ip_version': constants.IP_VERSION_4, + 'cidr': '10.210.10.0/28', + 'enable_dhcp': enable_dhcp, + 'gateway_ip': constants.ATTR_NOT_SPECIFIED, + 'allocation_pools': constants.ATTR_NOT_SPECIFIED, + 'dns_nameservers': constants.ATTR_NOT_SPECIFIED, + 'host_routes': constants.ATTR_NOT_SPECIFIED} + self.plugin.create_subnet(self.context, {'subnet': subnet_args}) + + # The metadata port has been created during the network creation. + ports = check_metadata_port(enable_dhcp) + + # Force the deletion and creation the metadata port. + self.plugin.delete_port(self.context, ports[0]['id']) + ovn_client.create_metadata_port(self.context, network) + check_metadata_port(enable_dhcp) + + # Call again the "create_metadata_port" method as is idempotent + # because it checks first if the metadata port exists. + ovn_client.create_metadata_port(self.context, network) + check_metadata_port(enable_dhcp) |