def test_noninteractive_changeset_update_with_stack_policy(self): stack_name = "MockStack" self.stubber.add_response("create_change_set", { 'Id': 'CHANGESETID', 'StackId': 'STACKID' }) changes = [] changes.append(generate_change()) self.stubber.add_response( "describe_change_set", generate_change_set_response( status="CREATE_COMPLETE", execution_status="AVAILABLE", changes=changes, )) self.stubber.add_response("set_stack_policy", {}) self.stubber.add_response("execute_change_set", {}) with self.stubber: self.provider.noninteractive_changeset_update( fqn=stack_name, template=Template(url="http://fake.template.url.com/"), old_parameters=[], parameters=[], stack_policy=Template(body="{}"), tags=[], )
def test_update_stack_execute_success_no_stack_policy( self, patched_approval): stack_name = "my-fake-stack" self.stubber.add_response("create_change_set", { 'Id': 'CHANGESETID', 'StackId': 'STACKID' }) changes = [] changes.append(generate_change()) self.stubber.add_response( "describe_change_set", generate_change_set_response( status="CREATE_COMPLETE", execution_status="AVAILABLE", changes=changes, )) self.stubber.add_response("execute_change_set", {}) with self.stubber: self.provider.update_stack( fqn=stack_name, template=Template(url="http://fake.template.url.com/"), old_parameters=[], parameters=[], tags=[]) patched_approval.assert_called_with(full_changeset=changes, params_diff=[], include_verbose=True, fqn=stack_name) self.assertEqual(patched_approval.call_count, 1)
def test_generate_cloudformation_args_with_notification_arns(self): stack_name = "mystack" template_url = "http://fake.s3url.com/blah.json" std_args = { "stack_name": stack_name, "parameters": [], "tags": [], "template": Template(url=template_url), "notification_arns": [ "arn:aws:sns:us-east-1:1234567890:test-cf-deploy-notify-sns-topic-CfDeployNotify" # noqa ] } std_return = { "StackName": stack_name, "Parameters": [], "Tags": [], "Capabilities": DEFAULT_CAPABILITIES, "TemplateURL": template_url, "NotificationARNs": [ "arn:aws:sns:us-east-1:1234567890:test-cf-deploy-notify-sns-topic-CfDeployNotify" # noqa ] } result = generate_cloudformation_args(**std_args) self.assertEqual(result, std_return)
def test_generate_cloudformation_args(self): stack_name = "mystack" template_url = "http://fake.s3url.com/blah.json" template_body = '{"fake_body": "woot"}' std_args = { "stack_name": stack_name, "parameters": [], "tags": [], "template": Template(url=template_url) } std_return = { "StackName": stack_name, "Parameters": [], "Tags": [], "Capabilities": DEFAULT_CAPABILITIES, "TemplateURL": template_url, } result = generate_cloudformation_args(**std_args) self.assertEqual(result, std_return) result = generate_cloudformation_args(service_role="FakeRole", **std_args) service_role_result = copy.deepcopy(std_return) service_role_result["RoleARN"] = "FakeRole" self.assertEqual(result, service_role_result) result = generate_cloudformation_args(change_set_name="MyChanges", **std_args) change_set_result = copy.deepcopy(std_return) change_set_result["ChangeSetName"] = "MyChanges" self.assertEqual(result, change_set_result) # Check stack policy stack_policy = Template(body="{}") result = generate_cloudformation_args(stack_policy=stack_policy, **std_args) stack_policy_result = copy.deepcopy(std_return) stack_policy_result["StackPolicyBody"] = "{}" self.assertEqual(result, stack_policy_result) # If not TemplateURL is provided, use TemplateBody std_args["template"] = Template(body=template_body) template_body_result = copy.deepcopy(std_return) del (template_body_result["TemplateURL"]) template_body_result["TemplateBody"] = template_body result = generate_cloudformation_args(**std_args) self.assertEqual(result, template_body_result)
def test_get_stack_changes_create(self, mock_output_full_cs): stack_name = "MockStack" mock_stack = generate_stack_object(stack_name) self.stubber.add_response( 'describe_stacks', { 'Stacks': [ generate_describe_stacks_stack( stack_name, stack_status='REVIEW_IN_PROGRESS') ] }) self.stubber.add_response("create_change_set", { 'Id': 'CHANGESETID', 'StackId': stack_name }) changes = [] changes.append(generate_change()) self.stubber.add_response( "describe_change_set", generate_change_set_response( status="CREATE_COMPLETE", execution_status="AVAILABLE", changes=changes, )) self.stubber.add_response("delete_change_set", {}) self.stubber.add_response( 'describe_stacks', { 'Stacks': [ generate_describe_stacks_stack( stack_name, stack_status='REVIEW_IN_PROGRESS') ] }) self.stubber.add_response( 'describe_stacks', { 'Stacks': [ generate_describe_stacks_stack( stack_name, stack_status='REVIEW_IN_PROGRESS') ] }) self.stubber.add_response("delete_stack", {}) with self.stubber: self.provider.get_stack_changes( stack=mock_stack, template=Template(url="http://fake.template.url.com/"), parameters=[], tags=[]) mock_output_full_cs.assert_called_with(full_changeset=changes, params_diff=[], fqn=stack_name, answer='y')
def test_get_stack_changes_update(self, mock_output_full_cs): stack_name = "MockStack" mock_stack = generate_stack_object(stack_name) self.stubber.add_response( 'describe_stacks', {'Stacks': [generate_describe_stacks_stack(stack_name)]}) self.stubber.add_response('get_template', generate_get_template('cfn_template.yaml')) self.stubber.add_response("create_change_set", { 'Id': 'CHANGESETID', 'StackId': stack_name }) changes = [] changes.append(generate_change()) self.stubber.add_response( "describe_change_set", generate_change_set_response( status="CREATE_COMPLETE", execution_status="AVAILABLE", changes=changes, )) self.stubber.add_response("delete_change_set", {}) self.stubber.add_response( 'describe_stacks', {'Stacks': [generate_describe_stacks_stack(stack_name)]}) with self.stubber: result = self.provider.get_stack_changes( stack=mock_stack, template=Template(url="http://fake.template.url.com/"), parameters=[], tags=[]) mock_output_full_cs.assert_called_with(full_changeset=changes, params_diff=[], fqn=stack_name, answer='y') expected_outputs = { 'FakeOutput': '<inferred-change: MockStack.FakeOutput={}>'.format( str({"Ref": "FakeResource"})) } self.assertEqual(self.provider.get_outputs(stack_name), expected_outputs) self.assertEqual(result, expected_outputs)
def test_get_stack_changes_interactive(self, mock_output_summary, mock_output_full_cs): stack_name = "MockStack" mock_stack = generate_stack_object(stack_name) self.stubber.add_response( 'describe_stacks', {'Stacks': [generate_describe_stacks_stack(stack_name)]}) self.stubber.add_response('get_template', generate_get_template('cfn_template.yaml')) self.stubber.add_response("create_change_set", { 'Id': 'CHANGESETID', 'StackId': stack_name }) changes = [] changes.append(generate_change()) self.stubber.add_response( "describe_change_set", generate_change_set_response( status="CREATE_COMPLETE", execution_status="AVAILABLE", changes=changes, )) self.stubber.add_response("delete_change_set", {}) self.stubber.add_response( 'describe_stacks', {'Stacks': [generate_describe_stacks_stack(stack_name)]}) with self.stubber: self.provider.get_stack_changes( stack=mock_stack, template=Template(url="http://fake.template.url.com/"), parameters=[], tags=[]) mock_output_summary.assert_called_with(stack_name, 'changes', changes, [], replacements_only=False) mock_output_full_cs.assert_called_with(full_changeset=changes, params_diff=[], fqn=stack_name)
def test_create_change_set_unhandled_failed_status(self): self.stubber.add_response("create_change_set", { 'Id': 'CHANGESETID', 'StackId': 'STACKID' }) self.stubber.add_response( "describe_change_set", generate_change_set_response( "FAILED", status_reason="Some random bad thing.")) with self.stubber: with self.assertRaises(exceptions.UnhandledChangeSetStatus): create_change_set( cfn_client=self.cfn, fqn="my-fake-stack", template=Template(url="http://fake.template.url.com/"), parameters=[], tags=[])
def test_create_change_set_bad_execution_status(self): self.stubber.add_response("create_change_set", { 'Id': 'CHANGESETID', 'StackId': 'STACKID' }) self.stubber.add_response( "describe_change_set", generate_change_set_response( status="CREATE_COMPLETE", execution_status="UNAVAILABLE", )) with self.stubber: with self.assertRaises(exceptions.UnableToExecuteChangeSet): create_change_set( cfn_client=self.cfn, fqn="my-fake-stack", template=Template(url="http://fake.template.url.com/"), parameters=[], tags=[])
def test_create_change_set_stack_did_not_change(self): self.stubber.add_response("create_change_set", { 'Id': 'CHANGESETID', 'StackId': 'STACKID' }) self.stubber.add_response( "describe_change_set", generate_change_set_response( "FAILED", status_reason="Stack didn't contain changes.")) self.stubber.add_response( "delete_change_set", {}, expected_params={"ChangeSetName": "CHANGESETID"}) with self.stubber: with self.assertRaises(exceptions.StackDidNotChange): create_change_set( cfn_client=self.cfn, fqn="my-fake-stack", template=Template(url="http://fake.template.url.com/"), parameters=[], tags=[])