diff options
| author | Jenkins <jenkins@review.openstack.org> | 2012-09-20 02:21:12 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2012-09-20 02:21:12 +0000 |
| commit | 23375b31f5c57aaf792afbac937844b9bc76a930 (patch) | |
| tree | 966219bcb376895a05a8e0e8b8e2b456a5c8b475 | |
| parent | bdeb2d3a444c56075e30b02a2584f7a5df2f1d0e (diff) | |
| parent | ef222bfe6f50d5203f83fa9d2e9071969f814c29 (diff) | |
| download | nova-23375b31f5c57aaf792afbac937844b9bc76a930.tar.gz nova-23375b31f5c57aaf792afbac937844b9bc76a930.tar.xz nova-23375b31f5c57aaf792afbac937844b9bc76a930.zip | |
Merge "Add lookup by ip via Quantum for metadata service."
| -rw-r--r-- | nova/exception.py | 5 | ||||
| -rw-r--r-- | nova/network/quantumv2/api.py | 28 | ||||
| -rw-r--r-- | nova/tests/network/test_quantumv2.py | 38 |
3 files changed, 59 insertions, 12 deletions
diff --git a/nova/exception.py b/nova/exception.py index 4de43c366..28fb1ee0a 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -605,6 +605,11 @@ class FixedIpAlreadyInUse(NovaException): "%(instance_uuid)s.") +class FixedIpAssociatedWithMultipleInstances(NovaException): + message = _("More than one instance is associated with fixed ip address " + "'%(address)s'.") + + class FixedIpInvalid(Invalid): message = _("Fixed IP address %(address)s is invalid.") diff --git a/nova/network/quantumv2/api.py b/nova/network/quantumv2/api.py index 65762cb31..6c47acb1d 100644 --- a/nova/network/quantumv2/api.py +++ b/nova/network/quantumv2/api.py @@ -220,6 +220,18 @@ class API(base.Base): id_str = id_str and id_str + ', ' + _id or _id raise exception.NetworkNotFound(network_id=id_str) + def _get_instance_uuids_by_ip(self, context, address): + """Retrieve instance uuids associated with the given ip address. + + :returns: A list of dicts containing the uuids keyed by 'instance_uuid' + e.g. [{'instance_uuid': uuid}, ...] + """ + search_opts = {"fixed_ips": 'ip_address=%s' % address} + data = quantumv2.get_client(context).list_ports(**search_opts) + ports = data.get('ports', []) + return [{'instance_uuid': port['device_id']} for port in ports + if port['device_id']] + def get_instance_uuids_by_ip_filter(self, context, filters): """Return a list of dicts in the form of [{'instance_uuid': uuid}] that matched the ip filter. @@ -232,12 +244,7 @@ class API(base.Base): if ip[-1] == '$': ip = ip[:-1] ip = ip.replace('\\.', '.') - search_opts = {"fixed_ips": {'ip_address': ip}} - data = quantumv2.get_client(context).list_ports(**search_opts) - ports = data.get('ports', []) - - return [{'instance_uuid': port['device_id']} for port in ports - if port['device_id']] + return self._get_instance_uuids_by_ip(context, ip) def trigger_security_group_members_refresh(self, context, instance_ref): @@ -277,7 +284,14 @@ class API(base.Base): raise NotImplementedError() def get_fixed_ip_by_address(self, context, address): - raise NotImplementedError() + uuid_maps = self._get_instance_uuids_by_ip(context, address) + if len(uuid_maps) == 1: + return uuid_maps[0] + elif not uuid_maps: + raise exception.FixedIpNotFoundForAddress(address=address) + else: + raise exception.FixedIpAssociatedWithMultipleInstances( + address=address) def get_floating_ip(self, context, id): raise NotImplementedError() diff --git a/nova/tests/network/test_quantumv2.py b/nova/tests/network/test_quantumv2.py index f0cfd0ba1..83703707e 100644 --- a/nova/tests/network/test_quantumv2.py +++ b/nova/tests/network/test_quantumv2.py @@ -162,11 +162,12 @@ class TestQuantumv2(test.TestCase): self.nets = [self.nets1, self.nets2, self.nets3, self.nets4] + self.port_address = '10.0.1.2' self.port_data1 = [{'network_id': 'my_netid1', 'device_id': 'device_id1', 'device_owner': 'compute:nova', 'id': 'my_portid1', - 'fixed_ips': [{'ip_address': '10.0.1.2', + 'fixed_ips': [{'ip_address': self.port_address, 'subnet_id': 'my_subid1'}], 'mac_address': 'my_mac1', }] self.dhcp_port_data1 = [{'fixed_ips': [{'ip_address': '10.0.1.9', @@ -546,17 +547,44 @@ class TestQuantumv2(test.TestCase): except exception.NetworkNotFound as ex: self.assertTrue("my_netid2, my_netid3" in str(ex)) - def test_get_instance_uuids_by_ip_filter(self): - filters = {'ip': '^10\\.0\\.1\\.2$'} + def _mock_list_ports(self, port_data=None): + if port_data is None: + port_data = self.port_data2 + address = self.port_address self.moxed_client.list_ports( - fixed_ips=MyComparator({'ip_address': '10.0.1.2'})).AndReturn( - {'ports': self.port_data2}) + fixed_ips=MyComparator('ip_address=%s' % address)).AndReturn( + {'ports': port_data}) self.mox.ReplayAll() + return address + + def test_get_instance_uuids_by_ip_filter(self): + self._mock_list_ports() + filters = {'ip': '^10\\.0\\.1\\.2$'} api = quantumapi.API() result = api.get_instance_uuids_by_ip_filter(self.context, filters) self.assertEquals('device_id1', result[0]['instance_uuid']) self.assertEquals('device_id2', result[1]['instance_uuid']) + def test_get_fixed_ip_by_address_fails_for_no_ports(self): + address = self._mock_list_ports(port_data=[]) + api = quantumapi.API() + self.assertRaises(exception.FixedIpNotFoundForAddress, + api.get_fixed_ip_by_address, + self.context, address) + + def test_get_fixed_ip_by_address_succeeds_for_1_port(self): + address = self._mock_list_ports(port_data=self.port_data1) + api = quantumapi.API() + result = api.get_fixed_ip_by_address(self.context, address) + self.assertEquals('device_id1', result['instance_uuid']) + + def test_get_fixed_ip_by_address_fails_for_more_than_1_port(self): + address = self._mock_list_ports() + api = quantumapi.API() + self.assertRaises(exception.FixedIpAssociatedWithMultipleInstances, + api.get_fixed_ip_by_address, + self.context, address) + def _get_available_networks(self, prv_nets, pub_nets, req_ids=None): api = quantumapi.API() nets = prv_nets + pub_nets |
