summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRodolfo Alonso Hernandez <ralonsoh@redhat.com>2023-03-15 06:29:39 +0100
committerRodolfo Alonso <ralonsoh@redhat.com>2023-03-21 17:07:51 +0000
commit92e55ab51f228fa26c530eed00eba1ee15508422 (patch)
treeafeb8a9329b9940f68ead3eb00921a35386e1769
parented96c94d41dea3e238e32156c56d2642c94eb68b (diff)
downloadneutron-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.py27
-rw-r--r--neutron/tests/functional/plugins/ml2/drivers/ovn/mech_driver/ovsdb/test_ovn_client.py68
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)