Skip to content

Commit 96dbb09

Browse files
Jenkinsopenstack-gerrit
authored andcommitted
Merge "Allow -P to be invoked multiple times"
2 parents 455b1cb + 795d52c commit 96dbb09

3 files changed

Lines changed: 79 additions & 23 deletions

File tree

heatclient/common/utils.py

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,25 @@ def exit(msg=''):
147147

148148
def format_parameters(params):
149149
'''Reformat parameters into dict of format expected by the API.'''
150+
151+
if not params:
152+
return {}
153+
154+
# expect multiple invocations of --parameters but fall back
155+
# to ; delimited if only one --parameters is specified
156+
if len(params) == 1:
157+
params = params[0].split(';')
158+
150159
parameters = {}
151-
if params:
152-
for count, p in enumerate(params.split(';'), 1):
153-
try:
154-
(n, v) = p.split(('='), 1)
155-
except ValueError:
156-
msg = '%s(%s). %s.' % ('Malformed parameter', p,
157-
'Use the key=value format')
158-
raise exc.CommandError(msg)
159-
160-
parameters[n] = v
160+
for p in params:
161+
try:
162+
(n, v) = p.split(('='), 1)
163+
except ValueError:
164+
msg = '%s(%s). %s.' % ('Malformed parameter', p,
165+
'Use the key=value format')
166+
raise exc.CommandError(msg)
167+
168+
parameters[n] = v
161169
return parameters
162170

163171

heatclient/tests/test_utils.py

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ def test_format_parameter_none(self):
2323
self.assertEqual({}, utils.format_parameters(None))
2424

2525
def test_format_parameters(self):
26-
p = utils.format_parameters(
26+
p = utils.format_parameters([
2727
'InstanceType=m1.large;DBUsername=wp;'
2828
'DBPassword=verybadpassword;KeyName=heat_key;'
29-
'LinuxDistribution=F17')
29+
'LinuxDistribution=F17'])
3030
self.assertEqual({'InstanceType': 'm1.large',
3131
'DBUsername': 'wp',
3232
'DBPassword': 'verybadpassword',
@@ -35,20 +35,50 @@ def test_format_parameters(self):
3535
}, p)
3636

3737
def test_format_parameters_split(self):
38-
p = utils.format_parameters(
38+
p = utils.format_parameters([
3939
'KeyName=heat_key;'
4040
'DnsSecKey=hsgx1m31PbamNF4WEcHlwjIlCGgifOdoB58/wwC7a4oAONQ/fDV5ct'
4141
'qrYBoLlKHhTfkyQEw9iVScKYZbbMtMNg==;'
42-
'UpstreamDNS=8.8.8.8')
42+
'UpstreamDNS=8.8.8.8'])
4343
self.assertEqual({'KeyName': 'heat_key',
4444
'DnsSecKey': 'hsgx1m31PbamNF4WEcHlwjIlCGgifOdoB58/ww'
4545
'C7a4oAONQ/fDV5ctqrYBoLlKHhTfkyQEw9iVScKYZbbMtMNg==',
4646
'UpstreamDNS': '8.8.8.8'}, p)
4747

48+
def test_format_parameters_multiple(self):
49+
p = utils.format_parameters([
50+
'KeyName=heat_key',
51+
'DnsSecKey=hsgx1m31PbamNF4WEcHlwjIlCGgifOdoB58/wwC7a4oAONQ/fDV5ct'
52+
'qrYBoLlKHhTfkyQEw9iVScKYZbbMtMNg==',
53+
'UpstreamDNS=8.8.8.8'])
54+
self.assertEqual({'KeyName': 'heat_key',
55+
'DnsSecKey': 'hsgx1m31PbamNF4WEcHlwjIlCGgifOdoB58/ww'
56+
'C7a4oAONQ/fDV5ctqrYBoLlKHhTfkyQEw9iVScKYZbbMtMNg==',
57+
'UpstreamDNS': '8.8.8.8'}, p)
58+
59+
def test_format_parameters_multiple_semicolon_values(self):
60+
p = utils.format_parameters([
61+
'KeyName=heat_key',
62+
'DnsSecKey=hsgx1m31;PbaNF4WEcHlwj;IlCGgfOdoB;58/ww7a4oAO;NQ/fD==',
63+
'UpstreamDNS=8.8.8.8'])
64+
self.assertEqual({'KeyName': 'heat_key',
65+
'DnsSecKey': 'hsgx1m31;PbaNF4WEcHlwj;IlCGgfOdoB;58/'
66+
'ww7a4oAO;NQ/fD==',
67+
'UpstreamDNS': '8.8.8.8'}, p)
68+
4869
def test_format_parameter_bad_parameter(self):
49-
params = 'KeyName=heat_key;UpstreamDNS8.8.8.8'
50-
self.assertRaises(exc.CommandError,
51-
utils.format_parameters, params)
70+
params = ['KeyName=heat_key;UpstreamDNS8.8.8.8']
71+
ex = self.assertRaises(exc.CommandError,
72+
utils.format_parameters, params)
73+
self.assertEqual('Malformed parameter(UpstreamDNS8.8.8.8). '
74+
'Use the key=value format.', str(ex))
75+
76+
def test_format_multiple_bad_parameter(self):
77+
params = ['KeyName=heat_key', 'UpstreamDNS8.8.8.8']
78+
ex = self.assertRaises(exc.CommandError,
79+
utils.format_parameters, params)
80+
self.assertEqual('Malformed parameter(UpstreamDNS8.8.8.8). '
81+
'Use the key=value format.', str(ex))
5282

5383
def test_link_formatter(self):
5484
self.assertEqual('', utils.link_formatter(None))

heatclient/v1/shell.py

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ def _process_environment_and_files(hc, args, fields):
103103
@utils.arg('-r', '--enable-rollback', default=False, action="store_true",
104104
help='Enable rollback on create/update failure')
105105
@utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
106-
help='Parameter values used to create the stack.')
106+
help='Parameter values used to create the stack. '
107+
'This can be specified multiple times, or once with parameters '
108+
'separated by semicolon.',
109+
action='append')
107110
@utils.arg('name', metavar='<STACK_NAME>',
108111
help='Name of the stack to create.')
109112
def do_create(hc, args):
@@ -125,7 +128,10 @@ def do_create(hc, args):
125128
@utils.arg('-r', '--enable-rollback', default=False, action="store_true",
126129
help='Enable rollback on create/update failure')
127130
@utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
128-
help='Parameter values used to create the stack.')
131+
help='Parameter values used to create the stack. '
132+
'This can be specified multiple times, or once with parameters '
133+
'separated by semicolon.',
134+
action='append')
129135
@utils.arg('name', metavar='<STACK_NAME>',
130136
help='Name of the stack to create.')
131137
def do_stack_create(hc, args):
@@ -221,7 +227,10 @@ def do_stack_show(hc, args):
221227
@utils.arg('-o', '--template-object', metavar='<URL>',
222228
help='URL to retrieve template object (e.g from swift)')
223229
@utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
224-
help='Parameter values used to create the stack.')
230+
help='Parameter values used to create the stack. '
231+
'This can be specified multiple times, or once with parameters '
232+
'separated by semicolon.',
233+
action='append')
225234
@utils.arg('id', metavar='<NAME or ID>',
226235
help='Name or ID of stack to update.')
227236
def do_update(hc, args):
@@ -238,7 +247,10 @@ def do_update(hc, args):
238247
@utils.arg('-o', '--template-object', metavar='<URL>',
239248
help='URL to retrieve template object (e.g from swift)')
240249
@utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
241-
help='Parameter values used to create the stack.')
250+
help='Parameter values used to create the stack. '
251+
'This can be specified multiple times, or once with parameters '
252+
'separated by semicolon.',
253+
action='append')
242254
@utils.arg('id', metavar='<NAME or ID>',
243255
help='Name or ID of stack to update.')
244256
def do_stack_update(hc, args):
@@ -297,7 +309,10 @@ def do_template_show(hc, args):
297309
@utils.arg('-o', '--template-object', metavar='<URL>',
298310
help='URL to retrieve template object (e.g from swift)')
299311
@utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
300-
help='Parameter values to validate.')
312+
help='Parameter values to validate. '
313+
'This can be specified multiple times, or once with parameters '
314+
'separated by semicolon.',
315+
action='append')
301316
def do_validate(hc, args):
302317
'''DEPRECATED! Use template-validate instead.'''
303318
do_template_validate(hc, args)
@@ -312,7 +327,10 @@ def do_validate(hc, args):
312327
@utils.arg('-o', '--template-object', metavar='<URL>',
313328
help='URL to retrieve template object (e.g from swift)')
314329
@utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>',
315-
help='Parameter values to validate.')
330+
help='Parameter values to validate. '
331+
'This can be specified multiple times, or once with parameters '
332+
'separated by semicolon.',
333+
action='append')
316334
def do_template_validate(hc, args):
317335
'''Validate a template with parameters.'''
318336
fields = {'parameters': utils.format_parameters(args.parameters)}

0 commit comments

Comments
 (0)