def test_handle_adds_cloud_formation_action_to_stage(self): action = cloud_formation_action.CloudFormationAction( action_name="CloudFormation", input_artifact_names=["InfraInput"], input_template_path="InfraInput::template.json", input_template_configuration="InfraInput::myenv.json", stage_name_to_add=self.deploy_stage_name, stack_name="my-microservice", action_mode=action_mode.ActionMode.REPLACE_ON_FAILURE, # cfn_action_config_role_arn=troposphere.NoValue, # cfn_action_role_arn=troposphere.NoValue ) action.handle(self.context) deploy_stage = TemplateQuery.get_resource_by_type( self.context.template, codepipeline.Stages)[0] self.assertEqual(len(deploy_stage.Actions), 1) test_action = deploy_stage.Actions[0] self.assertEqual(test_action.Name, "CloudFormation") self.assertEqual(test_action.ActionTypeId.Category, "Deploy") self.assertEqual(test_action.ActionTypeId.Provider, "CloudFormation") self.assertEqual(test_action.Configuration['TemplatePath'], "InfraInput::template.json") self.assertEqual(test_action.Configuration['TemplateConfiguration'], "InfraInput::myenv.json") self.assertEqual(test_action.Configuration['ActionMode'], action_mode.ActionMode.REPLACE_ON_FAILURE.value) self.assertEquals(len(test_action.InputArtifacts), 1) self.assertEquals(test_action.InputArtifacts[0].Name, "InfraInput") # By default no output artifact is created self.assertFalse(hasattr(test_action, 'OutputArtifacts')) self.assertFalse('OutputFileName' in test_action.Configuration)
def handle(self, chain_context): print("Adding source action %s." % self.action_name) template = chain_context.template policy_name = "CodeBuildPolicy%s" % chain_context.instance_name codebuild_policy = cumulus.policies.codebuild.get_policy_code_build_general_access( policy_name) role_name = "PipelineSourceRole%s" % self.action_name codebuild_role = iam.Role( role_name, Path="/", AssumeRolePolicyDocument=awacs.aws.Policy(Statement=[ awacs.aws.Statement(Effect=awacs.aws.Allow, Action=[awacs.sts.AssumeRole], Principal=awacs.aws.Principal( 'Service', "codebuild.amazonaws.com")) ]), Policies=[codebuild_policy], ManagedPolicyArns=[ chain_context.metadata[META_PIPELINE_BUCKET_POLICY_REF] ]) source_action = SourceCodeCommitAction( Name=self.action_name, OutputArtifacts=[ codepipeline.OutputArtifacts(Name=self.output_artifact_name) ], # TODO: when parameters are figured out, inject tehm into the template here. Configuration={ "RepositoryName": Ref("RepositoryName"), "BranchName": Ref("RepositoryBranch"), }, ) template.add_resource(codebuild_role) found_pipelines = TemplateQuery.get_resource_by_type( template=chain_context.template, type_to_find=codepipeline.Pipeline) pipeline = found_pipelines[0] # Alternate way to get this # dummy = TemplateQuery.get_resource_by_title(chain_context.template, 'AppPipeline') stages = pipeline.Stages # type: list # TODO: find stage by name first_stage = stages[0] # TODO accept a parallel action to the previous action, and don't +1 here. first_stage.Actions.append(source_action) template.add_output( troposphere.Output("RepoName%s" % self.action_name, Value=Ref("RepositoryName"))) template.add_output( troposphere.Output("RepoBranch%s" % self.action_name, Value=Ref("RepositoryBranch")))
def test_can_add_multiple_input_artifacts(self): action = cloud_formation_action.CloudFormationAction( action_name="CloudFormation", input_artifact_names=["InfraInput", "ParameterInput"], input_template_path="InfraInput::template.json", input_template_configuration="ParameterInput::myenv.json", stage_name_to_add=self.deploy_stage_name, stack_name="my-microservice", action_mode=action_mode.ActionMode.REPLACE_ON_FAILURE) action.handle(self.context) deploy_stage = TemplateQuery.get_resource_by_type( self.context.template, codepipeline.Stages)[0] self.assertEqual(len(deploy_stage.Actions), 1) test_action = deploy_stage.Actions[0] self.assertEqual(test_action.Name, "CloudFormation") self.assertEqual(test_action.Configuration['TemplatePath'], "InfraInput::template.json") self.assertEqual(test_action.Configuration['TemplateConfiguration'], "ParameterInput::myenv.json") self.assertEquals(len(test_action.InputArtifacts), 2) self.assertEquals(test_action.InputArtifacts[0].Name, "InfraInput") self.assertEquals(test_action.InputArtifacts[1].Name, "ParameterInput")
def test_uses_default_config_role_arn_to_cfn_action_configuration(self): unexpected_arn = 'im_another_arn' action = cloud_formation_action.CloudFormationAction( action_name="CloudFormation", input_artifact_names=["InfraInput"], input_template_path="InfraInput::template.json", input_template_configuration="InfraInput::myenv.json", output_artifact_name="AllOfTheThings", stage_name_to_add=self.deploy_stage_name, stack_name="my-microservice", action_mode=action_mode.ActionMode.REPLACE_ON_FAILURE, ) action.handle(self.context) deploy_stage = TemplateQuery.get_resource_by_type( self.context.template, codepipeline.Stages)[0] self.assertEqual(len(deploy_stage.Actions), 1) test_action = deploy_stage.Actions[0] self.assertTrue("RoleArn" in test_action.Configuration) self.assertNotEqual(test_action.Configuration['RoleArn'], unexpected_arn) self.assertFalse(hasattr(test_action, 'RoleArn')) self.assertTrue(test_action.Configuration['RoleArn'].__class__ is troposphere.GetAtt)
def test_should_not_find_resource_by_type(self): t = troposphere.Template() t.add_resource(troposphere.s3.Bucket("thebucket")) results = TemplateQuery.get_resource_by_type(t, troposphere.s3.Policy) self.assertTrue(results.count(results) == 0)
def test_pipeline_has_two_stages(self): sut = pipeline.Pipeline(name='test', bucket_name='testbucket') sut.handle(self.context) t = self.context.template pipelines = TemplateQuery.get_resource_by_type(t, codepipeline.Pipeline) self.assertTrue(len(pipelines), 1)
def test_pipeline_uses_non_default_bucket(self): sut = pipeline.Pipeline( name='test', bucket_name='ahhjustbucket', create_bucket=False, ) sut.handle(self.context) t = self.context.template the_bucket = TemplateQuery.get_resource_by_type(t, s3.Bucket) self.assertEqual(len(the_bucket), 0)
def test_pipeline_creates_default_bucket(self): sut = pipeline.Pipeline( name='test', bucket_name='testbucket', ) sut.handle(self.context) t = self.context.template the_bucket = TemplateQuery.get_resource_by_type(t, s3.Bucket) self.assertTrue(len(the_bucket), 1)
def test_should_find_resource_by_type(self): t = troposphere.Template() t.add_resource(troposphere.s3.Bucket("whoCares")) found = TemplateQuery.get_resource_by_type( template=t, type_to_find=troposphere.s3.Bucket) self.assertIsNotNone(found) self.assertIsInstance(found, list) self.assertIsInstance(found[0], troposphere.s3.Bucket)
def test_should_find_resource_by_title(self): t = troposphere.Template() resource_name_to_lookup = "TestingTheNameLookup" t.add_resource(troposphere.s3.Bucket(resource_name_to_lookup)) resource = TemplateQuery.get_resource_by_title( template=t, title=resource_name_to_lookup) self.assertIsNotNone(resource) self.assertIsInstance(resource, troposphere.s3.Bucket) self.assertEqual(resource.title, resource_name_to_lookup)
def handle(self, chain_context): template = chain_context.template template.add_resource(self.role) try: instanceProfile = TemplateQuery.get_resource_by_title( template, self.instance_profile_name) instanceProfile.properties['Roles'].append(Ref(self.role)) except ValueError: print('Adding new Instance Profile') template.add_resource( InstanceProfile(self.instance_profile_name, Roles=[Ref(self.role)]))
def handle(self, chain_context): pipeline_stage = codepipeline.Stages( Name=self.stage_name, Actions=[ # These will have to be filled out by a subsequent action step. ] ) found_pipeline = TemplateQuery.get_resource_by_type( template=chain_context.template, type_to_find=codepipeline.Pipeline)[0] stages = found_pipeline.properties['Stages'] # type: list stages.append(pipeline_stage) print("Added stage '%s' to pipeline %s" % (self.stage_name, stages.count(stages)))
def test_does_not_set_role_arn_to_cfn_action(self): action = cloud_formation_action.CloudFormationAction( action_name="CloudFormation", input_artifact_names=["InfraInput"], input_template_path="InfraInput::template.json", input_template_configuration="InfraInput::myenv.json", output_artifact_name="AllOfTheThings", stage_name_to_add=self.deploy_stage_name, stack_name="my-microservice", action_mode=action_mode.ActionMode.REPLACE_ON_FAILURE, ) action.handle(self.context) deploy_stage = TemplateQuery.get_resource_by_type( self.context.template, codepipeline.Stages)[0] self.assertEqual(len(deploy_stage.Actions), 1) test_action = deploy_stage.Actions[0] self.assertFalse(hasattr(test_action, 'RoleArn'))
def test_can_create_output_artifact(self): action = cloud_formation_action.CloudFormationAction( action_name="CloudFormation", input_artifact_names=["InfraInput"], input_template_path="InfraInput::template.json", input_template_configuration="InfraInput::myenv.json", output_artifact_name="AllOfTheThings", stage_name_to_add=self.deploy_stage_name, stack_name="my-microservice", action_mode=action_mode.ActionMode.REPLACE_ON_FAILURE) action.handle(self.context) deploy_stage = TemplateQuery.get_resource_by_type( self.context.template, codepipeline.Stages)[0] self.assertEqual(len(deploy_stage.Actions), 1) test_action = deploy_stage.Actions[0] self.assertEquals(len(test_action.OutputArtifacts), 1) self.assertEquals(test_action.OutputArtifacts[0].Name, "AllOfTheThings") self.assertEquals(test_action.Configuration['OutputFileName'], "StackOutputs.json")
def handle(self, chain_context): print("Adding source action %s." % self.action_name) template = chain_context.template policy_name = "CodeBuildPolicy%s" % chain_context.instance_name codebuild_policy = cumulus.policies.codebuild.get_policy_code_build_general_access( policy_name) role_name = "PipelineSourceRole%s" % self.action_name codebuild_role = iam.Role( role_name, Path="/", AssumeRolePolicyDocument=awacs.aws.Policy(Statement=[ awacs.aws.Statement(Effect=awacs.aws.Allow, Action=[awacs.sts.AssumeRole], Principal=awacs.aws.Principal( 'Service', "codebuild.amazonaws.com")) ]), Policies=[codebuild_policy], ManagedPolicyArns=[ chain_context.metadata[META_PIPELINE_BUCKET_POLICY_REF] ]) source_action = SourceS3Action( Name=self.action_name, OutputArtifacts=[ codepipeline.OutputArtifacts(Name=self.output_artifact_name) ], Configuration={ "S3Bucket": self.s3_bucket_name, "S3ObjectKey": self.s3_object_key, }, ) # TODO: support CFN params here. Use conditionals. Set to NoValue instead of None, using the same logic as below if self.poll_for_source_changes is not None: # if it's none - we shouldn't touch this. source_action.Configuration[ 'PollForSourceChanges'] = self.poll_for_source_changes template.add_resource(codebuild_role) found_pipelines = TemplateQuery.get_resource_by_type( template=chain_context.template, type_to_find=codepipeline.Pipeline) pipeline = found_pipelines[0] # Alternate way to get this # dummy = TemplateQuery.get_resource_by_title(chain_context.template, 'AppPipeline') stages = pipeline.Stages # type: list # TODO: find stage by name first_stage = stages[0] # TODO accept a parallel action to the previous action, and don't +1 here. first_stage.Actions.append(source_action) template.add_output( troposphere.Output( "PipelineBucket%s" % self.action_name, Value=self.s3_bucket_name, Description="A pipeline source bucket", )) template.add_output( troposphere.Output( "PipelineTriggerObject%s" % self.action_name, Value=self.s3_object_key, Description="An s3 object key in the pipeline bucket " "that will trigger the pipeline", ))
def handle(self, chain_context): launchConfig = TemplateQuery.get_resource_by_type( template=chain_context.template, type_to_find=autoscaling.LaunchConfiguration)[0] launchConfig.properties['BlockDeviceMappings'] = [self.volume]