Skip to content

Commit 9150206

Browse files
committed
[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 9704dca)
1 parent fec0286 commit 9150206

File tree

2 files changed

+86
-9
lines changed

2 files changed

+86
-9
lines changed

neutron/plugins/ml2/drivers/ovn/mech_driver/ovsdb/ovn_client.py

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2377,17 +2377,26 @@ def _find_metadata_port_ip(self, context, subnet):
23772377
return fixed_ip['ip_address']
23782378

23792379
def create_metadata_port(self, context, network):
2380-
if ovn_conf.is_ovn_metadata_enabled():
2381-
metadata_port = self._find_metadata_port(context, network['id'])
2382-
if not metadata_port:
2383-
# Create a neutron port for DHCP/metadata services
2384-
port = {'port':
2385-
{'network_id': network['id'],
2380+
if not ovn_conf.is_ovn_metadata_enabled():
2381+
return
2382+
2383+
if self._find_metadata_port(context, network['id']):
2384+
return
2385+
2386+
# Create a neutron port for DHCP/metadata services
2387+
filters = {'network_id': [network['id']]}
2388+
subnets = self._plugin.get_subnets(context, filters=filters)
2389+
fixed_ips = [{'subnet_id': s['id']}
2390+
for s in subnets if s['enable_dhcp']]
2391+
port = {'port': {'network_id': network['id'],
23862392
'tenant_id': network['project_id'],
23872393
'device_owner': const.DEVICE_OWNER_DISTRIBUTED,
2388-
'device_id': 'ovnmeta-%s' % network['id']}}
2389-
# TODO(boden): rehome create_port into neutron-lib
2390-
p_utils.create_port(self._plugin, context, port)
2394+
'device_id': 'ovnmeta-%s' % network['id'],
2395+
'fixed_ips': fixed_ips,
2396+
}
2397+
}
2398+
# TODO(boden): rehome create_port into neutron-lib
2399+
p_utils.create_port(self._plugin, context, port)
23912400

23922401
def update_metadata_port(self, context, network_id, subnet=None):
23932402
"""Update metadata port.
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Copyright 2023 Red Hat, Inc.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"); you may
4+
# not use this file except in compliance with the License. You may obtain
5+
# a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12+
# License for the specific language governing permissions and limitations
13+
# under the License.
14+
15+
from neutron_lib import constants
16+
17+
from neutron.conf.plugins.ml2.drivers.ovn import ovn_conf as ovn_config
18+
from neutron.tests.functional import base
19+
20+
21+
class TestOVNClient(base.TestOVNFunctionalBase):
22+
23+
def test_create_metadata_port(self):
24+
def check_metadata_port(enable_dhcp):
25+
ports = self.plugin.get_ports(
26+
self.context, filters={'network_id': [network['id']]})
27+
self.assertEqual(1, len(ports))
28+
if enable_dhcp:
29+
self.assertEqual(1, len(ports[0]['fixed_ips']))
30+
else:
31+
self.assertEqual(0, len(ports[0]['fixed_ips']))
32+
return ports
33+
34+
ovn_config.cfg.CONF.set_override('ovn_metadata_enabled', True,
35+
group='ovn')
36+
ovn_client = self.mech_driver._ovn_client
37+
for enable_dhcp in (True, False):
38+
network_args = {'tenant_id': 'project_1',
39+
'name': 'test_net_1',
40+
'admin_state_up': True,
41+
'shared': False,
42+
'status': constants.NET_STATUS_ACTIVE}
43+
network = self.plugin.create_network(self.context,
44+
{'network': network_args})
45+
subnet_args = {'tenant_id': 'project_1',
46+
'name': 'test_snet_1',
47+
'network_id': network['id'],
48+
'ip_version': constants.IP_VERSION_4,
49+
'cidr': '10.210.10.0/28',
50+
'enable_dhcp': enable_dhcp,
51+
'gateway_ip': constants.ATTR_NOT_SPECIFIED,
52+
'allocation_pools': constants.ATTR_NOT_SPECIFIED,
53+
'dns_nameservers': constants.ATTR_NOT_SPECIFIED,
54+
'host_routes': constants.ATTR_NOT_SPECIFIED}
55+
self.plugin.create_subnet(self.context, {'subnet': subnet_args})
56+
57+
# The metadata port has been created during the network creation.
58+
ports = check_metadata_port(enable_dhcp)
59+
60+
# Force the deletion and creation the metadata port.
61+
self.plugin.delete_port(self.context, ports[0]['id'])
62+
ovn_client.create_metadata_port(self.context, network)
63+
check_metadata_port(enable_dhcp)
64+
65+
# Call again the "create_metadata_port" method as is idempotent
66+
# because it checks first if the metadata port exists.
67+
ovn_client.create_metadata_port(self.context, network)
68+
check_metadata_port(enable_dhcp)

0 commit comments

Comments
 (0)