diff options
| author | Mark McClain <mark.mcclain@dreamhost.com> | 2012-10-30 23:54:45 -0400 |
|---|---|---|
| committer | Mark McClain <mark.mcclain@dreamhost.com> | 2012-10-31 13:26:06 -0400 |
| commit | 9e40f9cb239e6348432451eaf87a04e59016ea18 (patch) | |
| tree | 529acac4c3151ce68e7e959c9a1e1df0d5e46b62 | |
| parent | 73066e842c44e72d60cfe7d6cda0a17b1efeb5b9 (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.py | 18 | ||||
| -rw-r--r-- | nova/tests/network/test_quantumv2.py | 51 |
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}]) |
