From 186ee6a5a4422934f098794d08d8184771c50f88 Mon Sep 17 00:00:00 2001 From: Steve Pulec Date: Mon, 29 Dec 2014 22:12:23 -0500 Subject: [PATCH] Add cloudformation stack parsing for S3 keys. --- moto/cloudformation/responses.py | 14 ++++++++++++ .../test_cloudformation_stack_crud.py | 22 ++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/moto/cloudformation/responses.py b/moto/cloudformation/responses.py index 2a79c06c..d419e7ad 100644 --- a/moto/cloudformation/responses.py +++ b/moto/cloudformation/responses.py @@ -1,7 +1,10 @@ from __future__ import unicode_literals + import json +import urlparse from moto.core.responses import BaseResponse +from moto.s3 import s3_backend from .models import cloudformation_backends @@ -11,9 +14,20 @@ class CloudFormationResponse(BaseResponse): def cloudformation_backend(self): return cloudformation_backends[self.region] + def _get_stack_from_s3_url(self, template_url): + template_url_parts = urlparse.urlparse(template_url) + bucket_name = template_url_parts.netloc.split(".")[0] + key_name = template_url_parts.path.lstrip("/") + + key = s3_backend.get_key(bucket_name, key_name) + return key.value + def create_stack(self): stack_name = self._get_param('StackName') stack_body = self._get_param('TemplateBody') + template_url = self._get_param('TemplateURL') + if template_url: + stack_body = self._get_stack_from_s3_url(template_url) stack_notification_arns = self._get_multi_param('NotificationARNs.member') stack = self.cloudformation_backend.create_stack( diff --git a/tests/test_cloudformation/test_cloudformation_stack_crud.py b/tests/test_cloudformation/test_cloudformation_stack_crud.py index f9754239..ec521ee1 100644 --- a/tests/test_cloudformation/test_cloudformation_stack_crud.py +++ b/tests/test_cloudformation/test_cloudformation_stack_crud.py @@ -3,13 +3,15 @@ from __future__ import unicode_literals import json import boto +import boto.s3 +import boto.s3.key import boto.cloudformation import sure # noqa # Ensure 'assert_raises' context manager support for Python 2.6 import tests.backport_assert_raises # noqa from nose.tools import assert_raises -from moto import mock_cloudformation +from moto import mock_cloudformation, mock_s3 from moto.cloudformation.exceptions import ValidationError dummy_template = { @@ -66,6 +68,24 @@ def test_create_stack_with_notification_arn(): [n.value for n in stack.notification_arns].should.contain('arn:aws:sns:us-east-1:123456789012:fake-queue') +@mock_cloudformation +@mock_s3 +def test_create_stack_from_s3_url(): + s3_conn = boto.s3.connect_to_region('us-west-1') + bucket = s3_conn.create_bucket("foobar") + key = boto.s3.key.Key(bucket) + key.key = "template-key" + key.set_contents_from_string(dummy_template_json) + key_url = key.generate_url(expires_in=0, query_auth=False) + + conn = boto.cloudformation.connect_to_region('us-west-1') + conn.create_stack('new-stack', template_url=key_url) + + stack = conn.describe_stacks()[0] + stack.stack_name.should.equal('new-stack') + stack.get_template().should.equal(dummy_template) + + @mock_cloudformation def test_describe_stack_by_name(): conn = boto.connect_cloudformation()