Allow resources to use any field as 'name'

The 'name' field for some resources is called something different,
for example 'display_name' for volumes. There was a hack in our
find method to search for display_name as well.

This change adds a new class variable to a Resource to tell it
which attribute to use for searching by name. Volumes and snapshots
were switched to use 'display_name' and hypervisors were switched
to use 'hypervisor_hostname'.

Tests fixed and added.

Fixes bug 1034536

Change-Id: I1b4fb969d42c59d1ab8e3e275a563bbe158e9264
This commit is contained in:
Vishvananda Ishaya 2012-08-08 11:18:13 -07:00
parent 077cc0bf22
commit 576a64fbb5
6 changed files with 41 additions and 18 deletions

View File

@ -281,6 +281,7 @@ class Resource(object):
:param loaded: prevent lazy-loading if set to True
"""
HUMAN_ID = False
NAME_ATTR = 'name'
def __init__(self, manager, info, loaded=False):
self.manager = manager
@ -303,8 +304,8 @@ class Resource(object):
"""Subclasses may override this provide a pretty ID which can be used
for bash completion.
"""
if 'name' in self.__dict__ and self.HUMAN_ID:
return utils.slugify(self.name)
if self.NAME_ATTR in self.__dict__ and self.HUMAN_ID:
return utils.slugify(getattr(self, self.NAME_ATTR))
return None
def _add_details(self, info):

View File

@ -180,15 +180,14 @@ def find_resource(manager, name_or_id):
# finally try to find entity by name
try:
return manager.find(name=name_or_id)
resource = getattr(manager, 'resource_class', None)
name_attr = resource.NAME_ATTR if resource else 'name'
kwargs = {name_attr: name_or_id}
return manager.find(**kwargs)
except exceptions.NotFound:
try:
# Volumes does not have name, but display_name
return manager.find(display_name=name_or_id)
except exceptions.NotFound:
msg = "No %s with a name or ID of '%s' exists." % \
(manager.resource_class.__name__.lower(), name_or_id)
raise exceptions.CommandError(msg)
msg = "No %s with a name or ID of '%s' exists." % \
(manager.resource_class.__name__.lower(), name_or_id)
raise exceptions.CommandError(msg)
except exceptions.NoUniqueMatch:
msg = ("Multiple %s matches found for '%s', use an ID to be more"
" specific." % (manager.resource_class.__name__.lower(),

View File

@ -23,11 +23,13 @@ from novaclient import base
class Hypervisor(base.Resource):
NAME_ATTR = 'hypervisor_hostname'
def __repr__(self):
return "<Hypervisor: %s>" % self.id
class HypervisorManager(base.Manager):
class HypervisorManager(base.ManagerWithFind):
resource_class = Hypervisor
def list(self, detailed=True):

View File

@ -24,6 +24,8 @@ class Snapshot(base.Resource):
"""
A Snapshot is a point-in-time snapshot of an openstack volume.
"""
NAME_ATTR = 'display_name'
def __repr__(self):
return "<Snapshot: %s>" % self.id

View File

@ -24,6 +24,8 @@ class Volume(base.Resource):
"""
A volume is an extra block level storage to the OpenStack instances.
"""
NAME_ATTR = 'display_name'
def __repr__(self):
return "<Volume: %s>" % self.id

View File

@ -8,6 +8,7 @@ UUID = '8e8ec658-c7b0-4243-bdf8-6f7f2952c0d0'
class FakeResource(object):
NAME_ATTR = 'name'
def __init__(self, _id, properties):
self.id = _id
@ -15,10 +16,6 @@ class FakeResource(object):
self.name = properties['name']
except KeyError:
pass
try:
self.display_name = properties['display_name']
except KeyError:
pass
class FakeManager(base.ManagerWithFind):
@ -28,7 +25,6 @@ class FakeManager(base.ManagerWithFind):
resources = [
FakeResource('1234', {'name': 'entity_one'}),
FakeResource(UUID, {'name': 'entity_two'}),
FakeResource('4242', {'display_name': 'entity_three'}),
FakeResource('5678', {'name': '9876'})
]
@ -42,6 +38,26 @@ class FakeManager(base.ManagerWithFind):
return self.resources
class FakeDisplayResource(object):
NAME_ATTR = 'display_name'
def __init__(self, _id, properties):
self.id = _id
try:
self.display_name = properties['display_name']
except KeyError:
pass
class FakeDisplayManager(FakeManager):
resource_class = FakeDisplayResource
resources = [
FakeDisplayResource('4242', {'display_name': 'entity_three'}),
]
class FindResourceTestCase(test_utils.TestCase):
def setUp(self):
@ -70,5 +86,6 @@ class FindResourceTestCase(test_utils.TestCase):
self.assertEqual(output, self.manager.get('1234'))
def test_find_by_str_displayname(self):
output = utils.find_resource(self.manager, 'entity_three')
self.assertEqual(output, self.manager.get('4242'))
display_manager = FakeDisplayManager(None)
output = utils.find_resource(display_manager, 'entity_three')
self.assertEqual(output, display_manager.get('4242'))