Revert "nova flavor-show command is inconsistent"
This reverts commit 4e79285b45ec1490c8e923f724cbaf4d42fe81c4. 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:
parent
9799353781
commit
098116d6a5
novaclient
@ -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
|
||||
|
@ -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):
|
||||
|
@ -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)
|
||||
|
@ -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'}})
|
||||
|
||||
|
@ -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)
|
||||
|
Loading…
x
Reference in New Issue
Block a user