Revert "nova flavor-show command is inconsistent"

This reverts commit 4e79285b45.

The aforementioned commit broke flavor-show for mixed case flavorids.
The reason is a bit complex. On the nova api side, there is caching of
db items for flavors, keyed off the flavorid retrieved from the db,
case sensitive, unlike the db query itself. Attempts to flavor-show
a flavor with flavorid composed of letters will fail with a 400 if
the capitalization doesn't match.

For the flavor names, they work in lowercase because the find_resource
function falls back on a search by "human_id" after failing every other
attempt to find the flavor, because "human_id" is a oslo-slugified
string (all lowercase, non-word characters removed, spaces converted
to hyphens).

Closes-Bug: #1446850

Change-Id: I73247b50f5a6918167c071ccc13cd676aa2c7fec
This commit is contained in:
melanie witt 2015-04-21 21:32:33 +00:00
parent 9799353781
commit 098116d6a5
5 changed files with 21 additions and 32 deletions

View File

@ -36,7 +36,7 @@ class BaseTest(utils.TestCase):
def test_resource_lazy_getattr(self):
f = flavors.Flavor(cs.flavors, {'id': 1})
self.assertEqual('256 mb server', f.name)
self.assertEqual('256 MB Server', f.name)
cs.assert_called('GET', '/flavors/1')
# Missing stuff still fails after a second get

View File

@ -258,7 +258,7 @@ class FakeHTTPClient(base_client.HTTPClient):
},
"flavor": {
"id": 1,
"name": "256 mb server",
"name": "256 MB Server",
},
"hostId": "e4d909c290d0fb1ca068ffaddf22cbd0",
"status": "BUILD",
@ -299,7 +299,7 @@ class FakeHTTPClient(base_client.HTTPClient):
},
"flavor": {
"id": 1,
"name": "256 mb server",
"name": "256 MB Server",
},
"hostId": "9e107d9d372bb6826bd81d3542a419d6",
"status": "ACTIVE",
@ -340,7 +340,7 @@ class FakeHTTPClient(base_client.HTTPClient):
"image": "",
"flavor": {
"id": 1,
"name": "256 mb server",
"name": "256 MB Server",
},
"hostId": "9e107d9d372bb6826bd81d3542a419d6",
"status": "ACTIVE",
@ -672,19 +672,19 @@ class FakeHTTPClient(base_client.HTTPClient):
def get_flavors_detail(self, **kw):
flavors = {'flavors': [
{'id': 1, 'name': '256 mb server', 'ram': 256, 'disk': 10,
{'id': 1, 'name': '256 MB Server', 'ram': 256, 'disk': 10,
'OS-FLV-EXT-DATA:ephemeral': 10,
'os-flavor-access:is_public': True,
'links': {}},
{'id': 2, 'name': '512 mb server', 'ram': 512, 'disk': 20,
{'id': 2, 'name': '512 MB Server', 'ram': 512, 'disk': 20,
'OS-FLV-EXT-DATA:ephemeral': 20,
'os-flavor-access:is_public': False,
'links': {}},
{'id': 4, 'name': '1024 mb server', 'ram': 1024, 'disk': 10,
{'id': 4, 'name': '1024 MB Server', 'ram': 1024, 'disk': 10,
'OS-FLV-EXT-DATA:ephemeral': 10,
'os-flavor-access:is_public': True,
'links': {}},
{'id': 'aa1', 'name': '128 mb server', 'ram': 128, 'disk': 0,
{'id': 'aa1', 'name': '128 MB Server', 'ram': 128, 'disk': 0,
'OS-FLV-EXT-DATA:ephemeral': 0,
'os-flavor-access:is_public': True,
'links': {}}
@ -736,16 +736,16 @@ class FakeHTTPClient(base_client.HTTPClient):
{},
{'flavor': {
'id': 3,
'name': '256 mb server',
'name': '256 MB Server',
'ram': 256,
'disk': 10,
}},
)
def get_flavors_512_mb_server(self, **kw):
def get_flavors_512_MB_Server(self, **kw):
raise exceptions.NotFound('404')
def get_flavors_128_mb_server(self, **kw):
def get_flavors_128_MB_Server(self, **kw):
raise exceptions.NotFound('404')
def get_flavors_aa1(self, **kw):

View File

@ -93,10 +93,10 @@ class FlavorsTest(utils.TestCase):
def test_find(self):
f = self.cs.flavors.find(ram=256)
self.cs.assert_called('GET', '/flavors/detail')
self.assertEqual('256 mb server', f.name)
self.assertEqual('256 MB Server', f.name)
f = self.cs.flavors.find(disk=0)
self.assertEqual('128 mb server', f.name)
self.assertEqual('128 MB Server', f.name)
self.assertRaises(exceptions.NotFound, self.cs.flavors.find,
disk=12345)

View File

@ -668,10 +668,10 @@ class ShellTest(utils.TestCase):
def test_boot_named_flavor(self):
self.run_command(["boot", "--image", "1",
"--flavor", "512 mb server",
"--flavor", "512 MB Server",
"--max-count", "3", "server"])
self.assert_called('GET', '/images/1', pos=0)
self.assert_called('GET', '/flavors/512 mb server', pos=1)
self.assert_called('GET', '/flavors/512 MB Server', pos=1)
self.assert_called('GET', '/flavors?is_public=None', pos=2)
self.assert_called('GET', '/flavors/2', pos=3)
self.assert_called(
@ -708,15 +708,15 @@ class ShellTest(utils.TestCase):
self.assert_called_anytime('GET', '/flavors/aa1')
def test_flavor_show_by_name(self):
self.run_command(['flavor-show', '128 mb server'])
self.assert_called('GET', '/flavors/128 mb server', pos=0)
self.run_command(['flavor-show', '128 MB Server'])
self.assert_called('GET', '/flavors/128 MB Server', pos=0)
self.assert_called('GET', '/flavors?is_public=None', pos=1)
self.assert_called('GET', '/flavors/aa1', pos=2)
self.assert_called('GET', '/flavors/aa1/os-extra_specs', pos=3)
def test_flavor_show_by_name_priv(self):
self.run_command(['flavor-show', '512 mb server'])
self.assert_called('GET', '/flavors/512 mb server', pos=0)
self.run_command(['flavor-show', '512 MB Server'])
self.assert_called('GET', '/flavors/512 MB Server', pos=0)
self.assert_called('GET', '/flavors?is_public=None', pos=1)
self.assert_called('GET', '/flavors/2', pos=2)
self.assert_called('GET', '/flavors/2/os-extra_specs', pos=3)
@ -753,7 +753,7 @@ class ShellTest(utils.TestCase):
{'addTenantAccess': {'tenant': 'proj2'}})
def test_flavor_access_add_by_name(self):
self.run_command(['flavor-access-add', '512 mb server', 'proj2'])
self.run_command(['flavor-access-add', '512 MB Server', 'proj2'])
self.assert_called('POST', '/flavors/2/action',
{'addTenantAccess': {'tenant': 'proj2'}})
@ -763,7 +763,7 @@ class ShellTest(utils.TestCase):
{'removeTenantAccess': {'tenant': 'proj2'}})
def test_flavor_access_remove_by_name(self):
self.run_command(['flavor-access-remove', '512 mb server', 'proj2'])
self.run_command(['flavor-access-remove', '512 MB Server', 'proj2'])
self.assert_called('POST', '/flavors/2/action',
{'removeTenantAccess': {'tenant': 'proj2'}})

View File

@ -1898,17 +1898,6 @@ def _find_image(cs, image):
def _find_flavor(cs, flavor):
"""Get a flavor by name, ID, or RAM size."""
try:
# isinstance() is being used to check if flavor is an instance of
# integer. It will help us to check if the user has entered flavor
# name or flavorid. If flavor name has been entered it is being
# converted to lowercase using lower(). Incase it is an ID the user
# has passed it will not go through the "flavor = flavor.lower()"
# code.The reason for checking if it is a flavor name or flavorid is
# that int has no lower() so it will give an error.
if isinstance(flavor, six.integer_types):
pass
else:
flavor = flavor.lower()
return utils.find_resource(cs.flavors, flavor, is_public=None)
except exceptions.NotFound:
return cs.flavors.find(ram=flavor)