Merge "[OVN] Update metadata port ony for requested subnet" into stable/victoria
This commit is contained in:
commit
a97046e981
|
@ -1951,7 +1951,8 @@ class OVNClient(object):
|
|||
def create_subnet(self, context, subnet, network):
|
||||
if subnet['enable_dhcp']:
|
||||
if subnet['ip_version'] == 4:
|
||||
self.update_metadata_port(context, network['id'])
|
||||
self.update_metadata_port(context, network['id'],
|
||||
subnet_id=subnet['id'])
|
||||
self._add_subnet_dhcp_options(subnet, network)
|
||||
db_rev.bump_revision(context, subnet, ovn_const.TYPE_SUBNETS)
|
||||
|
||||
|
@ -1968,7 +1969,8 @@ class OVNClient(object):
|
|||
subnet['id'])['subnet']
|
||||
|
||||
if subnet['enable_dhcp'] or ovn_subnet:
|
||||
self.update_metadata_port(context, network['id'])
|
||||
self.update_metadata_port(context, network['id'],
|
||||
subnet_id=subnet['id'])
|
||||
|
||||
check_rev_cmd = self._nb_idl.check_revision_number(
|
||||
subnet['id'], subnet, ovn_const.TYPE_SUBNETS)
|
||||
|
@ -2076,12 +2078,24 @@ class OVNClient(object):
|
|||
# TODO(boden): rehome create_port into neutron-lib
|
||||
p_utils.create_port(self._plugin, context, port)
|
||||
|
||||
def update_metadata_port(self, context, network_id):
|
||||
def update_metadata_port(self, context, network_id, subnet_id=None):
|
||||
"""Update metadata port.
|
||||
|
||||
This function will allocate an IP address for the metadata port of
|
||||
the given network in all its IPv4 subnets.
|
||||
the given network in all its IPv4 subnets or the given subnet.
|
||||
"""
|
||||
def update_metadata_port_fixed_ips(metadata_port, subnet_ids):
|
||||
wanted_fixed_ips = [
|
||||
{'subnet_id': fixed_ip['subnet_id'],
|
||||
'ip_address': fixed_ip['ip_address']} for fixed_ip in
|
||||
metadata_port['fixed_ips']]
|
||||
wanted_fixed_ips.extend({'subnet_id': s_id} for s_id in subnet_ids)
|
||||
port = {'id': metadata_port['id'],
|
||||
'port': {'network_id': network_id,
|
||||
'fixed_ips': wanted_fixed_ips}}
|
||||
self._plugin.update_port(n_context.get_admin_context(),
|
||||
metadata_port['id'], port)
|
||||
|
||||
if not ovn_conf.is_ovn_metadata_enabled():
|
||||
return
|
||||
|
||||
|
@ -2092,31 +2106,28 @@ class OVNClient(object):
|
|||
network_id)
|
||||
return
|
||||
|
||||
port_subnet_ids = set(ip['subnet_id'] for ip in
|
||||
metadata_port['fixed_ips'])
|
||||
|
||||
# If this method is called from "create_subnet" or "update_subnet",
|
||||
# only the fixed IP address from this subnet should be updated in the
|
||||
# metadata port.
|
||||
if subnet_id:
|
||||
if subnet_id not in port_subnet_ids:
|
||||
update_metadata_port_fixed_ips(metadata_port, [subnet_id])
|
||||
return
|
||||
|
||||
# Retrieve all subnets in this network
|
||||
subnets = self._plugin.get_subnets(context, filters=dict(
|
||||
network_id=[network_id], ip_version=[4]))
|
||||
|
||||
subnet_ids = set(s['id'] for s in subnets)
|
||||
port_subnet_ids = set(ip['subnet_id'] for ip in
|
||||
metadata_port['fixed_ips'])
|
||||
|
||||
# Find all subnets where metadata port doesn't have an IP in and
|
||||
# allocate one.
|
||||
if subnet_ids != port_subnet_ids:
|
||||
wanted_fixed_ips = []
|
||||
for fixed_ip in metadata_port['fixed_ips']:
|
||||
wanted_fixed_ips.append(
|
||||
{'subnet_id': fixed_ip['subnet_id'],
|
||||
'ip_address': fixed_ip['ip_address']})
|
||||
wanted_fixed_ips.extend(
|
||||
dict(subnet_id=s)
|
||||
for s in subnet_ids - port_subnet_ids)
|
||||
|
||||
port = {'id': metadata_port['id'],
|
||||
'port': {'network_id': network_id,
|
||||
'fixed_ips': wanted_fixed_ips}}
|
||||
self._plugin.update_port(n_context.get_admin_context(),
|
||||
metadata_port['id'], port)
|
||||
update_metadata_port_fixed_ips(metadata_port,
|
||||
subnet_ids - port_subnet_ids)
|
||||
|
||||
def get_parent_port(self, port_id):
|
||||
return self._nb_idl.get_parent_port(port_id)
|
||||
|
|
|
@ -1504,13 +1504,13 @@ class TestOVNMechanismDriver(test_plugin.Ml2PluginV2TestCase):
|
|||
self.mech_driver.update_subnet_postcommit(context)
|
||||
esd.assert_called_once_with(
|
||||
context.current, context.network.current, mock.ANY)
|
||||
umd.assert_called_once_with(mock.ANY, 'id')
|
||||
umd.assert_called_once_with(mock.ANY, 'id', subnet_id='subnet_id')
|
||||
|
||||
def test_update_subnet_postcommit_disable_dhcp(self):
|
||||
self.mech_driver._nb_ovn.get_subnet_dhcp_options.return_value = {
|
||||
'subnet': mock.sentinel.subnet, 'ports': []}
|
||||
context = fakes.FakeSubnetContext(
|
||||
subnet={'enable_dhcp': False, 'id': 'fake_id', 'ip_version': 4,
|
||||
subnet={'enable_dhcp': False, 'id': 'subnet_id', 'ip_version': 4,
|
||||
'network_id': 'id'},
|
||||
network={'id': 'id'})
|
||||
with mock.patch.object(
|
||||
|
@ -1521,7 +1521,7 @@ class TestOVNMechanismDriver(test_plugin.Ml2PluginV2TestCase):
|
|||
'update_metadata_port') as umd:
|
||||
self.mech_driver.update_subnet_postcommit(context)
|
||||
dsd.assert_called_once_with(context.current['id'], mock.ANY)
|
||||
umd.assert_called_once_with(mock.ANY, 'id')
|
||||
umd.assert_called_once_with(mock.ANY, 'id', subnet_id='subnet_id')
|
||||
|
||||
def test_update_subnet_postcommit_update_dhcp(self):
|
||||
self.mech_driver._nb_ovn.get_subnet_dhcp_options.return_value = {
|
||||
|
@ -1539,7 +1539,63 @@ class TestOVNMechanismDriver(test_plugin.Ml2PluginV2TestCase):
|
|||
self.mech_driver.update_subnet_postcommit(context)
|
||||
usd.assert_called_once_with(
|
||||
context.current, context.network.current, mock.ANY)
|
||||
umd.assert_called_once_with(mock.ANY, 'id')
|
||||
umd.assert_called_once_with(mock.ANY, 'id', subnet_id='subnet_id')
|
||||
|
||||
def test_update_metadata_port_with_subnet_present_in_port(self):
|
||||
ovn_conf.cfg.CONF.set_override('ovn_metadata_enabled', True,
|
||||
group='ovn')
|
||||
fixed_ips = [{'subnet_id': 'subnet1', 'ip_address': 'ip_add1'}]
|
||||
with mock.patch.object(
|
||||
self.mech_driver._ovn_client, '_find_metadata_port',
|
||||
return_value={'fixed_ips': fixed_ips, 'id': 'metadata_id'}), \
|
||||
mock.patch.object(self.mech_driver._plugin, 'get_subnets',
|
||||
return_value=[{'id': 'subnet1'},
|
||||
{'id': 'subnet2'}]), \
|
||||
mock.patch.object(self.mech_driver._plugin, 'update_port') as \
|
||||
mock_update_port:
|
||||
self.mech_driver._ovn_client.update_metadata_port(
|
||||
self.context, 'net_id', subnet_id='subnet1')
|
||||
mock_update_port.assert_not_called()
|
||||
|
||||
def test_update_metadata_port_with_subnet_not_present_in_port(self):
|
||||
ovn_conf.cfg.CONF.set_override('ovn_metadata_enabled', True,
|
||||
group='ovn')
|
||||
fixed_ips = [{'subnet_id': 'subnet1', 'ip_address': 'ip_add1'}]
|
||||
with mock.patch.object(
|
||||
self.mech_driver._ovn_client, '_find_metadata_port',
|
||||
return_value={'fixed_ips': fixed_ips, 'id': 'metadata_id'}), \
|
||||
mock.patch.object(self.mech_driver._plugin, 'get_subnets',
|
||||
return_value=[{'id': 'subnet1'},
|
||||
{'id': 'subnet2'}]), \
|
||||
mock.patch.object(self.mech_driver._plugin, 'update_port') as \
|
||||
mock_update_port:
|
||||
self.mech_driver._ovn_client.update_metadata_port(
|
||||
self.context, 'net_id', subnet_id='subnet3')
|
||||
fixed_ips.append({'subnet_id': 'subnet3'})
|
||||
port = {'id': 'metadata_id', 'port': {
|
||||
'network_id': 'net_id', 'fixed_ips': fixed_ips}}
|
||||
mock_update_port.assert_called_once_with(
|
||||
mock.ANY, 'metadata_id', port)
|
||||
|
||||
def test_update_metadata_port_no_subnet(self):
|
||||
ovn_conf.cfg.CONF.set_override('ovn_metadata_enabled', True,
|
||||
group='ovn')
|
||||
fixed_ips = [{'subnet_id': 'subnet1', 'ip_address': 'ip_add1'}]
|
||||
with mock.patch.object(
|
||||
self.mech_driver._ovn_client, '_find_metadata_port',
|
||||
return_value={'fixed_ips': fixed_ips, 'id': 'metadata_id'}), \
|
||||
mock.patch.object(self.mech_driver._plugin, 'get_subnets',
|
||||
return_value=[{'id': 'subnet1'},
|
||||
{'id': 'subnet2'}]), \
|
||||
mock.patch.object(self.mech_driver._plugin, 'update_port') as \
|
||||
mock_update_port:
|
||||
self.mech_driver._ovn_client.update_metadata_port(self.context,
|
||||
'net_id')
|
||||
fixed_ips.append({'subnet_id': 'subnet2'})
|
||||
port = {'id': 'metadata_id', 'port': {
|
||||
'network_id': 'net_id', 'fixed_ips': fixed_ips}}
|
||||
mock_update_port.assert_called_once_with(
|
||||
mock.ANY, 'metadata_id', port)
|
||||
|
||||
@mock.patch.object(provisioning_blocks, 'is_object_blocked')
|
||||
@mock.patch.object(provisioning_blocks, 'provisioning_complete')
|
||||
|
|
Loading…
Reference in New Issue