Repository: aws/aws-cli

Issue:
aws ec2 modify-instance-attribute seems to fail with --source-dest-check parameter
Hi,

I need to call modify-instance-attribute from within my own instance, in order to automate the bootstrap process of my NAT instances.

Here is what happens (btw: $INSTANCE_ID contains a valid InstanceId):

# aws ec2 modify-instance-attribute --instance-id $INSTANCE_ID --source-dest-check 0 --region sa-east-1 --debug

2013-07-16 16:50:28,041 - botocore.service - DEBUG - Creating service object for: ec2
2013-07-16 16:50:28,042 - botocore.base - DEBUG - Attempting to Load: aws/ec2
2013-07-16 16:50:28,394 - botocore.base - DEBUG - Found data file: /usr/lib/python2.6/site-packages/botocore/data/aws/ec2.json
2013-07-16 16:50:28,394 - botocore.hooks - DEBUG - emit: service-created
2013-07-16 16:50:28,395 - botocore.service - DEBUG - Creating operation objects for: Service(ec2)
2013-07-16 16:50:28,412 - botocore.hooks - DEBUG - emit: parser-created.ec2
2013-07-16 16:50:28,413 - botocore.operation - DEBUG - Creating parameter objects for: Operation:ModifyInstanceAttribute
2013-07-16 16:50:28,417 - botocore.hooks - DEBUG - emit: parser-created.ec2-modify-instance-attribute
2013-07-16 16:50:28,418 - botocore.hooks - DEBUG - emit: process-cli-arg.ec2.modify-instance-attribute
2013-07-16 16:50:28,418 - botocore.hooks - DEBUG - emit: calling <awscli.argprocess.ParamShorthand object at 0x27dad10>
Traceback (most recent call last):
  File "/usr/lib/python2.6/site-packages/awscli/clidriver.py", line 168, in _call
    self._build_call_parameters(args, params)
  File "/usr/lib/python2.6/site-packages/awscli/clidriver.py", line 121, in _build_call_parameters
    param_dict[param.py_name] = unpack_cli_arg(param, value)
  File "/usr/lib/python2.6/site-packages/awscli/argprocess.py", line 344, in unpack_cli_arg
    return unpack_complex_cli_arg(parameter, value)
  File "/usr/lib/python2.6/site-packages/awscli/argprocess.py", line 355, in unpack_complex_cli_arg
    raise ValueError(msg)
ValueError: Structure option value must be JSON or path to file.

The output is the same if I use --source-dest-check false. If the call isn't supposed to be done like that, then I think it lacks better documentation.

Thanks a lot



Discussion:
Yeah, the error messages can be improved.  The actual call you need currently is:

`--source-dest-check '{"Value": true}'`
`--source-dest-check '{"Value": false}'`

Leaving this open while we work out error messages as well as alternative approaches for boolean args.


Resolving patch:
diff --git a/awscli/argprocess.py b/awscli/argprocess.py
--- a/awscli/argprocess.py
+++ b/awscli/argprocess.py
@@ -333,7 +333,8 @@ def unpack_complex_cli_arg(parameter, value):
         if value.lstrip()[0] == '{':
             d = json.loads(value)
         else:
-            msg = 'Structure option value must be JSON or path to file.'
+            msg = 'The value for parameter "%s" must be JSON or path to file.' % (
+                parameter.cli_name)
             raise ValueError(msg)
         return d
     elif parameter.type == 'list':


Test patch:
diff --git a/tests/unit/ec2/test_modify_image_attribute.py b/tests/unit/ec2/test_modify_image_attribute.py
--- a/tests/unit/ec2/test_modify_image_attribute.py
+++ b/tests/unit/ec2/test_modify_image_attribute.py
@@ -39,6 +39,14 @@ def test_two(self):
                   }
         self.assert_params_for_cmd(cmdline, result)
 
+    def test_assert_error_in_bad_json_path(self):
+        cmdline = self.prefix
+        cmdline += ' --image-id ami-d00dbeef'
+        cmdline += ' --launch-permission THISISNOTJSON'
+        # The arg name should be in the error message.
+        self.assert_params_for_cmd(cmdline, {}, expected_rc=255,
+                                   stderr_contains='launch-permission')
+
 
 if __name__ == "__main__":
     unittest.main()