diff options
author | Steve Baker <sbaker@redhat.com> | 2013-09-23 17:55:55 +1200 |
---|---|---|
committer | Steve Baker <sbaker@redhat.com> | 2013-09-25 16:10:32 +1200 |
commit | 795d52c6418fa3beab2e3385da11ece8fca3db37 (patch) | |
tree | 949477860d8881e972c7a6c5f5bb6633ae33eef0 | |
parent | 978e3f45423acc86b7836a4c07a42bbf878f31d4 (diff) | |
download | python-heatclient-795d52c6418fa3beab2e3385da11ece8fca3db37.tar.gz |
Allow -P to be invoked multiple times
If --parameters is specified more than once it is assumed
that each one contains only one parameter key=value.
This means semicolons are ignored if there is more than one -P
specified.
This should be fully backwared compatible, a single -P will
be assumed to be semicolon delimited.
Change-Id: Ic202ff3e0596b786cd5b07c53509f97a95d41585
Closes-Bug: #1224825
Closes-Bug: #1229030
-rw-r--r-- | heatclient/common/utils.py | 28 | ||||
-rw-r--r-- | heatclient/tests/test_utils.py | 44 | ||||
-rw-r--r-- | heatclient/v1/shell.py | 30 |
3 files changed, 79 insertions, 23 deletions
diff --git a/heatclient/common/utils.py b/heatclient/common/utils.py index aa8ee0b..a174fff 100644 --- a/heatclient/common/utils.py +++ b/heatclient/common/utils.py @@ -147,17 +147,25 @@ def exit(msg=''): def format_parameters(params): '''Reformat parameters into dict of format expected by the API.''' + + if not params: + return {} + + # expect multiple invocations of --parameters but fall back + # to ; delimited if only one --parameters is specified + if len(params) == 1: + params = params[0].split(';') + parameters = {} - if params: - for count, p in enumerate(params.split(';'), 1): - try: - (n, v) = p.split(('='), 1) - except ValueError: - msg = '%s(%s). %s.' % ('Malformed parameter', p, - 'Use the key=value format') - raise exc.CommandError(msg) - - parameters[n] = v + for p in params: + try: + (n, v) = p.split(('='), 1) + except ValueError: + msg = '%s(%s). %s.' % ('Malformed parameter', p, + 'Use the key=value format') + raise exc.CommandError(msg) + + parameters[n] = v return parameters diff --git a/heatclient/tests/test_utils.py b/heatclient/tests/test_utils.py index 05e97fa..faea928 100644 --- a/heatclient/tests/test_utils.py +++ b/heatclient/tests/test_utils.py @@ -23,10 +23,10 @@ class shellTest(testtools.TestCase): self.assertEqual({}, utils.format_parameters(None)) def test_format_parameters(self): - p = utils.format_parameters( + p = utils.format_parameters([ 'InstanceType=m1.large;DBUsername=wp;' 'DBPassword=verybadpassword;KeyName=heat_key;' - 'LinuxDistribution=F17') + 'LinuxDistribution=F17']) self.assertEqual({'InstanceType': 'm1.large', 'DBUsername': 'wp', 'DBPassword': 'verybadpassword', @@ -35,20 +35,50 @@ class shellTest(testtools.TestCase): }, p) def test_format_parameters_split(self): - p = utils.format_parameters( + p = utils.format_parameters([ 'KeyName=heat_key;' 'DnsSecKey=hsgx1m31PbamNF4WEcHlwjIlCGgifOdoB58/wwC7a4oAONQ/fDV5ct' 'qrYBoLlKHhTfkyQEw9iVScKYZbbMtMNg==;' - 'UpstreamDNS=8.8.8.8') + 'UpstreamDNS=8.8.8.8']) self.assertEqual({'KeyName': 'heat_key', 'DnsSecKey': 'hsgx1m31PbamNF4WEcHlwjIlCGgifOdoB58/ww' 'C7a4oAONQ/fDV5ctqrYBoLlKHhTfkyQEw9iVScKYZbbMtMNg==', 'UpstreamDNS': '8.8.8.8'}, p) + def test_format_parameters_multiple(self): + p = utils.format_parameters([ + 'KeyName=heat_key', + 'DnsSecKey=hsgx1m31PbamNF4WEcHlwjIlCGgifOdoB58/wwC7a4oAONQ/fDV5ct' + 'qrYBoLlKHhTfkyQEw9iVScKYZbbMtMNg==', + 'UpstreamDNS=8.8.8.8']) + self.assertEqual({'KeyName': 'heat_key', + 'DnsSecKey': 'hsgx1m31PbamNF4WEcHlwjIlCGgifOdoB58/ww' + 'C7a4oAONQ/fDV5ctqrYBoLlKHhTfkyQEw9iVScKYZbbMtMNg==', + 'UpstreamDNS': '8.8.8.8'}, p) + + def test_format_parameters_multiple_semicolon_values(self): + p = utils.format_parameters([ + 'KeyName=heat_key', + 'DnsSecKey=hsgx1m31;PbaNF4WEcHlwj;IlCGgfOdoB;58/ww7a4oAO;NQ/fD==', + 'UpstreamDNS=8.8.8.8']) + self.assertEqual({'KeyName': 'heat_key', + 'DnsSecKey': 'hsgx1m31;PbaNF4WEcHlwj;IlCGgfOdoB;58/' + 'ww7a4oAO;NQ/fD==', + 'UpstreamDNS': '8.8.8.8'}, p) + def test_format_parameter_bad_parameter(self): - params = 'KeyName=heat_key;UpstreamDNS8.8.8.8' - self.assertRaises(exc.CommandError, - utils.format_parameters, params) + params = ['KeyName=heat_key;UpstreamDNS8.8.8.8'] + ex = self.assertRaises(exc.CommandError, + utils.format_parameters, params) + self.assertEqual('Malformed parameter(UpstreamDNS8.8.8.8). ' + 'Use the key=value format.', str(ex)) + + def test_format_multiple_bad_parameter(self): + params = ['KeyName=heat_key', 'UpstreamDNS8.8.8.8'] + ex = self.assertRaises(exc.CommandError, + utils.format_parameters, params) + self.assertEqual('Malformed parameter(UpstreamDNS8.8.8.8). ' + 'Use the key=value format.', str(ex)) def test_link_formatter(self): self.assertEqual('', utils.link_formatter(None)) diff --git a/heatclient/v1/shell.py b/heatclient/v1/shell.py index 23bbff7..75beae5 100644 --- a/heatclient/v1/shell.py +++ b/heatclient/v1/shell.py @@ -103,7 +103,10 @@ def _process_environment_and_files(hc, args, fields): @utils.arg('-r', '--enable-rollback', default=False, action="store_true", help='Enable rollback on create/update failure') @utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>', - help='Parameter values used to create the stack.') + help='Parameter values used to create the stack. ' + 'This can be specified multiple times, or once with parameters ' + 'separated by semicolon.', + action='append') @utils.arg('name', metavar='<STACK_NAME>', help='Name of the stack to create.') def do_create(hc, args): @@ -125,7 +128,10 @@ def do_create(hc, args): @utils.arg('-r', '--enable-rollback', default=False, action="store_true", help='Enable rollback on create/update failure') @utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>', - help='Parameter values used to create the stack.') + help='Parameter values used to create the stack. ' + 'This can be specified multiple times, or once with parameters ' + 'separated by semicolon.', + action='append') @utils.arg('name', metavar='<STACK_NAME>', help='Name of the stack to create.') def do_stack_create(hc, args): @@ -221,7 +227,10 @@ def do_stack_show(hc, args): @utils.arg('-o', '--template-object', metavar='<URL>', help='URL to retrieve template object (e.g from swift)') @utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>', - help='Parameter values used to create the stack.') + help='Parameter values used to create the stack. ' + 'This can be specified multiple times, or once with parameters ' + 'separated by semicolon.', + action='append') @utils.arg('id', metavar='<NAME or ID>', help='Name or ID of stack to update.') def do_update(hc, args): @@ -238,7 +247,10 @@ def do_update(hc, args): @utils.arg('-o', '--template-object', metavar='<URL>', help='URL to retrieve template object (e.g from swift)') @utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>', - help='Parameter values used to create the stack.') + help='Parameter values used to create the stack. ' + 'This can be specified multiple times, or once with parameters ' + 'separated by semicolon.', + action='append') @utils.arg('id', metavar='<NAME or ID>', help='Name or ID of stack to update.') def do_stack_update(hc, args): @@ -297,7 +309,10 @@ def do_template_show(hc, args): @utils.arg('-o', '--template-object', metavar='<URL>', help='URL to retrieve template object (e.g from swift)') @utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>', - help='Parameter values to validate.') + help='Parameter values to validate. ' + 'This can be specified multiple times, or once with parameters ' + 'separated by semicolon.', + action='append') def do_validate(hc, args): '''DEPRECATED! Use template-validate instead.''' do_template_validate(hc, args) @@ -312,7 +327,10 @@ def do_validate(hc, args): @utils.arg('-o', '--template-object', metavar='<URL>', help='URL to retrieve template object (e.g from swift)') @utils.arg('-P', '--parameters', metavar='<KEY1=VALUE1;KEY2=VALUE2...>', - help='Parameter values to validate.') + help='Parameter values to validate. ' + 'This can be specified multiple times, or once with parameters ' + 'separated by semicolon.', + action='append') def do_template_validate(hc, args): '''Validate a template with parameters.''' fields = {'parameters': utils.format_parameters(args.parameters)} |