Ejemplo n.º 1
0
def load_app_in_account_region(
    parent,
    account,
    region,
    app_name,
    app_config,
    project=None,
    monitor_config=None,
    read_file_path='not set',
):
    """
    Load an Application from config into an AccountContainer and RegionContainer.
    Account can be a paco.ref but then the Paco Project must be supplied too.
    """
    account_name = account
    if is_ref(account):
        account_name = get_model_obj_from_ref(account, project).name
    if account_name not in parent:
        account_cont = AccountContainer(account_name, parent)
        parent[account_name] = account_cont
    if region not in parent[account_name]:
        region_cont = RegionContainer(region, parent[account_name])
        parent[account_name][region] = region_cont
    app = Application(app_name, parent[account_name][region])
    parent[account_name][region][app_name] = app
    if project == None:
        project = get_parent_by_interface(parent)
    apply_attributes_from_config(
        app,
        app_config,
        lookup_config=monitor_config,
        read_file_path=read_file_path,
        resource_registry=project.resource_registry,
    )
    return app
Ejemplo n.º 2
0
    def add_apigateway_resource(self, resource):
        resource_logical_id = 'ApiGatewayResource' + self.create_cfn_logical_id(resource.name + md5sum(str_data=resource.paco_ref_parts))
        cfn_export_dict = resource.cfn_export_dict
        parent_resource = resource.__parent__.__parent__
        # root resource
        if schemas.IApiGatewayRestApi.providedBy(parent_resource):
            cfn_export_dict["ParentId"] = troposphere.GetAtt(self.restapi_resource, "RootResourceId")
        # child resource
        else:
            cfn_export_dict["ParentId"] = troposphere.Ref(parent_resource.resource)
        cfn_export_dict["RestApiId"] = troposphere.Ref(self.restapi_resource)
        resource_resource = troposphere.apigateway.Resource.from_dict(resource_logical_id, cfn_export_dict)
        resource.resource = resource_resource
        self.template.add_resource(resource_resource)
        self.create_output(
            title=self.create_cfn_logical_id(f'ApiGatewayRestApiResource{resource.name}' + md5sum(str_data=resource.paco_ref_parts)),
            value=troposphere.Ref(resource_resource),
            ref=resource.paco_ref_parts + '.id',
        )
        # Add an OPTIONS method if CORS is enabled
        if resource.enable_cors == True:
            options_config = {
                'http_method': 'OPTIONS',
                'integration': {
                    'integration_type': 'MOCK',
                    'integration_http_method': 'OPTIONS',
                    'pass_through_behavior': 'WHEN_NO_MATCH',
                    'request_templates': {'application/json': '{"statusCode": 200}'},
                    'integration_responses': [{
                        'status_code': '200',
                        'response_parameters': {
                            'method.response.header.Access-Control-Allow-Headers': "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'",
                            'method.response.header.Access-Control-Allow-Methods': "'POST,OPTIONS'",
                            'method.response.header.Access-Control-Allow-Origin': "'*'",
                        },
                        'response_templates': {'application/json': ''},
                    },],
                },
                'method_responses': [{
                    'status_code': '200',
                    'response_models': [{
                        'content_type': 'application/json',
                        'model_name': 'emptyjson',
                    }],
                    'response_parameters': {
                        'method.response.header.Access-Control-Allow-Headers': False,
                        'method.response.header.Access-Control-Allow-Methods': False,
                        'method.response.header.Access-Control-Allow-Origin': False,
                    },
                }],
            }
            options_config['resource_name'] = resource.nested_name
            method_name = f'{resource.nested_name}PacoCORS'
            options_method = ApiGatewayMethod(method_name, self.apigatewayrestapi.methods)
            apply_attributes_from_config(options_method, options_config)
            self.apigatewayrestapi.methods[method_name] = options_method

        return resource_resource
Ejemplo n.º 3
0
    def __init__(self, name, parent, config_dict):
        super().__init__(name, parent)

        self.zones_by_account = {}
        if config_dict == None:
            return
        loader.apply_attributes_from_config(self, config_dict)

        for zone_id in self.hosted_zones.keys():
            hosted_zone = self.hosted_zones[zone_id]
            aws_account_ref = hosted_zone.account
            ref = Reference(aws_account_ref)
            account_name = ref.parts[1]
            if account_name not in self.zones_by_account:
                self.zones_by_account[account_name] = []
            self.zones_by_account[account_name].append(zone_id)
Ejemplo n.º 4
0
 def create_config_bucket(self, account_ctx, accounts):
     "Create an S3 Bucket for AWS Config"
     s3_ctl = self.paco_ctx.get_controller('S3')
     global_buckets = self.paco_ctx.project['resource']['s3'].buckets
     bucket_config_dict = {
         'region':
         self.config.global_resources_region,
         'account':
         self.config.s3_bucket_logs_account,
         'bucket_name':
         'config',
         'enabled':
         True,
         'deletion_policy':
         'delete',
         'policy': [{
             'sid': "AWSConfigBucketPermissionsCheck",
             'effect': "Allow",
             'action': ["s3:GetBucketAcl"],
             'principal': {
                 "Service": "config.amazonaws.com"
             },
         }, {
             'sid': "AWSConfigBucketExistenceCheck",
             'effect': "Allow",
             'action': ["s3:ListBucket"],
             'principal': {
                 "Service": "config.amazonaws.com"
             },
         }, {
             'sid':
             "AWSConfigBucketDelivery",
             'effect':
             "Allow",
             'action': ["s3:PutObject"],
             'principal': {
                 "Service": "config.amazonaws.com"
             },
             'resource_suffix': [
                 f"/AWSLogs/{account.account_id}/Config/*"
                 for account in accounts
             ],
             'condition': {
                 "StringEquals": {
                     "s3:x-amz-acl": "bucket-owner-full-control"
                 }
             },
         }]
     }
     s3bucket = paco.models.applications.S3Bucket('paco-awsconfig',
                                                  global_buckets)
     apply_attributes_from_config(
         s3bucket,
         bucket_config_dict,
         read_file_path=
         'dynamically generated in code paco.controllers.ctl_config')
     global_buckets['paco-awsconfig'] = s3bucket
     s3bucket.resolve_ref_object = self
     bucket_account_ctx = self.paco_ctx.get_account_context(
         account_ref=self.config.s3_bucket_logs_account)
     try:
         s3_config_ref = s3bucket.paco_ref_parts
         s3_ctl.init_context(bucket_account_ctx,
                             self.config.global_resources_region,
                             s3_config_ref, self, None)
         s3_ctl.add_bucket(s3bucket, config_ref=s3_config_ref)
     except PacoBucketExists:
         pass
     return s3bucket.get_bucket_name()
Ejemplo n.º 5
0
 def add_policy(self, policy_config_dict):
     policy_config = Policy(self)
     loader.apply_attributes_from_config(policy_config, policy_config_dict)
     self.policies.append(policy_config)
Ejemplo n.º 6
0
 def set_assume_role_policy(self, policy_config_dict):
     policy_config = AssumeRolePolicy(self)
     loader.apply_attributes_from_config(policy_config, policy_config_dict)
     self.assume_role_policy = policy_config
Ejemplo n.º 7
0
 def apply_config(self, config_dict):
     loader.apply_attributes_from_config(self, config_dict)
Ejemplo n.º 8
0
 def add_roles(self, roles_config_dict):
     roles_dict = {'roles': roles_config_dict}
     loader.apply_attributes_from_config(self, roles_dict)
Ejemplo n.º 9
0
    def __init__(self, paco_ctx, account_ctx, cloudtrail, controller, accounts,
                 account_default_region):
        aws_name = account_ctx.get_name()
        super().__init__(paco_ctx, account_ctx, 'CloudTrail', aws_name,
                         controller)
        project = self.paco_ctx.project
        self.cloudtrail = cloudtrail
        self.account_default_region = account_default_region
        self.stack_list = []
        for trail in cloudtrail.trails.values():
            if trail.region:
                region = trail.region
            else:
                region = self.account_default_region

            # Create an S3 bucket to store the CloudTrail in
            s3_ctl = self.paco_ctx.get_controller('S3')
            s3_config_ref = trail.paco_ref + '.s3bucket'
            # ToDo: StackTags is None
            s3_ctl.init_context(account_ctx, region, s3_config_ref, self, None)
            put_suffixes = []
            for account in accounts:
                if trail.s3_key_prefix:
                    put_suffixes.append("/{}/AWSLogs/{}/*".format(
                        trail.s3_key_prefix, account.account_id))
                else:
                    put_suffixes.append("/AWSLogs/{}/*".format(
                        account.account_id))
            bucket_config_dict = {
                'region':
                region,
                'account':
                account_ctx.gen_ref(),
                'bucket_name':
                'cloudtrail',
                'enabled':
                True,
                'deletion_policy':
                'delete',
                'policy': [{
                    'principal': {
                        "Service": "cloudtrail.amazonaws.com"
                    },
                    'effect': 'Allow',
                    'action': ['s3:GetBucketAcl'],
                    'resource_suffix': ['']
                }, {
                    'principal': {
                        "Service": "cloudtrail.amazonaws.com"
                    },
                    'effect': 'Allow',
                    'action': ['s3:PutObject'],
                    'resource_suffix': put_suffixes,
                    'condition': {
                        "StringEquals": {
                            "s3:x-amz-acl": "bucket-owner-full-control"
                        }
                    }
                }],
            }
            global_buckets = project['resource']['s3']
            s3bucket = paco.models.applications.S3Bucket(
                trail.name, global_buckets)
            apply_attributes_from_config(
                s3bucket,
                bucket_config_dict,
                read_file_path=
                'dynamically generated in code paco.controllers.ctl_cloudtrail'
            )
            global_buckets.buckets[trail.name] = s3bucket
            s3bucket.resolve_ref_object = self
            s3bucket.enabled = trail.is_enabled()
            try:
                s3_ctl.add_bucket(
                    s3bucket,
                    config_ref=s3_config_ref,
                )
            except PacoBucketExists:
                # for multiple accounts there is only one bucket needed
                pass
            # Create the CloudTrail stack and prepare it
            cloudtrail_template = paco.cftemplates.CloudTrail(
                self.paco_ctx,
                self.account_ctx,
                region,
                self,
                None,  #stack_tags
                trail,
                s3bucket.get_bucket_name())
            self.stack_list.append(cloudtrail_template.stack)
Ejemplo n.º 10
0
def create_role_from_yaml(yaml):
    config = load_yaml(yaml)
    role = RoleDefaultEnabled('role', None)
    apply_attributes_from_config(role, config)
    return role
Ejemplo n.º 11
0
    def __init__(
        self,
        paco_ctx,
        account_ctx,
        cloudtrail,
        controller,
        accounts,
        account_default_region,
        kms_key_account=False
    ):
        aws_name = account_ctx.get_name()
        super().__init__(
            paco_ctx,
            account_ctx,
            'CloudTrail',
            aws_name,
            controller
        )
        project = self.paco_ctx.project
        self.cloudtrail = cloudtrail
        self.account_default_region = account_default_region
        self.stack_list = []
        for trail in cloudtrail.trails.values():
            if trail.region:
                region = trail.region
            else:
                region = self.account_default_region

            # If KMS encryption is enabled then create a KMS Key for the trail
            if kms_key_account:
                kms_crypto_principle_list = []
                for account in accounts:
                    kms_crypto_principle_list.append(
                        "paco.sub 'arn:aws:iam::${%s}:root'" % (account.paco_ref)
                    )
                kms_config_dict = {
                    'admin_principal': {
                        'aws': [ "!Sub 'arn:aws:iam::${{AWS::AccountId}}:root'" ]
                    },
                    'crypto_principal': {
                        'aws': kms_crypto_principle_list
                    }
                }
                cloudtrail.kms_stack = self.add_new_stack(
                    region,
                    trail,
                    paco.cftemplates.KMS,
                    account_ctx=account_ctx,
                    support_resource_ref_ext='kms',
                    extra_context={'cloudtrail': trail}
                )
                self.stack_list.append(cloudtrail.kms_stack)

            # Create an S3 bucket to store the CloudTrail in
            s3_ctl = self.paco_ctx.get_controller('S3')
            # ToDo: StackTags is None
            put_suffixes = []
            for account in accounts:
                if trail.s3_key_prefix:
                    put_suffixes.append("/{}/AWSLogs/{}/*".format(trail.s3_key_prefix, account.account_id))
                else:
                    put_suffixes.append("/AWSLogs/{}/*".format(account.account_id))
            bucket_config_dict = {
                'region': region,
                'account': account_ctx.paco_ref,
                'bucket_name': 'cloudtrail',
                'enabled': True,
                'deletion_policy': 'delete',
                'policy': [ {
                    'principal': {"Service": "cloudtrail.amazonaws.com"},
                    'effect': 'Allow',
                    'action': ['s3:GetBucketAcl'],
                    'resource_suffix': ['']
                },
                {
                    'principal': {"Service": "cloudtrail.amazonaws.com"},
                    'effect': 'Allow',
                    'action': ['s3:PutObject'],
                    'resource_suffix': put_suffixes,
                    'condition': {"StringEquals": {"s3:x-amz-acl": "bucket-owner-full-control"}}
                } ],
            }
            global_buckets = project['resource']['s3'].buckets
            s3bucket = paco.models.applications.S3Bucket(trail.name, global_buckets)
            apply_attributes_from_config(s3bucket, bucket_config_dict, read_file_path = 'dynamically generated in code paco.controllers.ctl_cloudtrail')
            global_buckets[trail.name] = s3bucket
            s3bucket.resolve_ref_object = self
            s3bucket.enabled = trail.is_enabled()
            try:
                s3_config_ref = s3bucket.paco_ref_parts
                s3_ctl.init_context(account_ctx, region, s3_config_ref, self, None)
                s3_ctl.add_bucket(s3bucket, config_ref=s3_config_ref)
            except PacoBucketExists:
                # for multiple accounts there is only one bucket needed
                pass
            # Create the CloudTrail stack and prepare it
            stack = self.add_new_stack(
                region,
                trail,
                paco.cftemplates.CloudTrail,
                account_ctx=self.account_ctx,
                extra_context={'s3_bucket_name': s3bucket.get_bucket_name()}
            )
            self.stack_list.append(stack)