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)
Example #5
0
    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)
Example #6
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)
Example #7
0
    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)
Example #8
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)
Example #9
0
    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)
Example #10
0
    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)]))
Example #12
0
    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",
            ))
Example #16
0
 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]