Skip to content

Commit 3ff6971

Browse files
committed
Merge branch 'fix-407' of git://github.com/garnaat/aws-cli into garnaat-fix-407
2 parents 7edca37 + 60b3820 commit 3ff6971

File tree

3 files changed

+77
-10
lines changed

3 files changed

+77
-10
lines changed

awscli/argprocess.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@
1212
# language governing permissions and limitations under the License.
1313
"""Module for processing CLI args."""
1414
import os
15-
import json
1615
import logging
1716
import six
1817

18+
from botocore.compat import OrderedDict, json
19+
1920
from awscli import utils
2021
from awscli import SCALAR_TYPES, COMPLEX_TYPES
2122

@@ -243,7 +244,7 @@ def _key_value_parse(self, param, value):
243244
# that is, csv key value pairs, where the key and values
244245
# are separated by '='. All of this should be whitespace
245246
# insensitive.
246-
parsed = {}
247+
parsed = OrderedDict()
247248
parts = self._split_on_commas(value)
248249
valid_names = self._create_name_to_params(param)
249250
for part in parts:
@@ -253,18 +254,19 @@ def _key_value_parse(self, param, value):
253254
raise ParamSyntaxError(part)
254255
key = key.strip()
255256
value = value.strip()
256-
if key not in valid_names:
257+
if valid_names and key not in valid_names:
257258
raise ParamUnknownKeyError(param, key, valid_names)
258-
sub_param = valid_names[key]
259-
if sub_param is not None:
260-
value = unpack_scalar_cli_arg(sub_param, value)
259+
if valid_names:
260+
sub_param = valid_names[key]
261+
if sub_param is not None:
262+
value = unpack_scalar_cli_arg(sub_param, value)
261263
parsed[key] = value
262264
return parsed
263265

264266
def _create_name_to_params(self, param):
265267
if param.type == 'structure':
266268
return dict([(p.name, p) for p in param.members])
267-
elif param.type == 'map':
269+
elif param.type == 'map' and hasattr(param.keys, 'enum'):
268270
return dict([(v, None) for v in param.keys.enum])
269271

270272
def _docs_list_scalar_list_parse(self, param):
@@ -351,7 +353,7 @@ def unpack_cli_arg(parameter, value):
351353
def unpack_complex_cli_arg(parameter, value):
352354
if parameter.type == 'structure' or parameter.type == 'map':
353355
if value.lstrip()[0] == '{':
354-
d = json.loads(value)
356+
d = json.loads(value, object_pairs_hook=OrderedDict)
355357
else:
356358
msg = 'The value for parameter "%s" must be JSON or path to file.' % (
357359
parameter.cli_name)
@@ -360,11 +362,11 @@ def unpack_complex_cli_arg(parameter, value):
360362
elif parameter.type == 'list':
361363
if isinstance(value, six.string_types):
362364
if value.lstrip()[0] == '[':
363-
return json.loads(value)
365+
return json.loads(value, object_pairs_hook=OrderedDict)
364366
elif isinstance(value, list) and len(value) == 1:
365367
single_value = value[0].strip()
366368
if single_value and single_value[0] == '[':
367-
return json.loads(value[0])
369+
return json.loads(value[0], object_pairs_hook=OrderedDict)
368370
return [unpack_cli_arg(parameter.members, v) for v in value]
369371

370372

tests/unit/sns/__init__.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License"). You
4+
# may not use this file except in compliance with the License. A copy of
5+
# the License is located at
6+
#
7+
# http://aws.amazon.com/apache2.0/
8+
#
9+
# or in the "license" file accompanying this file. This file is
10+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11+
# ANY KIND, either express or implied. See the License for the specific
12+
# language governing permissions and limitations under the License.
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env python
2+
# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License"). You
5+
# may not use this file except in compliance with the License. A copy of
6+
# the License is located at
7+
#
8+
# http://aws.amazon.com/apache2.0/
9+
#
10+
# or in the "license" file accompanying this file. This file is
11+
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
12+
# ANY KIND, either express or implied. See the License for the specific
13+
# language governing permissions and limitations under the License.
14+
from tests.unit import BaseAWSCommandParamsTest
15+
16+
17+
class TestCreatePlatformApplication(BaseAWSCommandParamsTest):
18+
19+
prefix = 'sns create-platform-application'
20+
21+
def test_gcm_shorthand(self):
22+
cmdline = self.prefix
23+
cmdline += ' --name gcmpushapp'
24+
cmdline += ' --platform GCM'
25+
cmdline += ' --attributes '
26+
cmdline += 'PlatformCredential=foo,'
27+
cmdline += 'PlatformPrincipal=bar'
28+
result = {'Name': 'gcmpushapp',
29+
'Platform': 'GCM',
30+
'Attributes.entry.1.key': 'PlatformCredential',
31+
'Attributes.entry.1.value': 'foo',
32+
'Attributes.entry.2.key': 'PlatformPrincipal',
33+
'Attributes.entry.2.value': 'bar'}
34+
self.assert_params_for_cmd(cmdline, result)
35+
36+
def test_gcm_json(self):
37+
cmdline = self.prefix
38+
cmdline += ' --name gcmpushapp'
39+
cmdline += ' --platform GCM'
40+
cmdline += ' --attributes '
41+
cmdline += ('{"PlatformCredential":"AIzaSyClE2lcV2zEKTLYYo645zfk2jhQPFeyxDo",'
42+
'"PlatformPrincipal":"There+is+no+principal+for+GCM"}')
43+
result = {'Name': 'gcmpushapp',
44+
'Platform': 'GCM',
45+
'Attributes.entry.1.key': 'PlatformCredential',
46+
'Attributes.entry.1.value': 'AIzaSyClE2lcV2zEKTLYYo645zfk2jhQPFeyxDo',
47+
'Attributes.entry.2.key': 'PlatformPrincipal',
48+
'Attributes.entry.2.value': 'There+is+no+principal+for+GCM'}
49+
self.assert_params_for_cmd(cmdline, result)
50+
51+
52+
if __name__ == "__main__":
53+
unittest.main()

0 commit comments

Comments
 (0)