diff --git a/openstack/resource.py b/openstack/resource.py index 15e467b0a..7600dafe6 100644 --- a/openstack/resource.py +++ b/openstack/resource.py @@ -129,14 +129,17 @@ class Resource(collections.MutableMapping): self._attrs = attrs self._dirty = set() if loaded else set(attrs.keys()) self._loaded = loaded - if not self.resource_name: - if self.resource_key: - self.resource_name = self.resource_key - else: - self.resource_name = self.__class__.__name__ def __repr__(self): - return "%s: %s" % (self.resource_name, self._attrs) + return "%s: %s" % (self.get_resource_name(), self._attrs) + + @classmethod + def get_resource_name(cls): + if cls.resource_name: + return cls.resource_name + if cls.resource_key: + return cls.resource_key + return cls().__class__.__name__ ## # CONSTRUCTORS @@ -379,8 +382,12 @@ class Resource(collections.MutableMapping): @classmethod def find(cls, session, name_or_id, path_args=None): try: - info = cls.list(session, id=name_or_id, fields=cls.id_attribute, - path_args=path_args) + args = { + cls.id_attribute: name_or_id, + 'fields': cls.id_attribute, + 'path_args': path_args, + } + info = cls.list(session, **args) if len(info) == 1: return info[0] except exceptions.HttpException: @@ -393,8 +400,8 @@ class Resource(collections.MutableMapping): return info[0] if len(info) > 1: msg = "More than one %s exists with the name '%s'." - msg = (msg % (cls.resource_name, name_or_id)) + msg = (msg % (cls.get_resource_name(), name_or_id)) raise exceptions.DuplicateResource(msg) msg = ("No %s with a name or ID of '%s' exists." % - (cls.resource_name, name_or_id)) + (cls.get_resource_name(), name_or_id)) raise exceptions.ResourceNotFound(msg) diff --git a/openstack/tests/test_resource.py b/openstack/tests/test_resource.py index 3b053db94..fbb4e3423 100644 --- a/openstack/tests/test_resource.py +++ b/openstack/tests/test_resource.py @@ -293,6 +293,20 @@ class TestFind(base.TestCase): self.assertRaises(exceptions.DuplicateResource, FakeResource.find, self.mock_session, self.NAME) + def test_id_attribute_find(self): + floater = {'ip_address': "127.0.0.1"} + resp = FakeResponse({FakeResource.resources_key: [floater]}) + self.mock_get.return_value = resp + + FakeResource.id_attribute = 'ip_address' + result = FakeResource.find(self.mock_session, "127.0.0.1", + path_args=fake_arguments) + self.assertEqual("127.0.0.1", result.id) + FakeResource.id_attribute = 'id' + + p = {'fields': 'ip_address', 'ip_address': "127.0.0.1"} + self.mock_get.assert_called_with(fake_path, params=p, service=None) + def test_nada(self): resp = FakeResponse({FakeResource.resources_key: []}) self.mock_get.return_value = resp