summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark McClain <mark.mcclain@dreamhost.com>2012-10-30 23:54:45 -0400
committerMark McClain <mark.mcclain@dreamhost.com>2012-10-31 13:26:06 -0400
commit9e40f9cb239e6348432451eaf87a04e59016ea18 (patch)
tree529acac4c3151ce68e7e959c9a1e1df0d5e46b62
parent73066e842c44e72d60cfe7d6cda0a17b1efeb5b9 (diff)
make QuantumV2 support requested nic ordering
fixes bug 1064524 The QuantumV2 did not honor nic ordering, so nics were attached in Quantum's db natural order. This patch sorts the networks honor requested nic ordering when Nova calls the V2Quantum API. Unit tests have been updated to confirm ordering is honored. Change-Id: I44a6a4736c78e86e83b6e682e63f93a5b47652da
-rw-r--r--nova/network/quantumv2/api.py18
-rw-r--r--nova/tests/network/test_quantumv2.py51
2 files changed, 60 insertions, 9 deletions
diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py
index 594d7b2f2..31d16f7e1 100644
--- a/nova/network/quantumv2/api.py
+++ b/nova/network/quantumv2/api.py
@@ -90,6 +90,11 @@ class API(base.Base):
search_opts['id'] = net_ids
nets += quantum.list_networks(**search_opts).get('networks', [])
+ _ensure_requested_network_ordering(
+ lambda x: x['id'],
+ nets,
+ net_ids)
+
return nets
def allocate_for_instance(self, context, instance, **kwargs):
@@ -532,6 +537,13 @@ class API(base.Base):
if not networks:
networks = self._get_available_networks(context,
instance['project_id'])
+ else:
+ # ensure ports are in preferred network order
+ _ensure_requested_network_ordering(
+ lambda x: x['network_id'],
+ ports,
+ [n['id'] for n in networks])
+
nw_info = network_model.NetworkInfo()
for port in ports:
network_name = None
@@ -645,3 +657,9 @@ class API(base.Base):
def create_public_dns_domain(self, context, domain, project=None):
"""Create a private DNS domain with optional nova project."""
raise NotImplementedError()
+
+
+def _ensure_requested_network_ordering(accessor, unordered, preferred):
+ """Sort a list with respect to the preferred network ordering."""
+ if preferred:
+ unordered.sort(key=lambda i: preferred.index(accessor(i)))
diff --git a/nova/tests/network/test_quantumv2.py b/nova/tests/network/test_quantumv2.py
index edb477b70..a8f29e012 100644
--- a/nova/tests/network/test_quantumv2.py
+++ b/nova/tests/network/test_quantumv2.py
@@ -351,35 +351,37 @@ class TestQuantumv2(test.TestCase):
self.moxed_client.show_port(port_id).AndReturn(
{'port': {'id': 'my_portid1',
'network_id': 'my_netid1'}})
- req_net_ids.append('my_netid1')
ports['my_netid1'] = self.port_data1[0]
id = 'my_netid1'
else:
fixed_ips[id] = fixed_ip
req_net_ids.append(id)
+ expected_network_order = req_net_ids
+ else:
+ expected_network_order = [n['id'] for n in nets]
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'],
shared=False)
if search_ids:
- mox_list_network_params['id'] = search_ids
+ mox_list_network_params['id'] = mox.SameElementsAs(search_ids)
self.moxed_client.list_networks(
**mox_list_network_params).AndReturn({'networks': nets})
mox_list_network_params = dict(shared=True)
if search_ids:
- mox_list_network_params['id'] = search_ids
+ mox_list_network_params['id'] = mox.SameElementsAs(search_ids)
self.moxed_client.list_networks(
**mox_list_network_params).AndReturn({'networks': []})
- for network in nets:
+ for net_id in expected_network_order:
port_req_body = {
'port': {
'device_id': self.instance['uuid'],
'device_owner': 'compute:nova',
},
}
- port = ports.get(network['id'], None)
+ port = ports.get(net_id, None)
if port:
port_id = port['id']
self.moxed_client.update_port(port_id,
@@ -387,10 +389,10 @@ class TestQuantumv2(test.TestCase):
).AndReturn(
{'port': port})
else:
- fixed_ip = fixed_ips.get(network['id'])
+ fixed_ip = fixed_ips.get(net_id)
if fixed_ip:
port_req_body['port']['fixed_ip'] = fixed_ip
- port_req_body['port']['network_id'] = network['id']
+ port_req_body['port']['network_id'] = net_id
port_req_body['port']['admin_state_up'] = True
port_req_body['port']['tenant_id'] = \
self.instance['project_id']
@@ -410,8 +412,9 @@ class TestQuantumv2(test.TestCase):
def test_allocate_for_instance_with_requested_networks(self):
# specify only first and last network
- requested_networks = [(net['id'], None, None)
- for net in (self.nets3[0], self.nets3[-1])]
+ requested_networks = [
+ (net['id'], None, None)
+ for net in (self.nets3[1], self.nets3[0], self.nets3[2])]
self._allocate_for_instance(net_idx=3,
requested_networks=requested_networks)
@@ -902,3 +905,33 @@ class TestQuantumv2(test.TestCase):
self.mox.ReplayAll()
api.disassociate_floating_ip(self.context, self.instance, address)
+
+
+class TestQuantumv2ModuleMethods(test.TestCase):
+ def test_ensure_requested_network_ordering_no_preference(self):
+ l = [1, 2, 3]
+
+ quantumapi._ensure_requested_network_ordering(
+ lambda x: x,
+ l,
+ None)
+
+ def test_ensure_requested_network_ordering_no_preference(self):
+ l = [{'id': 3}, {'id': 1}, {'id': 2}]
+
+ quantumapi._ensure_requested_network_ordering(
+ lambda x: x['id'],
+ l,
+ None)
+
+ self.assertEqual(l, [{'id': 3}, {'id': 1}, {'id': 2}])
+
+ def test_ensure_requested_network_ordering_with_preference(self):
+ l = [{'id': 3}, {'id': 1}, {'id': 2}]
+
+ quantumapi._ensure_requested_network_ordering(
+ lambda x: x['id'],
+ l,
+ [1, 2, 3])
+
+ self.assertEqual(l, [{'id': 1}, {'id': 2}, {'id': 3}])