Merge in master.

This commit is contained in:
Steve Pulec 2017-03-05 09:58:39 -05:00
commit 3b4ef2cf15
26 changed files with 565 additions and 65 deletions

View file

@ -1,6 +1,7 @@
from __future__ import unicode_literals
from datetime import datetime
import json
import uuid
import boto.cloudformation
from moto.core import BaseBackend
@ -81,11 +82,10 @@ class FakeStack(object):
def stack_outputs(self):
return self.output_map.values()
def update(self, template, role_arn=None):
self._add_stack_event("UPDATE_IN_PROGRESS",
resource_status_reason="User Initiated")
def update(self, template, role_arn=None, parameters=None):
self._add_stack_event("UPDATE_IN_PROGRESS", resource_status_reason="User Initiated")
self.template = template
self.resource_map.update(json.loads(template))
self.resource_map.update(json.loads(template), parameters)
self.output_map = self._create_output_map()
self._add_stack_event("UPDATE_COMPLETE")
self.status = "UPDATE_COMPLETE"
@ -111,6 +111,7 @@ class FakeEvent(object):
self.resource_status_reason = resource_status_reason
self.resource_properties = resource_properties
self.timestamp = datetime.utcnow()
self.event_id = uuid.uuid4()
class CloudFormationBackend(BaseBackend):
@ -163,9 +164,9 @@ class CloudFormationBackend(BaseBackend):
if stack.name == name_or_stack_id:
return stack
def update_stack(self, name, template, role_arn=None):
def update_stack(self, name, template, role_arn=None, parameters=None):
stack = self.get_stack(name)
stack.update(template, role_arn)
stack.update(template, role_arn, parameters=parameters)
return stack
def list_stack_resources(self, stack_name_or_id):

View file

@ -143,7 +143,7 @@ def clean_json(resource_json, resources_map):
if 'Fn::If' in resource_json:
condition_name, true_value, false_value = resource_json['Fn::If']
if resources_map[condition_name]:
if resources_map.lazy_condition_map[condition_name]:
return clean_json(true_value, resources_map)
else:
return clean_json(false_value, resources_map)
@ -207,7 +207,7 @@ def parse_resource(logical_id, resource_json, resources_map):
def parse_and_create_resource(logical_id, resource_json, resources_map, region_name):
condition = resource_json.get('Condition')
if condition and not resources_map[condition]:
if condition and not resources_map.lazy_condition_map[condition]:
# If this has a False condition, don't create the resource
return None
@ -359,14 +359,13 @@ class ResourceMap(collections.Mapping):
def load_conditions(self):
conditions = self._template.get('Conditions', {})
lazy_condition_map = LazyDict()
self.lazy_condition_map = LazyDict()
for condition_name, condition in conditions.items():
lazy_condition_map[condition_name] = functools.partial(parse_condition,
condition, self._parsed_resources, lazy_condition_map)
self.lazy_condition_map[condition_name] = functools.partial(parse_condition,
condition, self._parsed_resources, self.lazy_condition_map)
for condition_name in lazy_condition_map:
self._parsed_resources[
condition_name] = lazy_condition_map[condition_name]
for condition_name in self.lazy_condition_map:
_ = self.lazy_condition_map[condition_name]
def create(self):
self.load_mapping()
@ -383,7 +382,9 @@ class ResourceMap(collections.Mapping):
ec2_models.ec2_backends[self._region_name].create_tags(
[self[resource].physical_resource_id], self.tags)
def update(self, template):
def update(self, template, parameters=None):
if parameters:
self.input_parameters = parameters
self.load_mapping()
self.load_parameters()
self.load_conditions()

View file

@ -147,6 +147,11 @@ class CloudFormationResponse(BaseResponse):
stack_name).template
else:
stack_body = self._get_param('TemplateBody')
parameters = dict([
(parameter['parameter_key'], parameter['parameter_value'])
for parameter
in self._get_list_prefix("Parameters.member")
])
stack = self.cloudformation_backend.get_stack(stack_name)
if stack.status == 'ROLLBACK_COMPLETE':
@ -157,6 +162,7 @@ class CloudFormationResponse(BaseResponse):
name=stack_name,
template=stack_body,
role_arn=role_arn,
parameters=parameters
)
if self.request_json:
stack_body = {
@ -296,7 +302,7 @@ DESCRIBE_STACK_RESOURCES_RESPONSE = """<DescribeStackResourcesResponse>
DESCRIBE_STACK_EVENTS_RESPONSE = """<DescribeStackEventsResponse xmlns="http://cloudformation.amazonaws.com/doc/2010-05-15/">
<DescribeStackEventsResult>
<StackEvents>
{% for event in stack.events %}
{% for event in stack.events[::-1] %}
<member>
<Timestamp>{{ event.timestamp.strftime('%Y-%m-%dT%H:%M:%S.%fZ') }}</Timestamp>
<ResourceStatus>{{ event.resource_status }}</ResourceStatus>