Add CloudFormation methods delete_change_set, describe_change_set and list_change_sets.
This commit is contained in:
parent
850496f29a
commit
337601b5fb
@ -477,12 +477,12 @@
|
|||||||
- [X] create_stack
|
- [X] create_stack
|
||||||
- [ ] create_stack_instances
|
- [ ] create_stack_instances
|
||||||
- [ ] create_stack_set
|
- [ ] create_stack_set
|
||||||
- [ ] delete_change_set
|
- [X] delete_change_set
|
||||||
- [X] delete_stack
|
- [X] delete_stack
|
||||||
- [ ] delete_stack_instances
|
- [ ] delete_stack_instances
|
||||||
- [ ] delete_stack_set
|
- [ ] delete_stack_set
|
||||||
- [ ] describe_account_limits
|
- [ ] describe_account_limits
|
||||||
- [ ] describe_change_set
|
- [X] describe_change_set
|
||||||
- [ ] describe_stack_events
|
- [ ] describe_stack_events
|
||||||
- [ ] describe_stack_instance
|
- [ ] describe_stack_instance
|
||||||
- [ ] describe_stack_resource
|
- [ ] describe_stack_resource
|
||||||
@ -495,7 +495,7 @@
|
|||||||
- [ ] get_stack_policy
|
- [ ] get_stack_policy
|
||||||
- [ ] get_template
|
- [ ] get_template
|
||||||
- [ ] get_template_summary
|
- [ ] get_template_summary
|
||||||
- [ ] list_change_sets
|
- [X] list_change_sets
|
||||||
- [X] list_exports
|
- [X] list_exports
|
||||||
- [ ] list_imports
|
- [ ] list_imports
|
||||||
- [ ] list_stack_instances
|
- [ ] list_stack_instances
|
||||||
|
@ -127,6 +127,49 @@ class FakeStack(BaseModel):
|
|||||||
self.status = "DELETE_COMPLETE"
|
self.status = "DELETE_COMPLETE"
|
||||||
|
|
||||||
|
|
||||||
|
class FakeChange(BaseModel):
|
||||||
|
|
||||||
|
def __init__(self, action, logical_resource_id, resource_type):
|
||||||
|
self.action = action
|
||||||
|
self.logical_resource_id = logical_resource_id
|
||||||
|
self.resource_type = resource_type
|
||||||
|
|
||||||
|
|
||||||
|
class FakeChangeSet(FakeStack):
|
||||||
|
|
||||||
|
def __init__(self, stack_id, stack_name, stack_template, change_set_id, change_set_name, template, parameters, region_name, notification_arns=None, tags=None, role_arn=None, cross_stack_resources=None):
|
||||||
|
super(FakeChangeSet, self).__init__(
|
||||||
|
stack_id,
|
||||||
|
stack_name,
|
||||||
|
stack_template,
|
||||||
|
parameters,
|
||||||
|
region_name,
|
||||||
|
notification_arns=notification_arns,
|
||||||
|
tags=tags,
|
||||||
|
role_arn=role_arn,
|
||||||
|
cross_stack_resources=cross_stack_resources,
|
||||||
|
create_change_set=True,
|
||||||
|
)
|
||||||
|
self.stack_name = stack_name
|
||||||
|
self.change_set_id = change_set_id
|
||||||
|
self.change_set_name = change_set_name
|
||||||
|
self.changes = self.diff(template=template, parameters=parameters)
|
||||||
|
|
||||||
|
def diff(self, template, parameters=None):
|
||||||
|
self.template = template
|
||||||
|
self._parse_template()
|
||||||
|
changes = []
|
||||||
|
resources_by_action = self.resource_map.diff(self.template_dict, parameters)
|
||||||
|
for action, resources in resources_by_action.items():
|
||||||
|
for resource_name, resource in resources.items():
|
||||||
|
changes.append(FakeChange(
|
||||||
|
action=action,
|
||||||
|
logical_resource_id=resource_name,
|
||||||
|
resource_type=resource['ResourceType'],
|
||||||
|
))
|
||||||
|
return changes
|
||||||
|
|
||||||
|
|
||||||
class FakeEvent(BaseModel):
|
class FakeEvent(BaseModel):
|
||||||
|
|
||||||
def __init__(self, stack_id, stack_name, logical_resource_id, physical_resource_id, resource_type, resource_status, resource_status_reason=None, resource_properties=None):
|
def __init__(self, stack_id, stack_name, logical_resource_id, physical_resource_id, resource_type, resource_status, resource_status_reason=None, resource_properties=None):
|
||||||
@ -171,24 +214,62 @@ class CloudFormationBackend(BaseBackend):
|
|||||||
return new_stack
|
return new_stack
|
||||||
|
|
||||||
def create_change_set(self, stack_name, change_set_name, template, parameters, region_name, change_set_type, notification_arns=None, tags=None, role_arn=None):
|
def create_change_set(self, stack_name, change_set_name, template, parameters, region_name, change_set_type, notification_arns=None, tags=None, role_arn=None):
|
||||||
|
stack_id = None
|
||||||
|
stack_template = None
|
||||||
if change_set_type == 'UPDATE':
|
if change_set_type == 'UPDATE':
|
||||||
stacks = self.stacks.values()
|
stacks = self.stacks.values()
|
||||||
stack = None
|
stack = None
|
||||||
for s in stacks:
|
for s in stacks:
|
||||||
if s.name == stack_name:
|
if s.name == stack_name:
|
||||||
stack = s
|
stack = s
|
||||||
|
stack_id = stack.stack_id
|
||||||
|
stack_template = stack.template
|
||||||
if stack is None:
|
if stack is None:
|
||||||
raise ValidationError(stack_name)
|
raise ValidationError(stack_name)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
stack = self.create_stack(stack_name, template, parameters,
|
stack_id = generate_stack_id(stack_name)
|
||||||
region_name, notification_arns, tags,
|
stack_template = template
|
||||||
role_arn, create_change_set=True)
|
|
||||||
change_set_id = generate_changeset_id(change_set_name, region_name)
|
change_set_id = generate_changeset_id(change_set_name, region_name)
|
||||||
self.stacks[change_set_name] = {'Id': change_set_id,
|
new_change_set = FakeChangeSet(
|
||||||
'StackId': stack.stack_id}
|
stack_id=stack_id,
|
||||||
self.change_sets[change_set_id] = stack
|
stack_name=stack_name,
|
||||||
return change_set_id, stack.stack_id
|
stack_template=stack_template,
|
||||||
|
change_set_id=change_set_id,
|
||||||
|
change_set_name=change_set_name,
|
||||||
|
template=template,
|
||||||
|
parameters=parameters,
|
||||||
|
region_name=region_name,
|
||||||
|
notification_arns=notification_arns,
|
||||||
|
tags=tags,
|
||||||
|
role_arn=role_arn,
|
||||||
|
cross_stack_resources=self.exports
|
||||||
|
)
|
||||||
|
self.change_sets[change_set_id] = new_change_set
|
||||||
|
self.stacks[stack_id] = new_change_set
|
||||||
|
return change_set_id, stack_id
|
||||||
|
|
||||||
|
def delete_change_set(self, change_set_name, stack_name=None):
|
||||||
|
if change_set_name in self.change_sets:
|
||||||
|
# This means arn was passed in
|
||||||
|
del self.change_sets[change_set_name]
|
||||||
|
else:
|
||||||
|
for cs in self.change_sets:
|
||||||
|
if self.change_sets[cs].change_set_name == change_set_name:
|
||||||
|
del self.change_sets[cs]
|
||||||
|
|
||||||
|
def describe_change_set(self, change_set_name, stack_name=None):
|
||||||
|
change_set = None
|
||||||
|
if change_set_name in self.change_sets:
|
||||||
|
# This means arn was passed in
|
||||||
|
change_set = self.change_sets[change_set_name]
|
||||||
|
else:
|
||||||
|
for cs in self.change_sets:
|
||||||
|
if self.change_sets[cs].change_set_name == change_set_name:
|
||||||
|
change_set = self.change_sets[cs]
|
||||||
|
if change_set is None:
|
||||||
|
raise ValidationError(change_set_name)
|
||||||
|
return change_set
|
||||||
|
|
||||||
def execute_change_set(self, change_set_name, stack_name=None):
|
def execute_change_set(self, change_set_name, stack_name=None):
|
||||||
stack = None
|
stack = None
|
||||||
@ -197,7 +278,7 @@ class CloudFormationBackend(BaseBackend):
|
|||||||
stack = self.change_sets[change_set_name]
|
stack = self.change_sets[change_set_name]
|
||||||
else:
|
else:
|
||||||
for cs in self.change_sets:
|
for cs in self.change_sets:
|
||||||
if self.change_sets[cs].name == change_set_name:
|
if self.change_sets[cs].change_set_name == change_set_name:
|
||||||
stack = self.change_sets[cs]
|
stack = self.change_sets[cs]
|
||||||
if stack is None:
|
if stack is None:
|
||||||
raise ValidationError(stack_name)
|
raise ValidationError(stack_name)
|
||||||
@ -223,6 +304,9 @@ class CloudFormationBackend(BaseBackend):
|
|||||||
else:
|
else:
|
||||||
return list(stacks)
|
return list(stacks)
|
||||||
|
|
||||||
|
def list_change_sets(self):
|
||||||
|
return self.change_sets.values()
|
||||||
|
|
||||||
def list_stacks(self):
|
def list_stacks(self):
|
||||||
return [
|
return [
|
||||||
v for v in self.stacks.values()
|
v for v in self.stacks.values()
|
||||||
|
@ -465,36 +465,70 @@ class ResourceMap(collections.Mapping):
|
|||||||
ec2_models.ec2_backends[self._region_name].create_tags(
|
ec2_models.ec2_backends[self._region_name].create_tags(
|
||||||
[self[resource].physical_resource_id], self.tags)
|
[self[resource].physical_resource_id], self.tags)
|
||||||
|
|
||||||
def update(self, template, parameters=None):
|
def diff(self, template, parameters=None):
|
||||||
if parameters:
|
if parameters:
|
||||||
self.input_parameters = parameters
|
self.input_parameters = parameters
|
||||||
self.load_mapping()
|
self.load_mapping()
|
||||||
self.load_parameters()
|
self.load_parameters()
|
||||||
self.load_conditions()
|
self.load_conditions()
|
||||||
|
|
||||||
|
old_template = self._resource_json_map
|
||||||
|
new_template = template['Resources']
|
||||||
|
|
||||||
|
resource_names_by_action = {
|
||||||
|
'Add': set(new_template) - set(old_template),
|
||||||
|
'Modify': set(name for name in new_template if name in old_template and new_template[
|
||||||
|
name] != old_template[name]),
|
||||||
|
'Remove': set(old_template) - set(new_template)
|
||||||
|
}
|
||||||
|
resources_by_action = {
|
||||||
|
'Add': {},
|
||||||
|
'Modify': {},
|
||||||
|
'Remove': {},
|
||||||
|
}
|
||||||
|
|
||||||
|
for resource_name in resource_names_by_action['Add']:
|
||||||
|
resources_by_action['Add'][resource_name] = {
|
||||||
|
'LogicalResourceId': resource_name,
|
||||||
|
'ResourceType': new_template[resource_name]['Type']
|
||||||
|
}
|
||||||
|
|
||||||
|
for resource_name in resource_names_by_action['Modify']:
|
||||||
|
resources_by_action['Modify'][resource_name] = {
|
||||||
|
'LogicalResourceId': resource_name,
|
||||||
|
'ResourceType': new_template[resource_name]['Type']
|
||||||
|
}
|
||||||
|
|
||||||
|
for resource_name in resource_names_by_action['Remove']:
|
||||||
|
resources_by_action['Remove'][resource_name] = {
|
||||||
|
'LogicalResourceId': resource_name,
|
||||||
|
'ResourceType': old_template[resource_name]['Type']
|
||||||
|
}
|
||||||
|
|
||||||
|
return resources_by_action
|
||||||
|
|
||||||
|
def update(self, template, parameters=None):
|
||||||
|
resources_by_action = self.diff(template, parameters)
|
||||||
|
|
||||||
old_template = self._resource_json_map
|
old_template = self._resource_json_map
|
||||||
new_template = template['Resources']
|
new_template = template['Resources']
|
||||||
self._resource_json_map = new_template
|
self._resource_json_map = new_template
|
||||||
|
|
||||||
new_resource_names = set(new_template) - set(old_template)
|
for resource_name, resource in resources_by_action['Add'].items():
|
||||||
for resource_name in new_resource_names:
|
|
||||||
resource_json = new_template[resource_name]
|
resource_json = new_template[resource_name]
|
||||||
new_resource = parse_and_create_resource(
|
new_resource = parse_and_create_resource(
|
||||||
resource_name, resource_json, self, self._region_name)
|
resource_name, resource_json, self, self._region_name)
|
||||||
self._parsed_resources[resource_name] = new_resource
|
self._parsed_resources[resource_name] = new_resource
|
||||||
|
|
||||||
removed_resource_names = set(old_template) - set(new_template)
|
for resource_name, resource in resources_by_action['Remove'].items():
|
||||||
for resource_name in removed_resource_names:
|
|
||||||
resource_json = old_template[resource_name]
|
resource_json = old_template[resource_name]
|
||||||
parse_and_delete_resource(
|
parse_and_delete_resource(
|
||||||
resource_name, resource_json, self, self._region_name)
|
resource_name, resource_json, self, self._region_name)
|
||||||
self._parsed_resources.pop(resource_name)
|
self._parsed_resources.pop(resource_name)
|
||||||
|
|
||||||
resources_to_update = set(name for name in new_template if name in old_template and new_template[
|
|
||||||
name] != old_template[name])
|
|
||||||
tries = 1
|
tries = 1
|
||||||
while resources_to_update and tries < 5:
|
while resources_by_action['Modify'] and tries < 5:
|
||||||
for resource_name in resources_to_update.copy():
|
for resource_name, resource in resources_by_action['Modify'].copy().items():
|
||||||
resource_json = new_template[resource_name]
|
resource_json = new_template[resource_name]
|
||||||
try:
|
try:
|
||||||
changed_resource = parse_and_update_resource(
|
changed_resource = parse_and_update_resource(
|
||||||
@ -505,7 +539,7 @@ class ResourceMap(collections.Mapping):
|
|||||||
last_exception = e
|
last_exception = e
|
||||||
else:
|
else:
|
||||||
self._parsed_resources[resource_name] = changed_resource
|
self._parsed_resources[resource_name] = changed_resource
|
||||||
resources_to_update.remove(resource_name)
|
del resources_by_action['Modify'][resource_name]
|
||||||
tries += 1
|
tries += 1
|
||||||
if tries == 5:
|
if tries == 5:
|
||||||
raise last_exception
|
raise last_exception
|
||||||
|
@ -120,6 +120,31 @@ class CloudFormationResponse(BaseResponse):
|
|||||||
template = self.response_template(CREATE_CHANGE_SET_RESPONSE_TEMPLATE)
|
template = self.response_template(CREATE_CHANGE_SET_RESPONSE_TEMPLATE)
|
||||||
return template.render(stack_id=stack_id, change_set_id=change_set_id)
|
return template.render(stack_id=stack_id, change_set_id=change_set_id)
|
||||||
|
|
||||||
|
def delete_change_set(self):
|
||||||
|
stack_name = self._get_param('StackName')
|
||||||
|
change_set_name = self._get_param('ChangeSetName')
|
||||||
|
|
||||||
|
self.cloudformation_backend.delete_change_set(change_set_name=change_set_name, stack_name=stack_name)
|
||||||
|
if self.request_json:
|
||||||
|
return json.dumps({
|
||||||
|
'DeleteChangeSetResponse': {
|
||||||
|
'DeleteChangeSetResult': {},
|
||||||
|
}
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
template = self.response_template(DELETE_CHANGE_SET_RESPONSE_TEMPLATE)
|
||||||
|
return template.render()
|
||||||
|
|
||||||
|
def describe_change_set(self):
|
||||||
|
stack_name = self._get_param('StackName')
|
||||||
|
change_set_name = self._get_param('ChangeSetName')
|
||||||
|
change_set = self.cloudformation_backend.describe_change_set(
|
||||||
|
change_set_name=change_set_name,
|
||||||
|
stack_name=stack_name,
|
||||||
|
)
|
||||||
|
template = self.response_template(DESCRIBE_CHANGE_SET_RESPONSE_TEMPLATE)
|
||||||
|
return template.render(change_set=change_set)
|
||||||
|
|
||||||
@amzn_request_id
|
@amzn_request_id
|
||||||
def execute_change_set(self):
|
def execute_change_set(self):
|
||||||
stack_name = self._get_param('StackName')
|
stack_name = self._get_param('StackName')
|
||||||
@ -187,6 +212,11 @@ class CloudFormationResponse(BaseResponse):
|
|||||||
template = self.response_template(DESCRIBE_STACK_EVENTS_RESPONSE)
|
template = self.response_template(DESCRIBE_STACK_EVENTS_RESPONSE)
|
||||||
return template.render(stack=stack)
|
return template.render(stack=stack)
|
||||||
|
|
||||||
|
def list_change_sets(self):
|
||||||
|
change_sets = self.cloudformation_backend.list_change_sets()
|
||||||
|
template = self.response_template(LIST_CHANGE_SETS_RESPONSE)
|
||||||
|
return template.render(change_sets=change_sets)
|
||||||
|
|
||||||
def list_stacks(self):
|
def list_stacks(self):
|
||||||
stacks = self.cloudformation_backend.list_stacks()
|
stacks = self.cloudformation_backend.list_stacks()
|
||||||
template = self.response_template(LIST_STACKS_RESPONSE)
|
template = self.response_template(LIST_STACKS_RESPONSE)
|
||||||
@ -354,6 +384,66 @@ CREATE_CHANGE_SET_RESPONSE_TEMPLATE = """<CreateStackResponse>
|
|||||||
</CreateStackResponse>
|
</CreateStackResponse>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
DELETE_CHANGE_SET_RESPONSE_TEMPLATE = """<DeleteChangeSetResponse>
|
||||||
|
<DeleteChangeSetResult>
|
||||||
|
</DeleteChangeSetResult>
|
||||||
|
<ResponseMetadata>
|
||||||
|
<RequestId>3d3200a1-810e-3023-6cc3-example</RequestId>
|
||||||
|
</ResponseMetadata>
|
||||||
|
</DeleteChangeSetResponse>
|
||||||
|
"""
|
||||||
|
|
||||||
|
DESCRIBE_CHANGE_SET_RESPONSE_TEMPLATE = """<DescribeChangeSetResponse>
|
||||||
|
<DescribeChangeSetResult>
|
||||||
|
<ChangeSetId>{{ change_set.change_set_id }}</ChangeSetId>
|
||||||
|
<ChangeSetName>{{ change_set.change_set_name }}</ChangeSetName>
|
||||||
|
<StackId>{{ change_set.stack_id }}</StackId>
|
||||||
|
<StackName>{{ change_set.stack_name }}</StackName>
|
||||||
|
<Description>{{ change_set.description }}</Description>
|
||||||
|
<Parameters>
|
||||||
|
{% for param_name, param_value in change_set.stack_parameters.items() %}
|
||||||
|
<member>
|
||||||
|
<ParameterKey>{{ param_name }}</ParameterKey>
|
||||||
|
<ParameterValue>{{ param_value }}</ParameterValue>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Parameters>
|
||||||
|
<CreationTime>2011-05-23T15:47:44Z</CreationTime>
|
||||||
|
<ExecutionStatus>{{ change_set.execution_status }}</ExecutionStatus>
|
||||||
|
<Status>{{ change_set.status }}</Status>
|
||||||
|
<StatusReason>{{ change_set.status_reason }}</StatusReason>
|
||||||
|
{% if change_set.notification_arns %}
|
||||||
|
<NotificationARNs>
|
||||||
|
{% for notification_arn in change_set.notification_arns %}
|
||||||
|
<member>{{ notification_arn }}</member>
|
||||||
|
{% endfor %}
|
||||||
|
</NotificationARNs>
|
||||||
|
{% else %}
|
||||||
|
<NotificationARNs/>
|
||||||
|
{% endif %}
|
||||||
|
{% if change_set.role_arn %}
|
||||||
|
<RoleARN>{{ change_set.role_arn }}</RoleARN>
|
||||||
|
{% endif %}
|
||||||
|
{% if change_set.changes %}
|
||||||
|
<Changes>
|
||||||
|
{% for change in change_set.changes %}
|
||||||
|
<member>
|
||||||
|
<Type>Resource</Type>
|
||||||
|
<ResourceChange>
|
||||||
|
<Action>{{ change.action }}</Action>
|
||||||
|
<LogicalResourceId>{{ change.logical_resource_id }}</LogicalResourceId>
|
||||||
|
<ResourceType>{{ change.resource_type }}</ResourceType>
|
||||||
|
</ResourceChange>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Changes>
|
||||||
|
{% endif %}
|
||||||
|
{% if next_token %}
|
||||||
|
<NextToken>{{ next_token }}</NextToken>
|
||||||
|
{% endif %}
|
||||||
|
</DescribeChangeSetResult>
|
||||||
|
</DescribeChangeSetResponse>"""
|
||||||
|
|
||||||
EXECUTE_CHANGE_SET_RESPONSE_TEMPLATE = """<ExecuteChangeSetResponse>
|
EXECUTE_CHANGE_SET_RESPONSE_TEMPLATE = """<ExecuteChangeSetResponse>
|
||||||
<ExecuteChangeSetResult>
|
<ExecuteChangeSetResult>
|
||||||
<ExecuteChangeSetResult/>
|
<ExecuteChangeSetResult/>
|
||||||
@ -479,6 +569,27 @@ DESCRIBE_STACK_EVENTS_RESPONSE = """<DescribeStackEventsResponse xmlns="http://c
|
|||||||
</DescribeStackEventsResponse>"""
|
</DescribeStackEventsResponse>"""
|
||||||
|
|
||||||
|
|
||||||
|
LIST_CHANGE_SETS_RESPONSE = """<ListChangeSetsResponse>
|
||||||
|
<ListChangeSetsResult>
|
||||||
|
<Summaries>
|
||||||
|
{% for change_set in change_sets %}
|
||||||
|
<member>
|
||||||
|
<StackId>{{ change_set.stack_id }}</StackId>
|
||||||
|
<StackName>{{ change_set.stack_name }}</StackName>
|
||||||
|
<ChangeSetId>{{ change_set.change_set_id }}</ChangeSetId>
|
||||||
|
<ChangeSetName>{{ change_set.change_set_name }}</ChangeSetName>
|
||||||
|
<ExecutionStatus>{{ change_set.execution_status }}</ExecutionStatus>
|
||||||
|
<Status>{{ change_set.status }}</Status>
|
||||||
|
<StatusReason>{{ change_set.status_reason }}</StatusReason>
|
||||||
|
<CreationTime>2011-05-23T15:47:44Z</CreationTime>
|
||||||
|
<Description>{{ change_set.description }}</Description>
|
||||||
|
</member>
|
||||||
|
{% endfor %}
|
||||||
|
</Summaries>
|
||||||
|
</ListChangeSetsResult>
|
||||||
|
</ListChangeSetsResponse>"""
|
||||||
|
|
||||||
|
|
||||||
LIST_STACKS_RESPONSE = """<ListStacksResponse>
|
LIST_STACKS_RESPONSE = """<ListStacksResponse>
|
||||||
<ListStacksResult>
|
<ListStacksResult>
|
||||||
<StackSummaries>
|
<StackSummaries>
|
||||||
|
@ -399,6 +399,32 @@ def test_create_change_set_from_s3_url():
|
|||||||
assert 'arn:aws:cloudformation:us-east-1:123456789:stack/NewStack' in response['StackId']
|
assert 'arn:aws:cloudformation:us-east-1:123456789:stack/NewStack' in response['StackId']
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cloudformation
|
||||||
|
def test_describe_change_set():
|
||||||
|
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
||||||
|
cf_conn.create_change_set(
|
||||||
|
StackName='NewStack',
|
||||||
|
TemplateBody=dummy_template_json,
|
||||||
|
ChangeSetName='NewChangeSet',
|
||||||
|
ChangeSetType='CREATE',
|
||||||
|
)
|
||||||
|
|
||||||
|
stack = cf_conn.describe_change_set(ChangeSetName="NewChangeSet")
|
||||||
|
stack['ChangeSetName'].should.equal('NewChangeSet')
|
||||||
|
stack['StackName'].should.equal('NewStack')
|
||||||
|
|
||||||
|
cf_conn.create_change_set(
|
||||||
|
StackName='NewStack',
|
||||||
|
TemplateBody=dummy_update_template_json,
|
||||||
|
ChangeSetName='NewChangeSet2',
|
||||||
|
ChangeSetType='UPDATE',
|
||||||
|
)
|
||||||
|
stack = cf_conn.describe_change_set(ChangeSetName="NewChangeSet2")
|
||||||
|
stack['ChangeSetName'].should.equal('NewChangeSet2')
|
||||||
|
stack['StackName'].should.equal('NewStack')
|
||||||
|
stack['Changes'].should.have.length_of(2)
|
||||||
|
|
||||||
|
|
||||||
@mock_cloudformation
|
@mock_cloudformation
|
||||||
def test_execute_change_set_w_arn():
|
def test_execute_change_set_w_arn():
|
||||||
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
||||||
@ -420,7 +446,7 @@ def test_execute_change_set_w_name():
|
|||||||
ChangeSetName='NewChangeSet',
|
ChangeSetName='NewChangeSet',
|
||||||
ChangeSetType='CREATE',
|
ChangeSetType='CREATE',
|
||||||
)
|
)
|
||||||
cf_conn.execute_change_set(ChangeSetName='NewStack', StackName='NewStack')
|
cf_conn.execute_change_set(ChangeSetName='NewChangeSet', StackName='NewStack')
|
||||||
|
|
||||||
|
|
||||||
@mock_cloudformation
|
@mock_cloudformation
|
||||||
@ -489,6 +515,20 @@ def test_describe_stack_by_stack_id():
|
|||||||
stack_by_id['StackName'].should.equal("test_stack")
|
stack_by_id['StackName'].should.equal("test_stack")
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cloudformation
|
||||||
|
def test_list_change_sets():
|
||||||
|
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
||||||
|
cf_conn.create_change_set(
|
||||||
|
StackName='NewStack2',
|
||||||
|
TemplateBody=dummy_template_json,
|
||||||
|
ChangeSetName='NewChangeSet2',
|
||||||
|
ChangeSetType='CREATE',
|
||||||
|
)
|
||||||
|
change_set = cf_conn.list_change_sets(StackName='NewStack2')['Summaries'][0]
|
||||||
|
change_set['StackName'].should.equal('NewStack2')
|
||||||
|
change_set['ChangeSetName'].should.equal('NewChangeSet2')
|
||||||
|
|
||||||
|
|
||||||
@mock_cloudformation
|
@mock_cloudformation
|
||||||
def test_list_stacks():
|
def test_list_stacks():
|
||||||
cf = boto3.resource('cloudformation', region_name='us-east-1')
|
cf = boto3.resource('cloudformation', region_name='us-east-1')
|
||||||
@ -521,6 +561,22 @@ def test_delete_stack_from_resource():
|
|||||||
list(cf.stacks.all()).should.have.length_of(0)
|
list(cf.stacks.all()).should.have.length_of(0)
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cloudformation
|
||||||
|
@mock_ec2
|
||||||
|
def test_delete_change_set():
|
||||||
|
cf_conn = boto3.client('cloudformation', region_name='us-east-1')
|
||||||
|
cf_conn.create_change_set(
|
||||||
|
StackName='NewStack',
|
||||||
|
TemplateBody=dummy_template_json,
|
||||||
|
ChangeSetName='NewChangeSet',
|
||||||
|
ChangeSetType='CREATE',
|
||||||
|
)
|
||||||
|
|
||||||
|
cf_conn.list_change_sets(StackName='NewStack')['Summaries'].should.have.length_of(1)
|
||||||
|
cf_conn.delete_change_set(ChangeSetName='NewChangeSet', StackName='NewStack')
|
||||||
|
cf_conn.list_change_sets(StackName='NewStack')['Summaries'].should.have.length_of(0)
|
||||||
|
|
||||||
|
|
||||||
@mock_cloudformation
|
@mock_cloudformation
|
||||||
@mock_ec2
|
@mock_ec2
|
||||||
def test_delete_stack_by_name():
|
def test_delete_stack_by_name():
|
||||||
|
Loading…
Reference in New Issue
Block a user