Repository: getmoto/moto

Issue:
CloudFormation's GetTemplate response is inaccurate
The GetTemplate function returns through `boto` the following format:

``` python
>>> import boto.cloudformation
>>> cf = boto.cloudformation.connect_to_region('us-east-1')
>>> cf.get_template('<my-stack-id>')
{u'GetTemplateResponse': {u'GetTemplateResult': {u'TemplateBody': u'{"Resources": "<RESOURCES HERE>"}', u'ResponseMetadata': {u'RequestId': u'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee'}}}
```

But moto returns just the template body... Moto's source: https://github.com/spulec/moto/blob/1dcfcbca5711ac50f9c3314b8a7e8812e3025156/moto/cloudformation/responses.py#L87-L91

AWS Docs: http://docs.aws.amazon.com/AWSCloudFormation/latest/APIReference/API_GetTemplate.html



Discussion:

Resolving patch:
diff --git a/moto/cloudformation/responses.py b/moto/cloudformation/responses.py
--- a/moto/cloudformation/responses.py
+++ b/moto/cloudformation/responses.py
@@ -86,9 +86,19 @@ def list_stack_resources(self):
 
     def get_template(self):
         name_or_stack_id = self.querystring.get('StackName')[0]
-
         stack = self.cloudformation_backend.get_stack(name_or_stack_id)
-        return stack.template
+
+        response = {
+            "GetTemplateResponse": {
+            "GetTemplateResult": {
+                "TemplateBody": stack.template,
+                "ResponseMetadata": {
+                    "RequestId": "2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE"
+                }
+            }
+          }
+        }
+        return json.dumps(response)
 
     def update_stack(self):
         stack_name = self._get_param('StackName')


Test patch:
diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud.py b/tests/test_cloudformation/test_cloudformation_stack_crud.py
--- a/tests/test_cloudformation/test_cloudformation_stack_crud.py
+++ b/tests/test_cloudformation/test_cloudformation_stack_crud.py
@@ -40,7 +40,17 @@ def test_create_stack():
 
     stack = conn.describe_stacks()[0]
     stack.stack_name.should.equal('test_stack')
-    stack.get_template().should.equal(dummy_template)
+    stack.get_template().should.equal({
+        'GetTemplateResponse': {
+            'GetTemplateResult': {
+                'TemplateBody': dummy_template_json,
+                'ResponseMetadata': {
+                    'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
+                }
+            }
+        }
+
+    })
 
 
 @mock_cloudformation
@@ -83,7 +93,18 @@ def test_create_stack_from_s3_url():
 
     stack = conn.describe_stacks()[0]
     stack.stack_name.should.equal('new-stack')
-    stack.get_template().should.equal(dummy_template)
+    stack.get_template().should.equal(
+        {
+        'GetTemplateResponse': {
+            'GetTemplateResult': {
+                'TemplateBody': dummy_template_json,
+                'ResponseMetadata': {
+                    'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
+                }
+            }
+        }
+
+    })
 
 
 @mock_cloudformation
@@ -138,7 +159,17 @@ def test_get_template_by_name():
     )
 
     template = conn.get_template("test_stack")
-    template.should.equal(dummy_template)
+    template.should.equal({
+        'GetTemplateResponse': {
+            'GetTemplateResult': {
+                'TemplateBody': dummy_template_json,
+                'ResponseMetadata': {
+                    'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
+                }
+            }
+        }
+
+    })
 
 
 @mock_cloudformation
@@ -243,4 +274,13 @@ def test_stack_tags():
 #     conn.update_stack("test_stack", dummy_template_json2)
 
 #     stack = conn.describe_stacks()[0]
-#     stack.get_template().should.equal(dummy_template2)
+#     stack.get_template().should.equal({
+#         'GetTemplateResponse': {
+#             'GetTemplateResult': {
+#                 'TemplateBody': dummy_template_json2,
+#                 'ResponseMetadata': {
+#                     'RequestId': '2d06e36c-ac1d-11e0-a958-f9382b6eb86bEXAMPLE'
+#                 }
+#             }
+#         }
+#     })