CF - detect changesets without changes (#5058)
This commit is contained in:
parent
96996b6b46
commit
be52b4d7a2
@ -251,6 +251,17 @@ class FakeStack(BaseModel):
|
||||
self.creation_time = datetime.utcnow()
|
||||
self.status = "CREATE_PENDING"
|
||||
|
||||
def has_template(self, other_template):
|
||||
our_template = (
|
||||
self.template
|
||||
if isinstance(self.template, dict)
|
||||
else json.loads(self.template)
|
||||
)
|
||||
return our_template == json.loads(other_template)
|
||||
|
||||
def has_parameters(self, other_parameters):
|
||||
return self.parameters == other_parameters
|
||||
|
||||
def _create_resource_map(self):
|
||||
resource_map = ResourceMap(
|
||||
self.stack_id,
|
||||
@ -732,8 +743,18 @@ class CloudFormationBackend(BaseBackend):
|
||||
tags=tags,
|
||||
role_arn=role_arn,
|
||||
)
|
||||
new_change_set.status = "CREATE_COMPLETE"
|
||||
new_change_set.execution_status = "AVAILABLE"
|
||||
if (
|
||||
change_set_type == "UPDATE"
|
||||
and stack.has_template(template)
|
||||
and stack.has_parameters(parameters)
|
||||
):
|
||||
# Nothing has changed - mark it as such
|
||||
new_change_set.status = "FAILED"
|
||||
new_change_set.execution_status = "UNAVAILABLE"
|
||||
new_change_set.status_reason = "The submitted information didn't contain changes. Submit different information to create a change set."
|
||||
else:
|
||||
new_change_set.status = "CREATE_COMPLETE"
|
||||
new_change_set.execution_status = "AVAILABLE"
|
||||
self.change_sets[change_set_id] = new_change_set
|
||||
return change_set_id, stack.stack_id
|
||||
|
||||
|
@ -1641,6 +1641,83 @@ def test_delete_change_set():
|
||||
cf_conn.list_change_sets(StackName="NewStack")["Summaries"].should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@mock_ec2
|
||||
def test_create_change_set_twice__no_changes():
|
||||
cf_client = boto3.client("cloudformation", region_name="us-east-1")
|
||||
|
||||
# Execute once
|
||||
change_set_id = cf_client.create_change_set(
|
||||
StackName="NewStack",
|
||||
TemplateBody=dummy_template_json,
|
||||
ChangeSetName="NewChangeSet",
|
||||
ChangeSetType="CREATE",
|
||||
)["Id"]
|
||||
cf_client.execute_change_set(ChangeSetName=change_set_id, DisableRollback=False)
|
||||
|
||||
# Execute twice
|
||||
change_set_id = cf_client.create_change_set(
|
||||
StackName="NewStack",
|
||||
TemplateBody=dummy_template_json,
|
||||
ChangeSetName="NewChangeSet",
|
||||
ChangeSetType="UPDATE",
|
||||
)["Id"]
|
||||
execution = cf_client.describe_change_set(ChangeSetName=change_set_id)
|
||||
|
||||
# Assert
|
||||
execution["ExecutionStatus"].should.equal("UNAVAILABLE")
|
||||
execution["Status"].should.equal("FAILED")
|
||||
execution["StatusReason"].should.equal(
|
||||
"The submitted information didn't contain changes. Submit different information to create a change set."
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@mock_ec2
|
||||
@mock_s3
|
||||
def test_create_change_set_twice__using_s3__no_changes():
|
||||
cf_client = boto3.client("cloudformation", region_name="us-east-1")
|
||||
s3 = boto3.client("s3", region_name="us-east-1")
|
||||
s3_conn = boto3.resource("s3", region_name="us-east-1")
|
||||
s3_conn.create_bucket(Bucket="foobar")
|
||||
|
||||
s3_conn.Object("foobar", "template-key").put(Body=dummy_template_json)
|
||||
key_url_1 = s3.generate_presigned_url(
|
||||
ClientMethod="get_object", Params={"Bucket": "foobar", "Key": "template-key"}
|
||||
)
|
||||
|
||||
s3_conn.Object("foobar", "template-key-unchanged").put(Body=dummy_template_json)
|
||||
key_url_2 = s3.generate_presigned_url(
|
||||
ClientMethod="get_object",
|
||||
Params={"Bucket": "foobar", "Key": "template-key-unchanged"},
|
||||
)
|
||||
|
||||
# Execute once
|
||||
change_set_id = cf_client.create_change_set(
|
||||
StackName="NewStack",
|
||||
TemplateURL=key_url_1,
|
||||
ChangeSetName="NewChangeSet",
|
||||
ChangeSetType="CREATE",
|
||||
)["Id"]
|
||||
cf_client.execute_change_set(ChangeSetName=change_set_id, DisableRollback=False)
|
||||
|
||||
# Execute twice
|
||||
change_set_id = cf_client.create_change_set(
|
||||
StackName="NewStack",
|
||||
TemplateURL=key_url_2,
|
||||
ChangeSetName="NewChangeSet",
|
||||
ChangeSetType="UPDATE",
|
||||
)["Id"]
|
||||
execution = cf_client.describe_change_set(ChangeSetName=change_set_id)
|
||||
|
||||
# Assert
|
||||
execution["ExecutionStatus"].should.equal("UNAVAILABLE")
|
||||
execution["Status"].should.equal("FAILED")
|
||||
execution["StatusReason"].should.equal(
|
||||
"The submitted information didn't contain changes. Submit different information to create a change set."
|
||||
)
|
||||
|
||||
|
||||
@mock_cloudformation
|
||||
@mock_ec2
|
||||
def test_delete_stack_by_name():
|
||||
|
Loading…
Reference in New Issue
Block a user