Merge "Allow name argument to flavor-access-add"

This commit is contained in:
Jenkins 2013-08-23 01:33:06 +00:00 committed by Gerrit Code Review
commit 27700f9b36
6 changed files with 93 additions and 21 deletions

View File

@ -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:

View File

@ -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):

View File

@ -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)

View File

@ -73,7 +73,10 @@ class ShellTest(utils.TestCase):
@mock.patch('sys.stdout', StringIO.StringIO())
def run_command(self, cmd):
self.shell.main(cmd.split())
if isinstance(cmd, list):
self.shell.main(cmd)
else:
self.shell.main(cmd.split())
return sys.stdout.getvalue()
def assert_called(self, method, url, body=None, **kwargs):
@ -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')

View File

@ -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

View File

@ -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: