Add 'flavor-list --all' admin switch

Nova gives admins public flavors and flavors from their own projects
only by default. For flavor management, admins need to see all flavors
regardless of access.

Changes:
- Adds an 'is_public' argument to flavors.list() that mirrors the
  Nova API. is_public=None can be used to see all flavors.
- Adds an --all switch to flavor-list in the CLI for use by admins
  when all flavors are wanted.

Fixes bug 1172179.

Change-Id: I915cd2d8266cb6e32c80691a6ff27d8a23488c98
This commit is contained in:
Kieran Spear 2013-04-24 17:55:48 +10:00
parent b9f27f6d94
commit 50fe79b47d
4 changed files with 38 additions and 8 deletions

View File

@ -2,6 +2,7 @@
"""
Flavor interface.
"""
import urllib
from novaclient import base
from novaclient import exceptions
@ -76,16 +77,25 @@ class FlavorManager(base.ManagerWithFind):
resource_class = Flavor
is_alphanum_id_allowed = True
def list(self, detailed=True):
def list(self, detailed=True, is_public=True):
"""
Get a list of all flavors.
:rtype: list of :class:`Flavor`.
"""
if detailed is True:
return self._list("/flavors/detail", "flavors")
else:
return self._list("/flavors", "flavors")
qparams = {}
# is_public is ternary - None means give all flavors.
# By default Nova assumes True and gives admins public flavors
# and flavors from their own projects only.
if not is_public:
qparams['is_public'] = is_public
query_string = "?%s" % urllib.urlencode(qparams) if qparams else ""
detail = ""
if detailed:
detail = "/detail"
return self._list("/flavors%s%s" % (detail, query_string), "flavors")
def get(self, flavor):
"""

View File

@ -420,9 +420,17 @@ def _print_flavor_list(cs, flavors, show_extra_specs=False):
action='store_true',
default=False,
help='Get extra-specs of each flavor.')
@utils.arg('--all',
dest='all',
action='store_true',
default=False,
help='Display all flavors (Admin only).')
def do_flavor_list(cs, args):
"""Print a list of available 'flavors' (sizes of servers)."""
flavors = cs.flavors.list()
if args.all:
flavors = cs.flavors.list(is_public=None)
else:
flavors = cs.flavors.list()
_print_flavor_list(cs, flavors, args.extra_specs)

View File

@ -12,12 +12,20 @@ class FlavorsTest(utils.TestCase):
def test_list_flavors(self):
fl = cs.flavors.list()
cs.assert_called('GET', '/flavors/detail')
[self.assertTrue(isinstance(f, flavors.Flavor)) for f in fl]
for flavor in fl:
self.assertTrue(isinstance(flavor, flavors.Flavor))
def test_list_flavors_undetailed(self):
fl = cs.flavors.list(detailed=False)
cs.assert_called('GET', '/flavors')
[self.assertTrue(isinstance(f, flavors.Flavor)) for f in fl]
for flavor in fl:
self.assertTrue(isinstance(flavor, flavors.Flavor))
def test_list_flavors_is_public(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_get_flavor_details(self):
f = cs.flavors.get(1)

View File

@ -397,6 +397,10 @@ class ShellTest(utils.TestCase):
self.assert_called('GET', '/flavors/aa1/os-extra_specs')
self.assert_called_anytime('GET', '/flavors/detail')
def test_flavor_list_with_all(self):
self.run_command('flavor-list --all')
self.assert_called('GET', '/flavors/detail?is_public=None')
def test_flavor_show(self):
self.run_command('flavor-show 1')
self.assert_called_anytime('GET', '/flavors/1')