Merge pull request #872 from 2rs2ts/allow-updating-cf-tags
Allow CloudFormation stack tags to be updated
This commit is contained in:
commit
f9b7a0a539
@ -82,7 +82,7 @@ class FakeStack(BaseModel):
|
|||||||
def stack_outputs(self):
|
def stack_outputs(self):
|
||||||
return self.output_map.values()
|
return self.output_map.values()
|
||||||
|
|
||||||
def update(self, template, role_arn=None, parameters=None):
|
def update(self, template, role_arn=None, parameters=None, tags=None):
|
||||||
self._add_stack_event("UPDATE_IN_PROGRESS", resource_status_reason="User Initiated")
|
self._add_stack_event("UPDATE_IN_PROGRESS", resource_status_reason="User Initiated")
|
||||||
self.template = template
|
self.template = template
|
||||||
self.resource_map.update(json.loads(template), parameters)
|
self.resource_map.update(json.loads(template), parameters)
|
||||||
@ -90,6 +90,10 @@ class FakeStack(BaseModel):
|
|||||||
self._add_stack_event("UPDATE_COMPLETE")
|
self._add_stack_event("UPDATE_COMPLETE")
|
||||||
self.status = "UPDATE_COMPLETE"
|
self.status = "UPDATE_COMPLETE"
|
||||||
self.role_arn = role_arn
|
self.role_arn = role_arn
|
||||||
|
# only overwrite tags if passed
|
||||||
|
if tags is not None:
|
||||||
|
self.tags = tags
|
||||||
|
# TODO: update tags in the resource map
|
||||||
|
|
||||||
def delete(self):
|
def delete(self):
|
||||||
self._add_stack_event("DELETE_IN_PROGRESS",
|
self._add_stack_event("DELETE_IN_PROGRESS",
|
||||||
@ -164,9 +168,9 @@ class CloudFormationBackend(BaseBackend):
|
|||||||
if stack.name == name_or_stack_id:
|
if stack.name == name_or_stack_id:
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
def update_stack(self, name, template, role_arn=None, parameters=None):
|
def update_stack(self, name, template, role_arn=None, parameters=None, tags=None):
|
||||||
stack = self.get_stack(name)
|
stack = self.get_stack(name)
|
||||||
stack.update(template, role_arn, parameters=parameters)
|
stack.update(template, role_arn, parameters=parameters, tags=tags)
|
||||||
return stack
|
return stack
|
||||||
|
|
||||||
def list_stack_resources(self, stack_name_or_id):
|
def list_stack_resources(self, stack_name_or_id):
|
||||||
|
@ -152,6 +152,14 @@ class CloudFormationResponse(BaseResponse):
|
|||||||
for parameter
|
for parameter
|
||||||
in self._get_list_prefix("Parameters.member")
|
in self._get_list_prefix("Parameters.member")
|
||||||
])
|
])
|
||||||
|
# boto3 is supposed to let you clear the tags by passing an empty value, but the request body doesn't
|
||||||
|
# end up containing anything we can use to differentiate between passing an empty value versus not
|
||||||
|
# passing anything. so until that changes, moto won't be able to clear tags, only update them.
|
||||||
|
tags = dict((item['key'], item['value'])
|
||||||
|
for item in self._get_list_prefix("Tags.member"))
|
||||||
|
# so that if we don't pass the parameter, we don't clear all the tags accidentally
|
||||||
|
if not tags:
|
||||||
|
tags = None
|
||||||
|
|
||||||
stack = self.cloudformation_backend.get_stack(stack_name)
|
stack = self.cloudformation_backend.get_stack(stack_name)
|
||||||
if stack.status == 'ROLLBACK_COMPLETE':
|
if stack.status == 'ROLLBACK_COMPLETE':
|
||||||
@ -162,7 +170,8 @@ class CloudFormationResponse(BaseResponse):
|
|||||||
name=stack_name,
|
name=stack_name,
|
||||||
template=stack_body,
|
template=stack_body,
|
||||||
role_arn=role_arn,
|
role_arn=role_arn,
|
||||||
parameters=parameters
|
parameters=parameters,
|
||||||
|
tags=tags,
|
||||||
)
|
)
|
||||||
if self.request_json:
|
if self.request_json:
|
||||||
stack_body = {
|
stack_body = {
|
||||||
|
@ -424,7 +424,7 @@ def test_update_stack():
|
|||||||
|
|
||||||
|
|
||||||
@mock_cloudformation_deprecated
|
@mock_cloudformation_deprecated
|
||||||
def test_update_stack():
|
def test_update_stack_with_previous_template():
|
||||||
conn = boto.connect_cloudformation()
|
conn = boto.connect_cloudformation()
|
||||||
conn.create_stack(
|
conn.create_stack(
|
||||||
"test_stack",
|
"test_stack",
|
||||||
@ -482,6 +482,26 @@ def test_update_stack_with_parameters():
|
|||||||
assert stack.parameters[0].value == "192.168.0.1/16"
|
assert stack.parameters[0].value == "192.168.0.1/16"
|
||||||
|
|
||||||
|
|
||||||
|
@mock_cloudformation_deprecated
|
||||||
|
def test_update_stack_replace_tags():
|
||||||
|
conn = boto.connect_cloudformation()
|
||||||
|
conn.create_stack(
|
||||||
|
"test_stack",
|
||||||
|
template_body=dummy_template_json,
|
||||||
|
tags={"foo": "bar"},
|
||||||
|
)
|
||||||
|
conn.update_stack(
|
||||||
|
"test_stack",
|
||||||
|
template_body=dummy_template_json,
|
||||||
|
tags={"foo": "baz"},
|
||||||
|
)
|
||||||
|
|
||||||
|
stack = conn.describe_stacks()[0]
|
||||||
|
stack.stack_status.should.equal("UPDATE_COMPLETE")
|
||||||
|
# since there is one tag it doesn't come out as a list
|
||||||
|
dict(stack.tags).should.equal({"foo": "baz"})
|
||||||
|
|
||||||
|
|
||||||
@mock_cloudformation_deprecated
|
@mock_cloudformation_deprecated
|
||||||
def test_update_stack_when_rolled_back():
|
def test_update_stack_when_rolled_back():
|
||||||
conn = boto.connect_cloudformation()
|
conn = boto.connect_cloudformation()
|
||||||
|
@ -258,12 +258,15 @@ def test_describe_updated_stack():
|
|||||||
cf_conn.create_stack(
|
cf_conn.create_stack(
|
||||||
StackName="test_stack",
|
StackName="test_stack",
|
||||||
TemplateBody=dummy_template_json,
|
TemplateBody=dummy_template_json,
|
||||||
|
Tags=[{'Key': 'foo', 'Value': 'bar'}],
|
||||||
)
|
)
|
||||||
|
|
||||||
cf_conn.update_stack(
|
cf_conn.update_stack(
|
||||||
StackName="test_stack",
|
StackName="test_stack",
|
||||||
RoleARN='arn:aws:iam::123456789012:role/moto',
|
RoleARN='arn:aws:iam::123456789012:role/moto',
|
||||||
TemplateBody=dummy_update_template_json)
|
TemplateBody=dummy_update_template_json,
|
||||||
|
Tags=[{'Key': 'foo', 'Value': 'baz'}],
|
||||||
|
)
|
||||||
|
|
||||||
stack = cf_conn.describe_stacks(StackName="test_stack")['Stacks'][0]
|
stack = cf_conn.describe_stacks(StackName="test_stack")['Stacks'][0]
|
||||||
stack_id = stack['StackId']
|
stack_id = stack['StackId']
|
||||||
@ -272,6 +275,7 @@ def test_describe_updated_stack():
|
|||||||
stack_by_id['StackName'].should.equal("test_stack")
|
stack_by_id['StackName'].should.equal("test_stack")
|
||||||
stack_by_id['StackStatus'].should.equal("UPDATE_COMPLETE")
|
stack_by_id['StackStatus'].should.equal("UPDATE_COMPLETE")
|
||||||
stack_by_id['RoleARN'].should.equal('arn:aws:iam::123456789012:role/moto')
|
stack_by_id['RoleARN'].should.equal('arn:aws:iam::123456789012:role/moto')
|
||||||
|
stack_by_id['Tags'].should.equal([{'Key': 'foo', 'Value': 'baz'}])
|
||||||
|
|
||||||
|
|
||||||
@mock_cloudformation
|
@mock_cloudformation
|
||||||
|
Loading…
Reference in New Issue
Block a user