Merge "Allow name argument to flavor-access-add"
This commit is contained in:
commit
27700f9b36
@ -202,13 +202,19 @@ class ManagerWithFind(Manager):
|
||||
searches = kwargs.items()
|
||||
|
||||
detailed = True
|
||||
if 'detailed' in inspect.getargspec(self.list).args:
|
||||
list_kwargs = {}
|
||||
|
||||
list_argspec = inspect.getargspec(self.list)
|
||||
if 'detailed' in list_argspec.args:
|
||||
detailed = ("human_id" not in kwargs and
|
||||
"name" not in kwargs and
|
||||
"display_name" not in kwargs)
|
||||
listing = self.list(detailed=detailed)
|
||||
else:
|
||||
listing = self.list()
|
||||
list_kwargs['detailed'] = detailed
|
||||
|
||||
if 'is_public' in list_argspec.args and 'is_public' in kwargs:
|
||||
list_kwargs['is_public'] = kwargs['is_public']
|
||||
|
||||
listing = self.list(**list_kwargs)
|
||||
|
||||
for obj in listing:
|
||||
try:
|
||||
|
@ -20,9 +20,11 @@ import urlparse
|
||||
import six
|
||||
|
||||
from novaclient import client as base_client
|
||||
from novaclient.v1_1 import client
|
||||
from novaclient import exceptions
|
||||
from novaclient.openstack.common import strutils
|
||||
from novaclient.tests import fakes
|
||||
from novaclient.tests import utils
|
||||
from novaclient.v1_1 import client
|
||||
|
||||
|
||||
class FakeClient(fakes.FakeClient, client.Client):
|
||||
@ -67,6 +69,7 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
munged_url = url.rsplit('?', 1)[0]
|
||||
munged_url = munged_url.strip('/').replace('/', '_').replace('.', '_')
|
||||
munged_url = munged_url.replace('-', '_')
|
||||
munged_url = munged_url.replace(' ', '_')
|
||||
|
||||
callback = "%s_%s" % (method.lower(), munged_url)
|
||||
|
||||
@ -595,7 +598,7 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
]})
|
||||
|
||||
def get_flavors_detail(self, **kw):
|
||||
return (200, {}, {'flavors': [
|
||||
flavors = {'flavors': [
|
||||
{'id': 1, 'name': '256 MB Server', 'ram': 256, 'disk': 10,
|
||||
'OS-FLV-EXT-DATA:ephemeral': 10,
|
||||
'os-flavor-access:is_public': True,
|
||||
@ -608,20 +611,45 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
'OS-FLV-EXT-DATA:ephemeral': 0,
|
||||
'os-flavor-access:is_public': True,
|
||||
'links': {}}
|
||||
]})
|
||||
]}
|
||||
|
||||
if 'is_public' not in kw:
|
||||
filter_is_public = True
|
||||
else:
|
||||
if kw['is_public'].lower() == 'none':
|
||||
filter_is_public = None
|
||||
else:
|
||||
filter_is_public = strutils.bool_from_string(kw['is_public'],
|
||||
True)
|
||||
|
||||
if filter_is_public is not None:
|
||||
if filter_is_public:
|
||||
flavors['flavors'] = [
|
||||
v for v in flavors['flavors']
|
||||
if v['os-flavor-access:is_public']
|
||||
]
|
||||
else:
|
||||
flavors['flavors'] = [
|
||||
v for v in flavors['flavors']
|
||||
if not v['os-flavor-access:is_public']
|
||||
]
|
||||
|
||||
return (200, {}, flavors)
|
||||
|
||||
def get_flavors_1(self, **kw):
|
||||
return (
|
||||
200,
|
||||
{},
|
||||
{'flavor': self.get_flavors_detail()[2]['flavors'][0]}
|
||||
{'flavor':
|
||||
self.get_flavors_detail(is_public='None')[2]['flavors'][0]}
|
||||
)
|
||||
|
||||
def get_flavors_2(self, **kw):
|
||||
return (
|
||||
200,
|
||||
{},
|
||||
{'flavor': self.get_flavors_detail()[2]['flavors'][1]}
|
||||
{'flavor':
|
||||
self.get_flavors_detail(is_public='None')[2]['flavors'][1]}
|
||||
)
|
||||
|
||||
def get_flavors_3(self, **kw):
|
||||
@ -637,12 +665,16 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
}},
|
||||
)
|
||||
|
||||
def get_flavors_512_MB_Server(self, **kw):
|
||||
raise exceptions.NotFound('404')
|
||||
|
||||
def get_flavors_aa1(self, **kw):
|
||||
# Aplhanumeric flavor id are allowed.
|
||||
return (
|
||||
200,
|
||||
{},
|
||||
{'flavor': self.get_flavors_detail()[2]['flavors'][2]}
|
||||
{'flavor':
|
||||
self.get_flavors_detail(is_public='None')[2]['flavors'][2]}
|
||||
)
|
||||
|
||||
def delete_flavors_flavordelete(self, **kw):
|
||||
@ -655,7 +687,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||
return (
|
||||
202,
|
||||
{},
|
||||
{'flavor': self.get_flavors_detail()[2]['flavors'][0]}
|
||||
{'flavor':
|
||||
self.get_flavors_detail(is_public='None')[2]['flavors'][0]}
|
||||
)
|
||||
|
||||
def get_flavors_1_os_extra_specs(self, **kw):
|
||||
|
@ -36,12 +36,24 @@ class FlavorsTest(utils.TestCase):
|
||||
for flavor in fl:
|
||||
self.assertTrue(isinstance(flavor, flavors.Flavor))
|
||||
|
||||
def test_list_flavors_is_public(self):
|
||||
def test_list_flavors_is_public_none(self):
|
||||
fl = cs.flavors.list(is_public=None)
|
||||
cs.assert_called('GET', '/flavors/detail?is_public=None')
|
||||
for flavor in fl:
|
||||
self.assertTrue(isinstance(flavor, flavors.Flavor))
|
||||
|
||||
def test_list_flavors_is_public_false(self):
|
||||
fl = cs.flavors.list(is_public=False)
|
||||
cs.assert_called('GET', '/flavors/detail?is_public=False')
|
||||
for flavor in fl:
|
||||
self.assertTrue(isinstance(flavor, flavors.Flavor))
|
||||
|
||||
def test_list_flavors_is_public_true(self):
|
||||
fl = cs.flavors.list(is_public=True)
|
||||
cs.assert_called('GET', '/flavors/detail')
|
||||
for flavor in fl:
|
||||
self.assertTrue(isinstance(flavor, flavors.Flavor))
|
||||
|
||||
def test_get_flavor_details(self):
|
||||
f = cs.flavors.get(1)
|
||||
cs.assert_called('GET', '/flavors/1')
|
||||
@ -74,8 +86,8 @@ class FlavorsTest(utils.TestCase):
|
||||
cs.assert_called('GET', '/flavors/detail')
|
||||
self.assertEqual(f.name, '256 MB Server')
|
||||
|
||||
f = cs.flavors.find(disk=20)
|
||||
self.assertEqual(f.name, '512 MB Server')
|
||||
f = cs.flavors.find(disk=0)
|
||||
self.assertEqual(f.name, '128 MB Server')
|
||||
|
||||
self.assertRaises(exceptions.NotFound, cs.flavors.find, disk=12345)
|
||||
|
||||
|
@ -73,6 +73,9 @@ class ShellTest(utils.TestCase):
|
||||
|
||||
@mock.patch('sys.stdout', StringIO.StringIO())
|
||||
def run_command(self, cmd):
|
||||
if isinstance(cmd, list):
|
||||
self.shell.main(cmd)
|
||||
else:
|
||||
self.shell.main(cmd.split())
|
||||
return sys.stdout.getvalue()
|
||||
|
||||
@ -449,16 +452,26 @@ class ShellTest(utils.TestCase):
|
||||
cmd = 'flavor-access-list'
|
||||
self.assertRaises(exceptions.CommandError, self.run_command, cmd)
|
||||
|
||||
def test_flavor_access_add(self):
|
||||
def test_flavor_access_add_by_id(self):
|
||||
self.run_command('flavor-access-add 2 proj2')
|
||||
self.assert_called('POST', '/flavors/2/action',
|
||||
{'addTenantAccess': {'tenant': 'proj2'}})
|
||||
|
||||
def test_flavor_access_remove(self):
|
||||
def test_flavor_access_add_by_name(self):
|
||||
self.run_command(['flavor-access-add', '512 MB Server', 'proj2'])
|
||||
self.assert_called('POST', '/flavors/2/action',
|
||||
{'addTenantAccess': {'tenant': 'proj2'}})
|
||||
|
||||
def test_flavor_access_remove_by_id(self):
|
||||
self.run_command('flavor-access-remove 2 proj2')
|
||||
self.assert_called('POST', '/flavors/2/action',
|
||||
{'removeTenantAccess': {'tenant': 'proj2'}})
|
||||
|
||||
def test_flavor_access_remove_by_name(self):
|
||||
self.run_command(['flavor-access-remove', '512 MB Server', 'proj2'])
|
||||
self.assert_called('POST', '/flavors/2/action',
|
||||
{'removeTenantAccess': {'tenant': 'proj2'}})
|
||||
|
||||
def test_image_show(self):
|
||||
self.run_command('image-show 1')
|
||||
self.assert_called('GET', '/images/1')
|
||||
|
@ -192,7 +192,7 @@ def print_dict(d, dict_property="Property", dict_value="Value", wrap=0):
|
||||
print(strutils.safe_encode(pt.get_string()))
|
||||
|
||||
|
||||
def find_resource(manager, name_or_id):
|
||||
def find_resource(manager, name_or_id, **find_args):
|
||||
"""Helper for the _find_* methods."""
|
||||
# first try to get entity as integer id
|
||||
try:
|
||||
@ -216,7 +216,7 @@ def find_resource(manager, name_or_id):
|
||||
|
||||
try:
|
||||
try:
|
||||
return manager.find(human_id=name_or_id)
|
||||
return manager.find(human_id=name_or_id, **find_args)
|
||||
except exceptions.NotFound:
|
||||
pass
|
||||
|
||||
|
@ -604,7 +604,7 @@ def do_flavor_access_list(cs, args):
|
||||
help='Filter results by tenant ID.')
|
||||
def do_flavor_access_add(cs, args):
|
||||
"""Add flavor access for the given tenant."""
|
||||
flavor = _find_flavor(cs, args.flavor)
|
||||
flavor = _find_flavor_for_admin(cs, args.flavor)
|
||||
access_list = cs.flavor_access.add_tenant_access(flavor, args.tenant)
|
||||
columns = ['Flavor_ID', 'Tenant_ID']
|
||||
utils.print_list(access_list, columns)
|
||||
@ -617,7 +617,7 @@ def do_flavor_access_add(cs, args):
|
||||
help='Filter results by tenant ID.')
|
||||
def do_flavor_access_remove(cs, args):
|
||||
"""Remove flavor access for the given tenant."""
|
||||
flavor = _find_flavor(cs, args.flavor)
|
||||
flavor = _find_flavor_for_admin(cs, args.flavor)
|
||||
access_list = cs.flavor_access.remove_tenant_access(flavor, args.tenant)
|
||||
columns = ['Flavor_ID', 'Tenant_ID']
|
||||
utils.print_list(access_list, columns)
|
||||
@ -1375,6 +1375,14 @@ def _find_image(cs, image):
|
||||
return utils.find_resource(cs.images, image)
|
||||
|
||||
|
||||
def _find_flavor_for_admin(cs, flavor):
|
||||
"""Get a flavor for administrator by name, ID, or RAM size."""
|
||||
try:
|
||||
return utils.find_resource(cs.flavors, flavor, is_public='None')
|
||||
except exceptions.NotFound:
|
||||
return cs.flavors.find(ram=flavor)
|
||||
|
||||
|
||||
def _find_flavor(cs, flavor):
|
||||
"""Get a flavor by name, ID, or RAM size."""
|
||||
try:
|
||||
|
Loading…
Reference in New Issue
Block a user