Repository: aws/aws-cli

Issue:
Route 53 inconsistent ID use and parsing
concerning AWS cli 1.0 , using ubuntu 12.04.

So when I am using the aws cli tool to get a list of hosted zone, I get a results with the ID being

```
"HostedZones": [
    {
        "ResourceRecordSetCount": 22, 
        "Config": {}, 
        "Id": "/hostedzone/Z2YTXXZMOVI7G7", 
        "Name": "mydomain.com."
    }
```

if I try to do call on that hosted zone ID I get an unknown error.

aws route53 change-resource-record-sets --hosted-zone-id "/hostedzone/Z2YTXXZMOVI7G7" --change-batch '{"Comment": "automatic setup", "Changes": [{"Action": "CREATE","ResourceRecordSet":{"Name":"test.mydomain.com","Type":"CNAME", "TTL":300, "ResourceRecords": [{"Value": "10.0.0.1" }]}}]}' --region us-west-2

 If I fix the ID to not have the /hostedzone then it works fine

aws route53 change-resource-record-sets --hosted-zone-id "Z2YTXXZMOVI7G7" --change-batch '{"Comment": "automatic setup", "Changes": [{"Action": "CREATE","ResourceRecordSet":{"Name":"test.mydomain.com","Type":"CNAME", "TTL":300, "ResourceRecords": [{"Value": "10.0.0.1" }]}}]}' --region us-west-2

This is very confusing because I have to parse an ID in this case and take only part of it. I believe the tool should handle that on its own, so that I can pass directly the id returned from the list-hosted-zone to make the experience cleaner.  Or at least not break as an unkown error was hard to figure out what I was doing wrong or not.

By the way, same applies to the GetChange when specifying the change ID .  The repsonse of the change-resource-record-sets return this

```
"ChangeInfo": {
    "Status": "PENDING", 
    "Comment": "automatic setup", 
    "SubmittedAt": "2013-10-07T18:02:38.139Z", 
    "Id": "/change/CD6SVDA4ZI2EK"
}
```

But again, the ID does not work when doing (get an unknown error)

aws route53 get-change --id "/change/CD6SVDA4ZI2EK"

but works with 

aws route53 get-change --id "CD6SVDA4ZI2EK"



Discussion:
:+1: 
Workaround in bash: 
`ZONE_ID=$(echo '/hostedzone/XYZ1234XYZ' | sed 's/\/hostedzone\///')`

But it would be nice for this to be consistent

I agree that it's confusing and it should be fixed.

There are two ways to address this.

We could change the option parsing to strip of the resource name prefix, e.g. accept either `/hostedzone/XYZ1234XYZ` to `XYZ1234XYZ` as the value of a resource ID.

Or, we could manipulate the output to filter out the prefix there so it never gets returned in the first place.

The latter seems better but could break existing scripts.

@jamesls @toastdriven - Opinions?

@garnaat I'm actually in favor of the former. I'd prefer to leave the output exactly as the service provides (makes it easier to line up with API docs). The code will perhaps be simpler as well (just stripping the `hostedzone` vs. manipulating a possibly complex body).

I prefer the former as well. I want to make sure I get the exact same response. And having the tool helping me format the request in case I missed something is better approach too I think . So former would be great!

I slightly favored the latter because it seemed like an anomaly in the service output to include the resource prefix in the first place.  But I agree with the argument of not altering the service output and doing the correction (if necessary) on the input side.

I'll work on that and update this with a PR when ready.


Resolving patch:
diff --git a/awscli/customizations/route53resourceid.py b/awscli/customizations/route53resourceid.py
new file mode 100644
--- /dev/null
+++ b/awscli/customizations/route53resourceid.py
@@ -0,0 +1,30 @@
+# Copyright 2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+#     http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+import logging
+
+
+logger = logging.getLogger(__name__)
+
+
+def register_resource_id(cli):
+    cli.register('process-cli-arg.route53.*',
+                 _check_for_resource_id)
+
+
+def _check_for_resource_id(param, value, **kwargs):
+    if hasattr(param, 'shape_name'):
+        if param.shape_name == 'ResourceId':
+            orig_value = value
+            value = value.split('/')[-1]
+            logger.debug('ResourceId %s -> %s', orig_value, value)
+    return value
diff --git a/awscli/handlers.py b/awscli/handlers.py
--- a/awscli/handlers.py
+++ b/awscli/handlers.py
@@ -35,6 +35,7 @@
 from awscli.customizations.iamvirtmfa import IAMVMFAWrapper
 from awscli.customizations.argrename import register_arg_renames
 from awscli.customizations.dryrundocs import register_dryrun_docs
+from awscli.customizations.route53resourceid import register_resource_id
 
 
 def awscli_initialize(event_handlers):
@@ -73,3 +74,4 @@ def awscli_initialize(event_handlers):
     IAMVMFAWrapper(event_handlers)
     register_arg_renames(event_handlers)
     register_dryrun_docs(event_handlers)
+    register_resource_id(event_handlers)


Test patch:
diff --git a/tests/unit/route53/__init__.py b/tests/unit/route53/__init__.py
new file mode 100644
--- /dev/null
+++ b/tests/unit/route53/__init__.py
@@ -0,0 +1,12 @@
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+#     http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
diff --git a/tests/unit/route53/test_resource_id.py b/tests/unit/route53/test_resource_id.py
new file mode 100644
--- /dev/null
+++ b/tests/unit/route53/test_resource_id.py
@@ -0,0 +1,64 @@
+#!/usr/bin/env python
+# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"). You
+# may not use this file except in compliance with the License. A copy of
+# the License is located at
+#
+#     http://aws.amazon.com/apache2.0/
+#
+# or in the "license" file accompanying this file. This file is
+# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
+# ANY KIND, either express or implied. See the License for the specific
+# language governing permissions and limitations under the License.
+from tests.unit import BaseAWSCommandParamsTest
+
+
+class TestGetHostedZone(BaseAWSCommandParamsTest):
+
+    prefix = 'route53 get-hosted-zone'
+
+    def setUp(self):
+        super(TestGetHostedZone, self).setUp()
+
+    def test_full_resource_id(self):
+        args = ' --id /hostedzone/ZD3IYMVP1KDDM'
+        cmdline = self.prefix + args
+        result = {'uri_params': {'Id': 'ZD3IYMVP1KDDM'},
+                  'headers': {}}
+        self.assert_params_for_cmd(cmdline, result, expected_rc=0,
+                                   ignore_params=['payload'])[0]
+
+    def test_short_resource_id(self):
+        args = ' --id ZD3IYMVP1KDDM'
+        cmdline = self.prefix + args
+        result = {'uri_params': {'Id': 'ZD3IYMVP1KDDM'},
+                  'headers': {}}
+        self.assert_params_for_cmd(cmdline, result, expected_rc=0,
+                                   ignore_params=['payload'])[0]
+
+
+class TestGetChange(BaseAWSCommandParamsTest):
+
+    prefix = 'route53 get-change'
+
+    def setUp(self):
+        super(TestGetChange, self).setUp()
+
+    def test_full_resource_id(self):
+        args = ' --id /change/ZD3IYMVP1KDDM'
+        cmdline = self.prefix + args
+        result = {'uri_params': {'Id': 'ZD3IYMVP1KDDM'},
+                  'headers': {}}
+        self.assert_params_for_cmd(cmdline, result, expected_rc=0,
+                                   ignore_params=['payload'])[0]
+
+    def test_short_resource_id(self):
+        args = ' --id ZD3IYMVP1KDDM'
+        cmdline = self.prefix + args
+        result = {'uri_params': {'Id': 'ZD3IYMVP1KDDM'},
+                  'headers': {}}
+        self.assert_params_for_cmd(cmdline, result, expected_rc=0,
+                                   ignore_params=['payload'])[0]
+
+