CF : Added support for get template summary (#3179)
* CF : Added support for get template summary * Linting Co-authored-by: Bert Blommers <info@bertblommers.nl>
This commit is contained in:
parent
03dd55d39d
commit
bc1674cb19
@ -10,6 +10,31 @@ from moto.s3 import s3_backend
|
||||
from moto.core import ACCOUNT_ID
|
||||
from .models import cloudformation_backends
|
||||
from .exceptions import ValidationError
|
||||
from .utils import yaml_tag_constructor
|
||||
|
||||
|
||||
def get_template_summary_response_from_template(template_body):
|
||||
def get_resource_types(template_dict):
|
||||
resources = {}
|
||||
for key, value in template_dict.items():
|
||||
if key == "Resources":
|
||||
resources = value
|
||||
|
||||
resource_types = []
|
||||
for key, value in resources.items():
|
||||
resource_types.append(value["Type"])
|
||||
return resource_types
|
||||
|
||||
yaml.add_multi_constructor("", yaml_tag_constructor)
|
||||
|
||||
try:
|
||||
template_dict = yaml.load(template_body, Loader=yaml.Loader)
|
||||
except (yaml.parser.ParserError, yaml.scanner.ScannerError):
|
||||
template_dict = json.loads(template_body)
|
||||
|
||||
resources_types = get_resource_types(template_dict)
|
||||
template_dict["resourceTypes"] = resources_types
|
||||
return template_dict
|
||||
|
||||
|
||||
class CloudFormationResponse(BaseResponse):
|
||||
@ -269,6 +294,20 @@ class CloudFormationResponse(BaseResponse):
|
||||
template = self.response_template(GET_TEMPLATE_RESPONSE_TEMPLATE)
|
||||
return template.render(stack=stack)
|
||||
|
||||
def get_template_summary(self):
|
||||
stack_name = self._get_param("StackName")
|
||||
template_url = self._get_param("TemplateURL")
|
||||
stack_body = self._get_param("TemplateBody")
|
||||
|
||||
if stack_name:
|
||||
stack_body = self.cloudformation_backend.get_stack(stack_name).template
|
||||
elif template_url:
|
||||
stack_body = self._get_stack_from_s3_url(template_url)
|
||||
|
||||
template_summary = get_template_summary_response_from_template(stack_body)
|
||||
template = self.response_template(GET_TEMPLATE_SUMMARY_TEMPLATE)
|
||||
return template.render(template_summary=template_summary)
|
||||
|
||||
def update_stack(self):
|
||||
stack_name = self._get_param("StackName")
|
||||
role_arn = self._get_param("RoleARN")
|
||||
@ -743,7 +782,6 @@ DESCRIBE_STACKS_TEMPLATE = """<DescribeStacksResponse>
|
||||
</DescribeStacksResult>
|
||||
</DescribeStacksResponse>"""
|
||||
|
||||
|
||||
DESCRIBE_STACK_RESOURCE_RESPONSE_TEMPLATE = """<DescribeStackResourceResponse>
|
||||
<DescribeStackResourceResult>
|
||||
<StackResourceDetail>
|
||||
@ -758,7 +796,6 @@ DESCRIBE_STACK_RESOURCE_RESPONSE_TEMPLATE = """<DescribeStackResourceResponse>
|
||||
</DescribeStackResourceResult>
|
||||
</DescribeStackResourceResponse>"""
|
||||
|
||||
|
||||
DESCRIBE_STACK_RESOURCES_RESPONSE = """<DescribeStackResourcesResponse>
|
||||
<DescribeStackResourcesResult>
|
||||
<StackResources>
|
||||
@ -777,7 +814,6 @@ DESCRIBE_STACK_RESOURCES_RESPONSE = """<DescribeStackResourcesResponse>
|
||||
</DescribeStackResourcesResult>
|
||||
</DescribeStackResourcesResponse>"""
|
||||
|
||||
|
||||
DESCRIBE_STACK_EVENTS_RESPONSE = """<DescribeStackEventsResponse xmlns="http://cloudformation.amazonaws.com/doc/2010-05-15/">
|
||||
<DescribeStackEventsResult>
|
||||
<StackEvents>
|
||||
@ -802,7 +838,6 @@ DESCRIBE_STACK_EVENTS_RESPONSE = """<DescribeStackEventsResponse xmlns="http://c
|
||||
</ResponseMetadata>
|
||||
</DescribeStackEventsResponse>"""
|
||||
|
||||
|
||||
LIST_CHANGE_SETS_RESPONSE = """<ListChangeSetsResponse>
|
||||
<ListChangeSetsResult>
|
||||
<Summaries>
|
||||
@ -823,7 +858,6 @@ LIST_CHANGE_SETS_RESPONSE = """<ListChangeSetsResponse>
|
||||
</ListChangeSetsResult>
|
||||
</ListChangeSetsResponse>"""
|
||||
|
||||
|
||||
LIST_STACKS_RESPONSE = """<ListStacksResponse>
|
||||
<ListStacksResult>
|
||||
<StackSummaries>
|
||||
@ -840,7 +874,6 @@ LIST_STACKS_RESPONSE = """<ListStacksResponse>
|
||||
</ListStacksResult>
|
||||
</ListStacksResponse>"""
|
||||
|
||||
|
||||
LIST_STACKS_RESOURCES_RESPONSE = """<ListStackResourcesResponse>
|
||||
<ListStackResourcesResult>
|
||||
<StackResourceSummaries>
|
||||
@ -860,7 +893,6 @@ LIST_STACKS_RESOURCES_RESPONSE = """<ListStackResourcesResponse>
|
||||
</ResponseMetadata>
|
||||
</ListStackResourcesResponse>"""
|
||||
|
||||
|
||||
GET_TEMPLATE_RESPONSE_TEMPLATE = """<GetTemplateResponse>
|
||||
<GetTemplateResult>
|
||||
<TemplateBody>{{ stack.template }}</TemplateBody>
|
||||
@ -870,7 +902,6 @@ GET_TEMPLATE_RESPONSE_TEMPLATE = """<GetTemplateResponse>
|
||||
</ResponseMetadata>
|
||||
</GetTemplateResponse>"""
|
||||
|
||||
|
||||
DELETE_STACK_RESPONSE_TEMPLATE = """<DeleteStackResponse>
|
||||
<ResponseMetadata>
|
||||
<RequestId>5ccc7dcd-744c-11e5-be70-example</RequestId>
|
||||
@ -878,7 +909,6 @@ DELETE_STACK_RESPONSE_TEMPLATE = """<DeleteStackResponse>
|
||||
</DeleteStackResponse>
|
||||
"""
|
||||
|
||||
|
||||
LIST_EXPORTS_RESPONSE = """<ListExportsResponse xmlns="http://cloudformation.amazonaws.com/doc/2010-05-15/">
|
||||
<ListExportsResult>
|
||||
<Exports>
|
||||
@ -1139,3 +1169,19 @@ LIST_STACK_SET_OPERATION_RESULTS_RESPONSE_TEMPLATE = (
|
||||
</ListStackSetOperationResultsResponse>
|
||||
"""
|
||||
)
|
||||
|
||||
GET_TEMPLATE_SUMMARY_TEMPLATE = """<GetTemplateSummaryResponse xmlns="http://cloudformation.amazonaws.com/doc/2010-05-15/">
|
||||
<GetTemplateSummaryResult>
|
||||
<Description>{{ template_summary.Description }}</Description>
|
||||
{% for resource in template_summary.resourceTypes %}
|
||||
<ResourceTypes>
|
||||
<ResourceType>{{ resource }}</ResourceType>
|
||||
</ResourceTypes>
|
||||
{% endfor %}
|
||||
<Version>{{ template_summary.AWSTemplateFormatVersion }}</Version>
|
||||
</GetTemplateSummaryResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>b9b4b068-3a41-11e5-94eb-example</RequestId>
|
||||
</ResponseMetadata>
|
||||
</GetTemplateSummaryResponse>
|
||||
"""
|
||||
|
@ -35,6 +35,14 @@ dummy_template = {
|
||||
},
|
||||
}
|
||||
|
||||
dummy_template3 = {
|
||||
"AWSTemplateFormatVersion": "2010-09-09",
|
||||
"Description": "Stack 3",
|
||||
"Resources": {
|
||||
"VPC": {"Properties": {"CidrBlock": "192.168.0.0/16"}, "Type": "AWS::EC2::VPC"}
|
||||
},
|
||||
}
|
||||
|
||||
dummy_template_yaml = """---
|
||||
AWSTemplateFormatVersion: 2010-09-09
|
||||
Description: Stack1 with yaml template
|
||||
@ -668,6 +676,48 @@ def test_boto3_create_stack_with_short_form_func_yaml():
|
||||
)
|
||||
|
||||
|
||||
@mock_s3
|
||||
@mock_cloudformation
|
||||
def test_get_template_summary():
|
||||
s3 = boto3.client("s3")
|
||||
s3_conn = boto3.resource("s3", region_name="us-east-1")
|
||||
|
||||
conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
result = conn.get_template_summary(TemplateBody=json.dumps(dummy_template3))
|
||||
|
||||
result["ResourceTypes"].should.equal(["AWS::EC2::VPC"])
|
||||
result["Version"].should.equal("2010-09-09")
|
||||
result["Description"].should.equal("Stack 3")
|
||||
|
||||
conn.create_stack(StackName="test_stack", TemplateBody=json.dumps(dummy_template3))
|
||||
|
||||
result = conn.get_template_summary(StackName="test_stack")
|
||||
|
||||
result["ResourceTypes"].should.equal(["AWS::EC2::VPC"])
|
||||
result["Version"].should.equal("2010-09-09")
|
||||
result["Description"].should.equal("Stack 3")
|
||||
|
||||
s3_conn.create_bucket(Bucket="foobar")
|
||||
s3_conn.Object("foobar", "template-key").put(Body=json.dumps(dummy_template3))
|
||||
|
||||
key_url = s3.generate_presigned_url(
|
||||
ClientMethod="get_object", Params={"Bucket": "foobar", "Key": "template-key"}
|
||||
)
|
||||
|
||||
conn.create_stack(StackName="stack_from_url", TemplateURL=key_url)
|
||||
result = conn.get_template_summary(TemplateURL=key_url)
|
||||
result["ResourceTypes"].should.equal(["AWS::EC2::VPC"])
|
||||
result["Version"].should.equal("2010-09-09")
|
||||
result["Description"].should.equal("Stack 3")
|
||||
|
||||
conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
result = conn.get_template_summary(TemplateBody=dummy_template_yaml)
|
||||
|
||||
result["ResourceTypes"].should.equal(["AWS::EC2::Instance"])
|
||||
result["Version"].should.equal("2010-09-09")
|
||||
result["Description"].should.equal("Stack1 with yaml template")
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
def test_boto3_create_stack_with_ref_yaml():
|
||||
cf_conn = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
Loading…
Reference in New Issue
Block a user