Add filter option to stack-list

Add ability to use filters on stack-list by passing a ``--filters``
options to the command line.  This option can appear multiple times or
be used once with several key=value filters separated by semicolons.  If
the same key appears more than once, both will be taken into account
when sending the request to the API.

e.g.:
The option:
``--filters status=COMPLETE;status=FAILED``
Will issue the call:
 ``/stacks?status=COMPLETE&status=FAILED``

Closes-Bug: 1268816
Change-Id: I553d6b5e3ceebdb24dcd4e4c8e409a4375d72333
This commit is contained in:
Anderson Mesquita
2014-01-08 18:47:34 -06:00
committed by Richard Lee
parent cda180eed4
commit ff9bde4001
5 changed files with 36 additions and 11 deletions

View File

@@ -162,7 +162,13 @@ def format_parameters(params):
'Use the key=value format')
raise exc.CommandError(msg)
parameters[n] = v
if n not in parameters:
parameters[n] = v
else:
if not isinstance(parameters[n], list):
parameters[n] = [parameters[n]]
parameters[n].append(v)
return parameters

View File

@@ -379,12 +379,18 @@ class ShellTestUserPass(ShellBase):
def test_stack_list_with_args(self):
self._script_keystone_client()
expected_url = '/stacks?marker=fake_id&limit=2'
expected_url = ('/stacks?'
'status=COMPLETE&status=FAILED'
'&marker=fake_id&limit=2')
fakes.script_heat_list(expected_url)
self.m.ReplayAll()
list_text = self.shell('stack-list --limit 2 --marker fake_id')
list_text = self.shell('stack-list'
' --limit 2'
' --marker fake_id'
' --filters=status=COMPLETE'
' --filters=status=FAILED')
required = [
'teststack',

View File

@@ -66,6 +66,14 @@ class shellTest(testtools.TestCase):
'ww7a4oAO;NQ/fD==',
'UpstreamDNS': '8.8.8.8'}, p)
def test_format_parameters_multiple_values_per_pamaters(self):
p = utils.format_parameters([
'status=COMPLETE',
'status=FAILED'])
self.assertIn('status', p)
self.assertIn('COMPLETE', p['status'])
self.assertIn('FAILED', p['status'])
def test_format_parameter_bad_parameter(self):
params = ['KeyName=heat_key;UpstreamDNS8.8.8.8']
ex = self.assertRaises(exc.CommandError,

View File

@@ -234,6 +234,11 @@ def do_list(hc):
do_stack_list(hc)
@utils.arg('-f', '--filters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
help='Filter parameters to apply on returned stacks. '
'This can be specified multiple times, or once with parameters '
'separated by semicolon.',
action='append')
@utils.arg('-l', '--limit', metavar='<LIMIT>',
help='Limit the number of stacks returned')
@utils.arg('-m', '--marker', metavar='<ID>',
@@ -243,7 +248,9 @@ def do_stack_list(hc, args=None):
kwargs = {}
if args:
kwargs = {'limit': args.limit,
'marker': args.marker}
'marker': args.marker,
'filters': utils.format_parameters(args.filters)}
stacks = hc.stacks.list(**kwargs)
fields = ['id', 'stack_name', 'stack_status', 'creation_time']
utils.print_list(stacks, fields, sortby=3)

View File

@@ -77,7 +77,7 @@ class StackManager(base.BaseManager):
def paginate(params):
'''Paginate stacks, even if more than API limit.'''
current_limit = int(params.get('limit') or 0)
url = '/stacks?%s' % urlutils.urlencode(params)
url = '/stacks?%s' % urlutils.urlencode(params, True)
stacks = self._list(url, 'stacks')
for stack in stacks:
yield stack
@@ -91,16 +91,14 @@ class StackManager(base.BaseManager):
yield stack
params = {}
if 'filters' in kwargs:
filters = kwargs.pop('filters')
params.update(filters)
for key, value in kwargs.iteritems():
if value:
params[key] = value
filters = kwargs.get('filters', {})
properties = filters.pop('properties', {})
for key, value in properties.items():
params['property-%s' % key] = value
params.update(filters)
return paginate(params)
def create(self, **kwargs):