Request ID when name is ambiguous.

Fixes bug 931605

Change-Id: If0778915d964995dbb6647d56ed21075aec08baa
This commit is contained in:
Rick Harris 2012-04-09 20:32:37 +00:00
parent ea448e2497
commit 0028eb4ac2
4 changed files with 34 additions and 20 deletions

View File

@ -174,12 +174,15 @@ class ManagerWithFind(Manager):
This isn't very efficient: it loads the entire list then filters on
the Python side.
"""
rl = self.findall(**kwargs)
try:
return rl[0]
except IndexError:
matches = self.findall(**kwargs)
num_matches = len(matches)
if num_matches == 0:
msg = "No %s matching %s." % (self.resource_class.__name__, kwargs)
raise exceptions.NotFound(404, msg)
elif num_matches > 1:
raise exceptions.NoUniqueMatch
else:
return matches[0]
def findall(self, **kwargs):
"""

View File

@ -18,6 +18,10 @@ class AuthorizationFailure(Exception):
pass
class NoUniqueMatch(Exception):
pass
class NoTokenLookupException(Exception):
"""This form of authentication does not support looking up
endpoints from an existing token."""

View File

@ -169,21 +169,27 @@ def find_resource(manager, name_or_id):
pass
try:
return manager.find(human_id=name_or_id)
except exceptions.NotFound:
pass
# finally try to find entity by name
try:
return manager.find(name=name_or_id)
except exceptions.NotFound:
try:
# Volumes does not have name, but displayName
return manager.find(displayName=name_or_id)
return manager.find(human_id=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)
pass
# finally try to find entity by name
try:
return manager.find(name=name_or_id)
except exceptions.NotFound:
try:
# Volumes does not have name, but displayName
return manager.find(displayName=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)
except exceptions.NoUniqueMatch:
msg = ("Multiple %s matches found for '%s', use an ID to be more"
" specific." % (manager.resource_class.__name__.lower(),
name_or_id))
raise exceptions.CommandError(msg)
def _format_servers_list_networks(server):

View File

@ -1,5 +1,6 @@
import StringIO
from novaclient import exceptions
from novaclient.v1_1 import servers
from tests import utils
from tests.v1_1 import fakes
@ -97,10 +98,10 @@ class ServersTest(utils.TestCase):
cs.assert_called('GET', '/servers/detail')
self.assertEqual(s.name, 'sample-server')
# Find with multiple results arbitraility returns the first item
s = cs.servers.find(flavor={"id": 1, "name": "256 MB Server"})
self.assertRaises(exceptions.NoUniqueMatch, cs.servers.find,
flavor={"id": 1, "name": "256 MB Server"})
sl = cs.servers.findall(flavor={"id": 1, "name": "256 MB Server"})
self.assertEqual(sl[0], s)
self.assertEqual([s.id for s in sl], [1234, 5678])
def test_reboot_server(self):