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:
parent
077cc0bf22
commit
576a64fbb5
@ -281,6 +281,7 @@ class Resource(object):
|
|||||||
:param loaded: prevent lazy-loading if set to True
|
:param loaded: prevent lazy-loading if set to True
|
||||||
"""
|
"""
|
||||||
HUMAN_ID = False
|
HUMAN_ID = False
|
||||||
|
NAME_ATTR = 'name'
|
||||||
|
|
||||||
def __init__(self, manager, info, loaded=False):
|
def __init__(self, manager, info, loaded=False):
|
||||||
self.manager = manager
|
self.manager = manager
|
||||||
@ -303,8 +304,8 @@ class Resource(object):
|
|||||||
"""Subclasses may override this provide a pretty ID which can be used
|
"""Subclasses may override this provide a pretty ID which can be used
|
||||||
for bash completion.
|
for bash completion.
|
||||||
"""
|
"""
|
||||||
if 'name' in self.__dict__ and self.HUMAN_ID:
|
if self.NAME_ATTR in self.__dict__ and self.HUMAN_ID:
|
||||||
return utils.slugify(self.name)
|
return utils.slugify(getattr(self, self.NAME_ATTR))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _add_details(self, info):
|
def _add_details(self, info):
|
||||||
|
@ -180,15 +180,14 @@ def find_resource(manager, name_or_id):
|
|||||||
|
|
||||||
# finally try to find entity by name
|
# finally try to find entity by name
|
||||||
try:
|
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:
|
except exceptions.NotFound:
|
||||||
try:
|
msg = "No %s with a name or ID of '%s' exists." % \
|
||||||
# Volumes does not have name, but display_name
|
(manager.resource_class.__name__.lower(), name_or_id)
|
||||||
return manager.find(display_name=name_or_id)
|
raise exceptions.CommandError(msg)
|
||||||
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)
|
|
||||||
except exceptions.NoUniqueMatch:
|
except exceptions.NoUniqueMatch:
|
||||||
msg = ("Multiple %s matches found for '%s', use an ID to be more"
|
msg = ("Multiple %s matches found for '%s', use an ID to be more"
|
||||||
" specific." % (manager.resource_class.__name__.lower(),
|
" specific." % (manager.resource_class.__name__.lower(),
|
||||||
|
@ -23,11 +23,13 @@ from novaclient import base
|
|||||||
|
|
||||||
|
|
||||||
class Hypervisor(base.Resource):
|
class Hypervisor(base.Resource):
|
||||||
|
NAME_ATTR = 'hypervisor_hostname'
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Hypervisor: %s>" % self.id
|
return "<Hypervisor: %s>" % self.id
|
||||||
|
|
||||||
|
|
||||||
class HypervisorManager(base.Manager):
|
class HypervisorManager(base.ManagerWithFind):
|
||||||
resource_class = Hypervisor
|
resource_class = Hypervisor
|
||||||
|
|
||||||
def list(self, detailed=True):
|
def list(self, detailed=True):
|
||||||
|
@ -24,6 +24,8 @@ class Snapshot(base.Resource):
|
|||||||
"""
|
"""
|
||||||
A Snapshot is a point-in-time snapshot of an openstack volume.
|
A Snapshot is a point-in-time snapshot of an openstack volume.
|
||||||
"""
|
"""
|
||||||
|
NAME_ATTR = 'display_name'
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Snapshot: %s>" % self.id
|
return "<Snapshot: %s>" % self.id
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ class Volume(base.Resource):
|
|||||||
"""
|
"""
|
||||||
A volume is an extra block level storage to the OpenStack instances.
|
A volume is an extra block level storage to the OpenStack instances.
|
||||||
"""
|
"""
|
||||||
|
NAME_ATTR = 'display_name'
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Volume: %s>" % self.id
|
return "<Volume: %s>" % self.id
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ UUID = '8e8ec658-c7b0-4243-bdf8-6f7f2952c0d0'
|
|||||||
|
|
||||||
|
|
||||||
class FakeResource(object):
|
class FakeResource(object):
|
||||||
|
NAME_ATTR = 'name'
|
||||||
|
|
||||||
def __init__(self, _id, properties):
|
def __init__(self, _id, properties):
|
||||||
self.id = _id
|
self.id = _id
|
||||||
@ -15,10 +16,6 @@ class FakeResource(object):
|
|||||||
self.name = properties['name']
|
self.name = properties['name']
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
try:
|
|
||||||
self.display_name = properties['display_name']
|
|
||||||
except KeyError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
class FakeManager(base.ManagerWithFind):
|
class FakeManager(base.ManagerWithFind):
|
||||||
@ -28,7 +25,6 @@ class FakeManager(base.ManagerWithFind):
|
|||||||
resources = [
|
resources = [
|
||||||
FakeResource('1234', {'name': 'entity_one'}),
|
FakeResource('1234', {'name': 'entity_one'}),
|
||||||
FakeResource(UUID, {'name': 'entity_two'}),
|
FakeResource(UUID, {'name': 'entity_two'}),
|
||||||
FakeResource('4242', {'display_name': 'entity_three'}),
|
|
||||||
FakeResource('5678', {'name': '9876'})
|
FakeResource('5678', {'name': '9876'})
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -42,6 +38,26 @@ class FakeManager(base.ManagerWithFind):
|
|||||||
return self.resources
|
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):
|
class FindResourceTestCase(test_utils.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
def setUp(self):
|
||||||
@ -70,5 +86,6 @@ class FindResourceTestCase(test_utils.TestCase):
|
|||||||
self.assertEqual(output, self.manager.get('1234'))
|
self.assertEqual(output, self.manager.get('1234'))
|
||||||
|
|
||||||
def test_find_by_str_displayname(self):
|
def test_find_by_str_displayname(self):
|
||||||
output = utils.find_resource(self.manager, 'entity_three')
|
display_manager = FakeDisplayManager(None)
|
||||||
self.assertEqual(output, self.manager.get('4242'))
|
output = utils.find_resource(display_manager, 'entity_three')
|
||||||
|
self.assertEqual(output, display_manager.get('4242'))
|
||||||
|
Loading…
Reference in New Issue
Block a user