Beispiel #1
0
class IoTRule(PushEventSource):
    resource_type = 'IoTRule'
    principal = 'iot.amazonaws.com'

    property_types = {
        'Sql': PropertyType(True, is_str()),
        'AwsIotSqlVersion': PropertyType(False, is_str())
    }

    def to_cloudformation(self, **kwargs):
        function = kwargs.get('function')

        if not function:
            raise TypeError("Missing required keyword argument: function")

        resources = []

        resource = 'rule/${RuleName}'

        partition = ArnGenerator.get_partition_name()
        source_arn = fnSub(
            ArnGenerator.generate_arn(partition=partition,
                                      service='iot',
                                      resource=resource),
            {'RuleName': ref(self.logical_id)})
        source_account = fnSub('${AWS::AccountId}')

        resources.append(
            self._construct_permission(function,
                                       source_arn=source_arn,
                                       source_account=source_account))
        resources.append(self._construct_iot_rule(function))

        return resources

    def _construct_iot_rule(self, function):
        rule = IotTopicRule(self.logical_id)

        payload = {
            'Sql':
            self.Sql,
            'RuleDisabled':
            False,
            'Actions': [{
                'Lambda': {
                    'FunctionArn': function.get_runtime_attr("arn")
                }
            }]
        }

        if self.AwsIotSqlVersion:
            payload['AwsIotSqlVersion'] = self.AwsIotSqlVersion

        rule.TopicRulePayload = payload
        if CONDITION in function.resource_attributes:
            rule.set_resource_attribute(
                CONDITION, function.resource_attributes[CONDITION])

        return rule
Beispiel #2
0
class Schedule(PushEventSource):
    """Scheduled executions for SAM Functions."""
    resource_type = 'Schedule'
    principal = 'events.amazonaws.com'
    property_types = {
        'Schedule': PropertyType(True, is_str()),
        'Input': PropertyType(False, is_str()),
        'Enabled': PropertyType(False, is_type(bool)),
        'Name': PropertyType(False, is_str()),
        'Description': PropertyType(False, is_str())
    }

    def to_cloudformation(self, **kwargs):
        """Returns the CloudWatch Events Rule and Lambda Permission to which this Schedule event source corresponds.

        :param dict kwargs: no existing resources need to be modified
        :returns: a list of vanilla CloudFormation Resources, to which this Schedule event expands
        :rtype: list
        """
        function = kwargs.get('function')

        if not function:
            raise TypeError("Missing required keyword argument: function")

        resources = []

        events_rule = EventsRule(self.logical_id)
        resources.append(events_rule)

        events_rule.ScheduleExpression = self.Schedule
        if self.Enabled is not None:
            events_rule.State = "ENABLED" if self.Enabled else "DISABLED"
        events_rule.Name = self.Name
        events_rule.Description = self.Description
        events_rule.Targets = [self._construct_target(function)]

        source_arn = events_rule.get_runtime_attr("arn")
        if CONDITION in function.resource_attributes:
            events_rule.set_resource_attribute(
                CONDITION, function.resource_attributes[CONDITION])
        resources.append(
            self._construct_permission(function, source_arn=source_arn))

        return resources

    def _construct_target(self, function):
        """Constructs the Target property for the CloudWatch Events Rule.

        :returns: the Target property
        :rtype: dict
        """
        target = {
            'Arn': function.get_runtime_attr("arn"),
            'Id': self.logical_id + 'LambdaTarget'
        }
        if self.Input is not None:
            target['Input'] = self.Input

        return target
class SamSimpleTable(SamResourceMacro):
    """SAM simple table macro.
    """
    resource_type = 'AWS::Serverless::SimpleTable'
    property_types = {
        'PrimaryKey': PropertyType(False, dict_of(is_str(), is_str())),
        'ProvisionedThroughput': PropertyType(False, dict_of(is_str(), one_of(is_type(int), is_type(dict)))),
        'TableName': PropertyType(False, one_of(is_str(), is_type(dict))),
        'Tags': PropertyType(False, is_type(dict))
    }
    attribute_type_conversions = {
        'String': 'S',
        'Number': 'N',
        'Binary': 'B'
    }

    def to_cloudformation(self, **kwargs):
        dynamodb_resources = self._construct_dynamodb_table()

        return [dynamodb_resources]


    def _construct_dynamodb_table(self):
        dynamodb_table = DynamoDBTable(self.logical_id, depends_on=self.depends_on)

        if self.PrimaryKey:
            primary_key = {
                'AttributeName': self.PrimaryKey['Name'],
                'AttributeType': self._convert_attribute_type(self.PrimaryKey['Type'])
            }

        else:
            primary_key = {'AttributeName': 'id', 'AttributeType': 'S'}

        dynamodb_table.AttributeDefinitions = [primary_key]
        dynamodb_table.KeySchema = [{
            'AttributeName': primary_key['AttributeName'],
            'KeyType': 'HASH'
        }]

        if self.ProvisionedThroughput:
            provisioned_throughput = self.ProvisionedThroughput
        else:
            provisioned_throughput = {'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5}

        dynamodb_table.ProvisionedThroughput = provisioned_throughput

        if self.TableName:
            dynamodb_table.TableName = self.TableName

        if bool(self.Tags):
            dynamodb_table.Tags = get_tag_list(self.Tags)

        return dynamodb_table

    def _convert_attribute_type(self, attribute_type):
        if attribute_type in self.attribute_type_conversions:
            return self.attribute_type_conversions[attribute_type]
        raise InvalidResourceException(self.logical_id, 'Invalid \'Type\' "{actual}".'.format(actual=attribute_type))
class ApiGatewayDomainName(Resource):
    resource_type = 'AWS::ApiGateway::DomainName'
    property_types = {
            'RegionalCertificateArn': PropertyType(False, is_str()),
            'DomainName': PropertyType(True, is_str()),
            'EndpointConfiguration': PropertyType(False, is_type(dict)),
            'CertificateArn': PropertyType(False, is_str())
    }
class ApiGatewayBasePathMapping(Resource):
    resource_type = 'AWS::ApiGateway::BasePathMapping'
    property_types = {
        'BasePath': PropertyType(False, is_str()),
        'DomainName': PropertyType(True, is_str()),
        'RestApiId': PropertyType(False, is_str()),
        'Stage': PropertyType(False, is_str())
    }
Beispiel #6
0
class ApiGatewayV2ApiMapping(Resource):
    resource_type = "AWS::ApiGatewayV2::ApiMapping"
    property_types = {
        "ApiId": PropertyType(True, is_str()),
        "ApiMappingKey": PropertyType(False, is_str()),
        "DomainName": PropertyType(True, is_str()),
        "Stage": PropertyType(True, is_str()),
    }
Beispiel #7
0
class SNSSubscription(Resource):
    resource_type = 'AWS::SNS::Subscription'
    property_types = {
        'Endpoint': PropertyType(True, is_str()),
        'Protocol': PropertyType(True, is_str()),
        'TopicArn': PropertyType(True, is_str()),
        'FilterPolicy': PropertyType(False, is_type(dict))
    }
Beispiel #8
0
class ApiGatewayDomainName(Resource):
    resource_type = "AWS::ApiGateway::DomainName"
    property_types = {
        "RegionalCertificateArn": PropertyType(False, is_str()),
        "DomainName": PropertyType(True, is_str()),
        "EndpointConfiguration": PropertyType(False, is_type(dict)),
        "CertificateArn": PropertyType(False, is_str()),
    }
Beispiel #9
0
class ApiGatewayBasePathMapping(Resource):
    resource_type = "AWS::ApiGateway::BasePathMapping"
    property_types = {
        "BasePath": PropertyType(False, is_str()),
        "DomainName": PropertyType(True, is_str()),
        "RestApiId": PropertyType(False, is_str()),
        "Stage": PropertyType(False, is_str()),
    }
Beispiel #10
0
class CloudWatchEvent(PushEventSource):
    """CloudWatch Events event source for SAM Functions."""
    resource_type = 'CloudWatchEvent'
    principal = 'events.amazonaws.com'
    property_types = {
        'EventBusName': PropertyType(False, is_str()),
        'Pattern': PropertyType(False, is_type(dict)),
        'Input': PropertyType(False, is_str()),
        'InputPath': PropertyType(False, is_str())
    }

    def to_cloudformation(self, **kwargs):
        """Returns the CloudWatch Events Rule and Lambda Permission to which this CloudWatch Events event source
        corresponds.

        :param dict kwargs: no existing resources need to be modified
        :returns: a list of vanilla CloudFormation Resources, to which this CloudWatch Events event expands
        :rtype: list
        """
        function = kwargs.get('function')

        if not function:
            raise TypeError("Missing required keyword argument: function")

        resources = []

        events_rule = EventsRule(self.logical_id)
        events_rule.EventBusName = self.EventBusName
        events_rule.EventPattern = self.Pattern
        events_rule.Targets = [self._construct_target(function)]
        if CONDITION in function.resource_attributes:
            events_rule.set_resource_attribute(
                CONDITION, function.resource_attributes[CONDITION])

        resources.append(events_rule)

        source_arn = events_rule.get_runtime_attr("arn")
        resources.append(
            self._construct_permission(function, source_arn=source_arn))

        return resources

    def _construct_target(self, function):
        """Constructs the Target property for the CloudWatch Events Rule.

        :returns: the Target property
        :rtype: dict
        """
        target = {
            'Arn': function.get_runtime_attr("arn"),
            'Id': self.logical_id + 'LambdaTarget'
        }
        if self.Input is not None:
            target['Input'] = self.Input

        if self.InputPath is not None:
            target['InputPath'] = self.InputPath
        return target
Beispiel #11
0
class SamHttpApi(SamResourceMacro):
    """SAM rest API macro.
    """
    resource_type = 'AWS::Serverless::HttpApi'
    property_types = {
        # Internal property set only by Implicit HTTP API plugin. If set to True, the API Event Source code will
        # inject Lambda Integration URI to the OpenAPI. To preserve backwards compatibility, this must be set only for
        # Implicit APIs. For Explicit APIs, this is managed by the DefaultDefinitionBody Plugin.
        # In the future, we might rename and expose this property to customers so they can have SAM manage Explicit APIs
        # Swagger.
        '__MANAGE_SWAGGER': PropertyType(False, is_type(bool)),
        'StageName': PropertyType(False, one_of(is_str(), is_type(dict))),
        'Tags': PropertyType(False, is_type(dict)),
        'DefinitionBody': PropertyType(False, is_type(dict)),
        'DefinitionUri': PropertyType(False, one_of(is_str(), is_type(dict))),
        'StageVariables': PropertyType(False, is_type(dict)),
        'Cors': PropertyType(False, one_of(is_str(), is_type(dict))),
        'AccessLogSettings': PropertyType(False, is_type(dict)),
        'Auth': PropertyType(False, is_type(dict))
    }

    referable_properties = {
        "Stage": ApiGatewayV2Stage.resource_type,
    }

    def to_cloudformation(self, **kwargs):
        """Returns the API Gateway RestApi, Deployment, and Stage to which this SAM Api corresponds.

        :param dict kwargs: already-converted resources that may need to be modified when converting this \
        macro to pure CloudFormation
        :returns: a list of vanilla CloudFormation Resources, to which this Function expands
        :rtype: list
        """
        resources = []

        api_generator = HttpApiGenerator(
            self.logical_id,
            self.StageVariables,
            self.depends_on,
            self.DefinitionBody,
            self.DefinitionUri,
            self.StageName,
            tags=self.Tags,
            auth=self.Auth,
            access_log_settings=self.AccessLogSettings,
            resource_attributes=self.resource_attributes,
            passthrough_resource_attributes=self.
            get_passthrough_resource_attributes())

        http_api, stage = api_generator.to_cloudformation()

        resources.append(http_api)

        # Stage is now optional. Only add it if one is created.
        if stage:
            resources.append(stage)

        return resources
Beispiel #12
0
class ApiGatewayDeployment(Resource):
    _X_HASH_DELIMITER = "||"

    resource_type = "AWS::ApiGateway::Deployment"
    property_types = {
        "Description": PropertyType(False, is_str()),
        "RestApiId": PropertyType(True, is_str()),
        "StageDescription": PropertyType(False, is_type(dict)),
        "StageName": PropertyType(False, is_str()),
    }

    runtime_attrs = {"deployment_id": lambda self: ref(self.logical_id)}

    def make_auto_deployable(self,
                             stage,
                             openapi_version=None,
                             swagger=None,
                             domain=None,
                             redeploy_restapi_parameters=None):
        """
        Sets up the resource such that it will trigger a re-deployment when Swagger changes
        or the openapi version changes or a domain resource changes.

        :param swagger: Dictionary containing the Swagger definition of the API
        :param openapi_version: string containing value of OpenApiVersion flag in the template
        :param domain: Dictionary containing the custom domain configuration for the API
        :param redeploy_restapi_parameters: Dictionary containing the properties for which rest api will be redeployed
        """
        if not swagger:
            return

        # CloudFormation does NOT redeploy the API unless it has a new deployment resource
        # that points to latest RestApi resource. Append a hash of Swagger Body location to
        # redeploy only when the API data changes. First 10 characters of hash is good enough
        # to prevent redeployment when API has not changed

        # NOTE: `str(swagger)` is for backwards compatibility. Changing it to a JSON or something will break compat
        hash_input = [str(swagger)]
        if openapi_version:
            hash_input.append(str(openapi_version))
        if domain:
            hash_input.append(json.dumps(domain))
        if redeploy_restapi_parameters:
            function_names = redeploy_restapi_parameters.get("function_names")
        else:
            function_names = None
        # The deployment logical id is <api logicalId> + "Deployment"
        # The keyword "Deployment" is removed and all the function names associated with api is obtained
        if function_names and function_names.get(self.logical_id[:-10], None):
            hash_input.append(function_names.get(self.logical_id[:-10], ""))
        data = self._X_HASH_DELIMITER.join(hash_input)
        generator = logical_id_generator.LogicalIdGenerator(
            self.logical_id, data)
        self.logical_id = generator.gen()
        digest = generator.get_hash(length=40)  # Get the full hash
        self.Description = "RestApi deployment id: {}".format(digest)
        stage.update_deployment_ref(self.logical_id)
Beispiel #13
0
class Schedule(EventSource):
    """Scheduled executions for SAM State Machine."""

    resource_type = "Schedule"
    principal = "events.amazonaws.com"
    property_types = {
        "Schedule": PropertyType(True, is_str()),
        "Input": PropertyType(False, is_str()),
        "Enabled": PropertyType(False, is_type(bool)),
        "Name": PropertyType(False, is_str()),
        "Description": PropertyType(False, is_str()),
    }

    def to_cloudformation(self, resource, **kwargs):
        """Returns the EventBridge Rule and IAM Role to which this Schedule event source corresponds.

        :param dict kwargs: no existing resources need to be modified
        :returns: a list of vanilla CloudFormation Resources, to which this Schedule event expands
        :rtype: list
        """
        resources = []

        permissions_boundary = kwargs.get("permissions_boundary")

        events_rule = EventsRule(self.logical_id)
        resources.append(events_rule)

        events_rule.ScheduleExpression = self.Schedule
        if self.Enabled is not None:
            events_rule.State = "ENABLED" if self.Enabled else "DISABLED"
        events_rule.Name = self.Name
        events_rule.Description = self.Description
        if CONDITION in resource.resource_attributes:
            events_rule.set_resource_attribute(
                CONDITION, resource.resource_attributes[CONDITION])

        role = self._construct_role(resource, permissions_boundary)
        resources.append(role)
        events_rule.Targets = [self._construct_target(resource, role)]

        return resources

    def _construct_target(self, resource, role):
        """Constructs the Target property for the EventBridge Rule.

        :returns: the Target property
        :rtype: dict
        """
        target = {
            "Arn": resource.get_runtime_attr("arn"),
            "Id": self.logical_id + "StepFunctionsTarget",
            "RoleArn": role.get_runtime_attr("arn"),
        }
        if self.Input is not None:
            target["Input"] = self.Input

        return target
Beispiel #14
0
class SNSSubscription(Resource):
    resource_type = "AWS::SNS::Subscription"
    property_types = {
        "Endpoint": PropertyType(True, is_str()),
        "Protocol": PropertyType(True, is_str()),
        "TopicArn": PropertyType(True, is_str()),
        "Region": PropertyType(False, is_str()),
        "FilterPolicy": PropertyType(False, is_type(dict)),
    }
Beispiel #15
0
class LambdaEventInvokeConfig(Resource):
    resource_type = "AWS::Lambda::EventInvokeConfig"
    property_types = {
        "DestinationConfig": PropertyType(False, is_type(dict)),
        "FunctionName": PropertyType(True, is_str()),
        "MaximumEventAgeInSeconds": PropertyType(False, is_type(int)),
        "MaximumRetryAttempts": PropertyType(False, is_type(int)),
        "Qualifier": PropertyType(True, is_str()),
    }
Beispiel #16
0
class LambdaPermission(Resource):
    resource_type = 'AWS::Lambda::Permission'
    property_types = {
        'Action': PropertyType(True, is_str()),
        'FunctionName': PropertyType(True, is_str()),
        'Principal': PropertyType(True, is_str()),
        'SourceAccount': PropertyType(False, is_str()),
        'SourceArn': PropertyType(False, is_str())
    }
Beispiel #17
0
class SamApplication(SamResourceMacro):
    """SAM application macro.
    """

    APPLICATION_ID_KEY = 'ApplicationId'
    SEMANTIC_VERSION_KEY = 'SemanticVersion'

    resource_type = 'AWS::Serverless::Application'

    # The plugin will always insert the TemplateUrl parameter
    property_types = {
        'Location': PropertyType(True, one_of(is_str(), is_type(dict))),
        'TemplateUrl': PropertyType(False, is_str()),
        'Parameters': PropertyType(False, is_type(dict)),
        'NotificationARNs': PropertyType(False, list_of(is_str())),
        'Tags': PropertyType(False, is_type(dict)),
        'TimeoutInMinutes': PropertyType(False, is_type(int))
    }

    def to_cloudformation(self, **kwargs):
        """Returns the stack with the proper parameters for this application
        """
        nested_stack = self._construct_nested_stack()
        return [nested_stack]

    def _construct_nested_stack(self):
        """Constructs a AWS::CloudFormation::Stack resource
        """
        nested_stack = NestedStack(
            self.logical_id,
            depends_on=self.depends_on,
            attributes=self.get_passthrough_resource_attributes())
        nested_stack.Parameters = self.Parameters
        nested_stack.NotificationARNs = self.NotificationARNs
        application_tags = self._get_application_tags()
        nested_stack.Tags = self._construct_tag_list(self.Tags,
                                                     application_tags)
        nested_stack.TimeoutInMinutes = self.TimeoutInMinutes
        nested_stack.TemplateURL = self.TemplateUrl if self.TemplateUrl else ""

        return nested_stack

    def _get_application_tags(self):
        """Adds tags to the stack if this resource is using the serverless app repo
        """
        application_tags = {}
        if isinstance(self.Location, dict):
            if (self.APPLICATION_ID_KEY in self.Location.keys()
                    and self.Location[self.APPLICATION_ID_KEY] is not None):
                application_tags[self._SAR_APP_KEY] = self.Location[
                    self.APPLICATION_ID_KEY]
            if (self.SEMANTIC_VERSION_KEY in self.Location.keys()
                    and self.Location[self.SEMANTIC_VERSION_KEY] is not None):
                application_tags[self._SAR_SEMVER_KEY] = self.Location[
                    self.SEMANTIC_VERSION_KEY]
        return application_tags
Beispiel #18
0
class CloudWatchEvent(EventSource):
    """CloudWatch Events/EventBridge event source for SAM State Machine."""

    resource_type = "CloudWatchEvent"
    principal = "events.amazonaws.com"
    property_types = {
        "EventBusName": PropertyType(False, is_str()),
        "Pattern": PropertyType(False, is_type(dict)),
        "Input": PropertyType(False, is_str()),
        "InputPath": PropertyType(False, is_str()),
    }

    def to_cloudformation(self, resource, **kwargs):
        """Returns the CloudWatch Events/EventBridge Rule and IAM Role to which this
        CloudWatch Events/EventBridge event source corresponds.

        :param dict kwargs: no existing resources need to be modified
        :returns: a list of vanilla CloudFormation Resources, to which this CloudWatch Events/EventBridge event expands
        :rtype: list
        """
        resources = []

        permissions_boundary = kwargs.get("permissions_boundary")

        events_rule = EventsRule(self.logical_id)
        events_rule.EventBusName = self.EventBusName
        events_rule.EventPattern = self.Pattern
        if CONDITION in resource.resource_attributes:
            events_rule.set_resource_attribute(
                CONDITION, resource.resource_attributes[CONDITION])

        resources.append(events_rule)

        role = self._construct_role(resource, permissions_boundary)
        resources.append(role)
        events_rule.Targets = [self._construct_target(resource, role)]

        return resources

    def _construct_target(self, resource, role):
        """Constructs the Target property for the CloudWatch Events/EventBridge Rule.

        :returns: the Target property
        :rtype: dict
        """
        target = {
            "Arn": resource.get_runtime_attr("arn"),
            "Id": self.logical_id + "StepFunctionsTarget",
            "RoleArn": role.get_runtime_attr("arn"),
        }
        if self.Input is not None:
            target["Input"] = self.Input

        if self.InputPath is not None:
            target["InputPath"] = self.InputPath
        return target
class LambdaAlias(Resource):
    resource_type = 'AWS::Lambda::Alias'
    property_types = {
        'Description': PropertyType(False, is_str()),
        'Name': PropertyType(False, is_str()),
        'FunctionName': PropertyType(True, one_of(is_str(), is_type(dict))),
        'FunctionVersion': PropertyType(True, one_of(is_str(), is_type(dict)))
    }

    runtime_attrs = {"arn": lambda self: ref(self.logical_id)}
Beispiel #20
0
class LambdaFunction(Resource):
    resource_type = "AWS::Lambda::Function"
    property_types = {
        "Code": PropertyType(True, is_type(dict)),
        "PackageType": PropertyType(False, is_str()),
        "DeadLetterConfig": PropertyType(False, is_type(dict)),
        "Description": PropertyType(False, is_str()),
        "FunctionName": PropertyType(False, is_str()),
        "Handler": PropertyType(False, is_str()),
        "MemorySize": PropertyType(False, is_type(int)),
        "Role": PropertyType(False, is_str()),
        "Runtime": PropertyType(False, is_str()),
        "Timeout": PropertyType(False, is_type(int)),
        "VpcConfig": PropertyType(False, is_type(dict)),
        "Environment": PropertyType(False, is_type(dict)),
        "Tags": PropertyType(False, list_of(is_type(dict))),
        "TracingConfig": PropertyType(False, is_type(dict)),
        "KmsKeyArn": PropertyType(False, one_of(is_type(dict), is_str())),
        "Layers": PropertyType(False, list_of(one_of(is_str(),
                                                     is_type(dict)))),
        "ReservedConcurrentExecutions": PropertyType(False, any_type()),
        "FileSystemConfigs": PropertyType(False, list_of(is_type(dict))),
        "CodeSigningConfigArn": PropertyType(False, is_str()),
        "ImageConfig": PropertyType(False, is_type(dict)),
    }

    runtime_attrs = {
        "name": lambda self: ref(self.logical_id),
        "arn": lambda self: fnGetAtt(self.logical_id, "Arn")
    }
Beispiel #21
0
class CognitoUserPool(Resource):
    resource_type = "AWS::Cognito::UserPool"
    property_types = {
        "AdminCreateUserConfig": PropertyType(False, is_type(dict)),
        "AliasAttributes": PropertyType(False, list_of(is_str())),
        "AutoVerifiedAttributes": PropertyType(False, list_of(is_str())),
        "DeviceConfiguration": PropertyType(False, is_type(dict)),
        "EmailConfiguration": PropertyType(False, is_type(dict)),
        "EmailVerificationMessage": PropertyType(False, is_str()),
        "EmailVerificationSubject": PropertyType(False, is_str()),
        "LambdaConfig": PropertyType(False, is_type(dict)),
        "MfaConfiguration": PropertyType(False, is_str()),
        "Policies": PropertyType(False, is_type(dict)),
        "Schema": PropertyType(False, list_of(dict)),
        "SmsAuthenticationMessage": PropertyType(False, is_str()),
        "SmsConfiguration": PropertyType(False, list_of(dict)),
        "SmsVerificationMessage": PropertyType(False, is_str()),
        "UsernameAttributes": PropertyType(False, list_of(is_str())),
        "UserPoolAddOns": PropertyType(False, list_of(dict)),
        "UserPoolName": PropertyType(False, is_str()),
        "UserPoolTags": PropertyType(False, is_type(dict)),
        "VerificationMessageTemplate": PropertyType(False, is_type(dict)),
    }

    runtime_attrs = {
        "name": lambda self: ref(self.logical_id),
        "arn": lambda self: fnGetAtt(self.logical_id, "Arn"),
        "provider_name":
        lambda self: fnGetAtt(self.logical_id, "ProviderName"),
        "provider_url": lambda self: fnGetAtt(self.logical_id, "ProviderURL"),
    }
Beispiel #22
0
class LambdaAlias(Resource):
    resource_type = "AWS::Lambda::Alias"
    property_types = {
        "Description": PropertyType(False, is_str()),
        "Name": PropertyType(False, is_str()),
        "FunctionName": PropertyType(True, one_of(is_str(), is_type(dict))),
        "FunctionVersion": PropertyType(True, one_of(is_str(), is_type(dict))),
        "ProvisionedConcurrencyConfig": PropertyType(False, is_type(dict)),
    }

    runtime_attrs = {"arn": lambda self: ref(self.logical_id)}
Beispiel #23
0
class CloudWatchLogs(PushEventSource):
    """CloudWatch Logs event source for SAM Functions."""

    resource_type = "CloudWatchLogs"
    principal = "logs.amazonaws.com"
    property_types = {
        "LogGroupName": PropertyType(True, is_str()),
        "FilterPattern": PropertyType(True, is_str())
    }

    def to_cloudformation(self, **kwargs):
        """Returns the CloudWatch Logs Subscription Filter and Lambda Permission to which this CloudWatch Logs event source
        corresponds.

        :param dict kwargs: no existing resources need to be modified
        :returns: a list of vanilla CloudFormation Resources, to which this push event expands
        :rtype: list
        """
        function = kwargs.get("function")

        if not function:
            raise TypeError("Missing required keyword argument: function")

        source_arn = self.get_source_arn()
        permission = self._construct_permission(function,
                                                source_arn=source_arn)
        subscription_filter = self.get_subscription_filter(
            function, permission)
        resources = [permission, subscription_filter]

        return resources

    def get_source_arn(self):
        resource = "log-group:${__LogGroupName__}:*"
        partition = ArnGenerator.get_partition_name()

        return fnSub(
            ArnGenerator.generate_arn(partition=partition,
                                      service="logs",
                                      resource=resource),
            {"__LogGroupName__": self.LogGroupName},
        )

    def get_subscription_filter(self, function, permission):
        subscription_filter = SubscriptionFilter(
            self.logical_id, depends_on=[permission.logical_id])
        subscription_filter.LogGroupName = self.LogGroupName
        subscription_filter.FilterPattern = self.FilterPattern
        subscription_filter.DestinationArn = function.get_runtime_attr("arn")
        if "Condition" in function.resource_attributes:
            subscription_filter.set_resource_attribute(
                "Condition", function.resource_attributes["Condition"])

        return subscription_filter
Beispiel #24
0
class ApiGatewayUsagePlan(Resource):
    resource_type = "AWS::ApiGateway::UsagePlan"
    property_types = {
        "ApiStages": PropertyType(False, is_type(list)),
        "Description": PropertyType(False, is_str()),
        "Quota": PropertyType(False, is_type(dict)),
        "Tags": PropertyType(False, list_of(dict)),
        "Throttle": PropertyType(False, is_type(dict)),
        "UsagePlanName": PropertyType(False, is_str()),
    }
    runtime_attrs = {"usage_plan_id": lambda self: ref(self.logical_id)}
Beispiel #25
0
class LambdaEventSourceMapping(Resource):
    resource_type = 'AWS::Lambda::EventSourceMapping'
    property_types = {
        'BatchSize': PropertyType(False, is_type(int)),
        'Enabled': PropertyType(False, is_type(bool)),
        'EventSourceArn': PropertyType(True, is_str()),
        'FunctionName': PropertyType(True, is_str()),
        'StartingPosition': PropertyType(True, is_str())
    }

    runtime_attrs = {"name": lambda self: ref(self.logical_id)}
class LambdaVersion(Resource):
    resource_type = 'AWS::Lambda::Version'
    property_types = {
        'CodeSha256': PropertyType(False, is_str()),
        'Description': PropertyType(False, is_str()),
        'FunctionName': PropertyType(True, one_of(is_str(), is_type(dict)))
    }

    runtime_attrs = {
        "arn": lambda self: ref(self.logical_id),
        "version": lambda self: fnGetAtt(self.logical_id, "Version")
    }
Beispiel #27
0
class SubscriptionFilter(Resource):
    resource_type = "AWS::Logs::SubscriptionFilter"
    property_types = {
        "LogGroupName": PropertyType(True, is_str()),
        "FilterPattern": PropertyType(True, is_str()),
        "DestinationArn": PropertyType(True, is_str()),
    }

    runtime_attrs = {
        "name": lambda self: ref(self.logical_id),
        "arn": lambda self: fnGetAtt(self.logical_id, "Arn")
    }
Beispiel #28
0
class NestedStack(Resource):
    resource_type = 'AWS::CloudFormation::Stack'
    # TODO: support passthrough parameters for stacks (Conditions, etc)
    property_types = {
        'TemplateURL': PropertyType(True, is_str()),
        'Parameters': PropertyType(False, is_type(dict)),
        'NotificationArns': PropertyType(False, list_of(is_str())),
        'Tags': PropertyType(False, list_of(is_type(dict))),
        'TimeoutInMinutes': PropertyType(False, is_type(int))
    }

    runtime_attrs = {"stack_id": lambda self: ref(self.logical_id)}
Beispiel #29
0
class IAMRole(Resource):
    resource_type = "AWS::IAM::Role"
    property_types = {
        "AssumeRolePolicyDocument": PropertyType(True, is_type(dict)),
        "ManagedPolicyArns": PropertyType(False, is_type(list)),
        "Path": PropertyType(False, is_str()),
        "Policies": PropertyType(False, is_type(list)),
        "PermissionsBoundary": PropertyType(False, is_str()),
        "Tags": PropertyType(False, list_of(is_type(dict))),
    }

    runtime_attrs = {"name": lambda self: ref(self.logical_id), "arn": lambda self: fnGetAtt(self.logical_id, "Arn")}
Beispiel #30
0
class ApiGatewayV2HttpApi(Resource):
    resource_type = "AWS::ApiGatewayV2::Api"
    property_types = {
        "Body": PropertyType(False, is_type(dict)),
        "BodyS3Location": PropertyType(False, is_type(dict)),
        "Description": PropertyType(False, is_str()),
        "FailOnWarnings": PropertyType(False, is_type(bool)),
        "BasePath": PropertyType(False, is_str()),
        "CorsConfiguration": PropertyType(False, is_type(dict)),
    }

    runtime_attrs = {"http_api_id": lambda self: ref(self.logical_id)}