Merge "Reject user ports that have MACs the hypervisor cannot use."

This commit is contained in:
Jenkins 2013-01-16 00:04:25 +00:00 committed by Gerrit Code Review
commit 6c1eae946d
3 changed files with 36 additions and 8 deletions

View File

@ -522,6 +522,10 @@ class PortNotFound(NotFound):
message = _("Port %(port_id)s could not be found.")
class PortNotUsable(NovaException):
message = _("Port %(port_id)s not usable for instance %(instance)s.")
class FixedIpNotFound(NotFound):
message = _("No fixed IP associated with id %(id)s.")

View File

@ -113,6 +113,7 @@ class API(base.Base):
with requested_networks which is user supplied).
NB: QuantumV2 does not yet honour mac address limits.
"""
hypervisor_macs = kwargs.get('macs', None)
quantum = quantumv2.get_client(context)
LOG.debug(_('allocate_for_instance() for %s'),
instance['display_name'])
@ -127,7 +128,11 @@ class API(base.Base):
if requested_networks:
for network_id, fixed_ip, port_id in requested_networks:
if port_id:
port = quantum.show_port(port_id).get('port')
port = quantum.show_port(port_id)['port']
if hypervisor_macs is not None:
if port['mac_address'] not in hypervisor_macs:
raise exception.PortNotUsable(port_id=port_id,
instance=instance['display_name'])
network_id = port['network_id']
ports[network_id] = port
elif fixed_ip:

View File

@ -342,15 +342,11 @@ class TestQuantumv2(test.TestCase):
self.assertEquals('my_mac%s' % id_suffix, nw_inf[0]['address'])
self.assertEquals(0, len(nw_inf[0]['network']['subnets']))
def _allocate_for_instance(self, net_idx=1, **kwargs):
def _stub_allocate_for_instance(self, net_idx=1, **kwargs):
api = quantumapi.API()
self.mox.StubOutWithMock(api, 'get_instance_nw_info')
# Net idx is 1-based for compatibility with existing unit tests
nets = self.nets[net_idx - 1]
api.get_instance_nw_info(mox.IgnoreArg(),
self.instance,
networks=nets).AndReturn(None)
ports = {}
fixed_ips = {}
req_net_ids = []
@ -359,7 +355,8 @@ class TestQuantumv2(test.TestCase):
if port_id:
self.moxed_client.show_port(port_id).AndReturn(
{'port': {'id': 'my_portid1',
'network_id': 'my_netid1'}})
'network_id': 'my_netid1',
'mac_address': 'my_mac1'}})
ports['my_netid1'] = self.port_data1[0]
id = 'my_netid1'
else:
@ -368,6 +365,9 @@ class TestQuantumv2(test.TestCase):
expected_network_order = req_net_ids
else:
expected_network_order = [n['id'] for n in nets]
if kwargs.get('_break_list_networks'):
self.mox.ReplayAll()
return api
search_ids = [net['id'] for net in nets if net['id'] in req_net_ids]
mox_list_network_params = dict(tenant_id=self.instance['project_id'],
@ -409,7 +409,15 @@ class TestQuantumv2(test.TestCase):
res_port = {'port': {'id': 'fake'}}
self.moxed_client.create_port(
MyComparator(port_req_body)).AndReturn(res_port)
api.get_instance_nw_info(mox.IgnoreArg(),
self.instance,
networks=nets).AndReturn(None)
self.mox.ReplayAll()
return api
def _allocate_for_instance(self, net_idx=1, **kwargs):
api = self._stub_allocate_for_instance(net_idx, **kwargs)
api.allocate_for_instance(self.context, self.instance, **kwargs)
def test_allocate_for_instance_1(self):
@ -428,6 +436,18 @@ class TestQuantumv2(test.TestCase):
# The macs kwarg should be accepted, as a set.
self._allocate_for_instance(1, macs=set(['ab:cd:ef:01:23:45']))
def test_allocate_for_instance_mac_conflicting_requested_port(self):
# specify only first and last network
requested_networks = [(None, None, 'my_portid1')]
api = self._stub_allocate_for_instance(
net_idx=1, requested_networks=requested_networks,
macs=set(['unknown:mac']),
_break_list_networks=True)
self.assertRaises(exception.PortNotUsable,
api.allocate_for_instance, self.context,
self.instance, requested_networks=requested_networks,
macs=set(['unknown:mac']))
def test_allocate_for_instance_with_requested_networks(self):
# specify only first and last network
requested_networks = [
@ -443,7 +463,6 @@ class TestQuantumv2(test.TestCase):
requested_networks=requested_networks)
def test_allocate_for_instance_with_requested_networks_with_port(self):
# specify only first and last network
requested_networks = [(None, None, 'myportid1')]
self._allocate_for_instance(net_idx=1,
requested_networks=requested_networks)