Allow both 'network' and 'subnet' in NIC

Fixes and issue where a port cannot be created on
a specific subnet if there are multiple subnets
with the same name on different networks.

Allows both 'network' and 'subnet' in NIC information,
when looking up the subnet filter on the network_id when
both 'network' and 'subnet' is provided.

Story: 2009732
Task: 44152
Change-Id: Ied2d16ec33fe71522c3461d3df6e70fbfdd976b2
This commit is contained in:
Harald Jensås 2021-12-09 15:20:29 +01:00
parent ce81c05548
commit 264836d59a
3 changed files with 66 additions and 3 deletions

View File

@ -131,7 +131,7 @@ class NICs(object):
or ``{"network": "<net ident>", "fixed_ip": "<desired IP>"}``.
:returns: keyword arguments to use when creating a port.
"""
unexpected = set(nic) - {'network', 'fixed_ip'}
unexpected = set(nic) - {'network', 'fixed_ip', 'subnet'}
if unexpected:
raise exceptions.InvalidNIC(
'Unexpected fields for a network: %s' % ', '.join(unexpected))
@ -144,9 +144,25 @@ class NICs(object):
'Cannot find network %(net)s: %(error)s' %
{'net': nic['network'], 'error': exc})
port_args = {'network_id': network.id}
fixed_ip = {}
if nic.get('fixed_ip'):
port_args['fixed_ips'] = [{'ip_address': nic['fixed_ip']}]
fixed_ip['ip_address'] = nic['fixed_ip']
if nic.get('subnet'):
try:
subnet = self._connection.network.find_subnet(
nic['subnet'], network_id=network.id, ignore_missing=False)
except sdk_exc.SDKException as exc:
raise exceptions.InvalidNIC(
'Cannot find subnet %(subnet)s on network %(net)s: '
'%(error)s' %
{'net': nic['network'], 'subnet': nic['subnet'],
'error': exc})
fixed_ip['subnet_id'] = subnet.id
port_args = {'network_id': network.id}
if fixed_ip:
port_args['fixed_ips'] = [fixed_ip]
if self._hostname:
port_args['name'] = '%s-%s' % (self._hostname, network.name)

View File

@ -104,6 +104,45 @@ class TestNICs(unittest.TestCase):
'name': '%s-%s' % (hostname, fake_net.name)},
return_value)
def test_get_network_and_subnet(self):
nic_info = [{'network': 'net-name', 'subnet': 'subnet-name'}]
hostname = 'test-host'
nics = _nics.NICs(self.connection, self.node, nic_info,
hostname=hostname)
fake_net = mock.Mock(id='fake_net_id', name='fake_net_name')
fake_subnet = mock.Mock(id='fake_subnet_id', name='fake_subnet_name')
self.connection.network.find_network.return_value = fake_net
self.connection.network.find_subnet.return_value = fake_subnet
return_value = nics._get_network(nic_info[0])
self.connection.network.find_network.assert_called_once_with(
nic_info[0]['network'], ignore_missing=False)
self.connection.network.find_subnet.assert_called_once_with(
nic_info[0]['subnet'], network_id=fake_net.id,
ignore_missing=False)
self.assertEqual({'network_id': fake_net.id,
'name': '%s-%s' % (hostname, fake_net.name),
'fixed_ips': [{'subnet_id': fake_subnet.id}]},
return_value)
def test_get_network_and_subnet_not_found(self):
nic_info = [{'network': 'net-name', 'subnet': 'subnet-name'}]
hostname = 'test-host'
nics = _nics.NICs(self.connection, self.node, nic_info,
hostname=hostname)
fake_net = mock.Mock(id='fake_net_id', name='fake_net_name')
self.connection.network.find_network.return_value = fake_net
self.connection.network.find_subnet.side_effect = (
sdk_exc.SDKException('SDK_ERROR'))
self.assertRaisesRegex(exceptions.InvalidNIC,
('Cannot find subnet subnet-name on network '
'net-name: SDK_ERROR'),
nics._get_network, nic_info[0])
self.connection.network.find_network.assert_called_once_with(
nic_info[0]['network'], ignore_missing=False)
self.connection.network.find_subnet.assert_called_once_with(
nic_info[0]['subnet'], network_id=fake_net.id,
ignore_missing=False)
def test_get_network_fixed_ip(self):
nic_info = [{'network': 'net-name', 'fixed_ip': '1.1.1.1'}]
hostname = 'test-host'
@ -121,6 +160,7 @@ class TestNICs(unittest.TestCase):
def test_get_network_unexpected_fields(self):
nic_info = [{'network': 'uuid',
'subnet': 'subnet_name',
'fixed_ip': '1.1.1.1',
'unexpected': 'field'}]
nics = _nics.NICs(self.connection, self.node, nic_info,

View File

@ -0,0 +1,7 @@
---
fixes:
- |
It is now possible to create a port on a specific subnet also when multiple
subnets with the same name exist on different networks. See bug:
`2009732 <https://storyboard.openstack.org/#!/story/2009732>`_.