def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=SNS_CONFIG_SCHEMA,
                               configuration_received=self._configuration)

        # Defining SNS Topic
        topic_data = deepcopy(self._configuration["topic"])
        self._sns_topic = base_topic(self, **topic_data)

        # Validating Lambda Function Runtime
        functions_data = self._configuration["lambda_handlers"]
        self._lambda_functions = list()
        for lambda_function in functions_data:
            _lambda_function = base_lambda_function(self, **lambda_function)
            self._lambda_functions.append(_lambda_function)

            # Defining the Lambda subscription to the specified SNS Topic in cdk.json file.
            sns_subscription = sns_subs.LambdaSubscription(fn=_lambda_function)
            self._sns_topic.add_subscription(sns_subscription)
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=S3_LAMBDA_CONFIG_SCHEMA,
                               configuration_received=self._configuration)

        # Defining S3 Bucket
        bucket_data = deepcopy(self._configuration["bucket"])
        self._s3_bucket = base_bucket(self, **bucket_data)

        # Validating Lambda Function Runtime
        functions_data = self._configuration["lambda_handler"]
        self._lambda_function = base_lambda_function(self, **functions_data)

        # Defining the Lambda subscription to the specified S3 Bucket in cdk.json file.
        s3_events = self._configuration["events"]
        event_list = enum_parsing(source_list=s3_events,
                                  target_enum=s3.EventType)

        s3_subscription = events.S3EventSource(bucket=self._s3_bucket,
                                               events=event_list)
        self._lambda_function.add_event_source(source=s3_subscription)
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case APIGATEWAY_FAN_OUT_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(
            configuration_schema=LAMBDA_FUNCTIONS_CLUSTER_SCHEMA,
            configuration_received=self._configuration)

        # Define FAN-Out Lambda functions
        self._lambda_functions = list()
        for lambda_function in self._configuration["functions"]:
            _lambda = base_lambda_function(self, **lambda_function)
            self._lambda_functions.append(_lambda)
Exemple #4
0
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case SQS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=SQS_CONFIG_SCHEMA,
                               configuration_received=self._configuration)

        # Defining SQS Queue
        queue_data = deepcopy(self._configuration["queue"])
        self._sqs_queue = base_queue(construct=self, **queue_data)

        # Validating Lambda Function Runtime
        functions_data = self._configuration["lambda_handlers"]
        self._lambda_functions = list()
        for lambda_function in functions_data:
            _lambda_function = base_lambda_function(self, **lambda_function)
            self._lambda_functions.append(_lambda_function)

            _lambda_function.add_event_source(
                lambda_sources.SqsEventSource(queue=self._sqs_queue,
                                              batch_size=10))
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case IOT_SNS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=IOT_LAMBDA_CONFIG_SCHEMA,
                               configuration_received=self._configuration)

        # Validating Lambda Function Runtime
        functions_data = self._configuration["lambda_handler"]
        self._lambda_function = base_lambda_function(self, **functions_data)

        # Defining Topic Rule properties
        action = iot.CfnTopicRule.LambdaActionProperty(
            function_arn=self._lambda_function.function_arn)
        action_property = iot.CfnTopicRule.ActionProperty(lambda_=action)

        rule_data = self._configuration["iot_rule"]
        self._iot_rule = base_iot_rule(self,
                                       action_property=action_property,
                                       **rule_data)
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case IOT_SNS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=IOT_KINESIS_CONFIG_SCHEMA,
                               configuration_received=self._configuration)

        # Defining Kinesis Stream
        stream_data = deepcopy(self._configuration["stream"])
        self._kinesis_stream = base_kinesis_stream(self, **stream_data)

        # Defining IAM Role
        role = base_kinesis_role(self,
                                 resource_name=stream_data["stream_name"],
                                 principal_resource="iot")

        # Validating Lambda Function Runtime
        functions_data = self._configuration["lambda_handlers"]
        self._lambda_functions = list()
        for setting in functions_data:
            _lambda_function = base_lambda_function(
                self, **setting["lambda_handler"])
            self._lambda_functions.append(_lambda_function)

            # Defining Function Subscription
            event_source = event_src.KinesisEventSource(
                stream=self._kinesis_stream, **setting["event_settings"])
            _lambda_function.add_event_source(event_source)

        # Defining Topic Rule properties
        action = iot.CfnTopicRule.KinesisActionProperty(
            stream_name=self._kinesis_stream.stream_name,
            role_arn=role.role_arn)
        action_property = iot.CfnTopicRule.ActionProperty(kinesis=action)

        rule_data = self._configuration["iot_rule"]
        self._iot_rule = base_iot_rule(self,
                                       action_property=action_property,
                                       **rule_data)
Exemple #7
0
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case IOT_SNS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=IOT_SNS_CONFIG_SCHEMA,
                               configuration_received=self._configuration)

        # Defining SNS Topic
        topic_data = deepcopy(self._configuration["topic"])
        self._sns_topic = base_topic(self, **topic_data)

        # Defining IAM Role
        role = base_sns_role(self,
                             resource_name=topic_data["topic_name"],
                             principal_resource="iot")

        # Validating Lambda Function Runtime
        functions_data = self._configuration["lambda_handlers"]
        self._lambda_functions = list()
        for lambda_function in functions_data:
            _lambda_function = base_lambda_function(self, **lambda_function)
            self._lambda_functions.append(_lambda_function)

            # Defining the Lambda subscription to the specified SNS Topic in cdk.json file.
            sns_subscription = sns_subs.LambdaSubscription(fn=_lambda_function)
            self._sns_topic.add_subscription(sns_subscription)

        # Defining Topic Rule properties
        action = iot.CfnTopicRule.SnsActionProperty(
            target_arn=self._sns_topic.topic_arn, role_arn=role.role_arn)
        action_property = iot.CfnTopicRule.ActionProperty(sns=action)

        rule_data = self._configuration["iot_rule"]
        self._iot_rule = base_iot_rule(self,
                                       action_property=action_property,
                                       **rule_data)
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=CLOUDWATCH_CONFIG_SCHEMA,
                               configuration_received=self._configuration)
        rule_configuration = self._configuration["cloudwatch_rule"]

        rule_name = self.prefix + "_" + rule_configuration[
            "rule_name"] + "_" + self.environment_
        schedule = events.Schedule.expression(
            f"cron({rule_configuration['schedule']})")
        self._cloudwatch_event = events.Rule(
            self,
            id=rule_name,
            rule_name=rule_name,
            description=rule_configuration.get("description"),
            enabled=rule_configuration["enabled"],
            schedule=schedule,
        )

        self._lambda_functions = list()
        for function_definition in self._configuration["lambda_handlers"]:
            function_ = base_lambda_function(self, **function_definition)
            self._cloudwatch_event.add_target(
                targets.LambdaFunction(handler=function_))
            self._lambda_functions.append(function_)
Exemple #9
0
    def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case IOT_SNS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=IOT_SQS_CONFIG_SCHEMA, configuration_received=self._configuration)

        # Defining SQS Queue
        queue_data = deepcopy(self._configuration["queue"])
        self._sqs_queue = base_queue(construct=self, **queue_data)

        # Defining IAM Role
        role = base_sqs_role(self, resource_name=queue_data["queue_name"], principal_resource="iot")

        # Validating Lambda Function Runtime
        functions_data = self._configuration["lambda_handlers"]
        self._lambda_functions = list()
        for lambda_function in functions_data:
            _lambda_function = base_lambda_function(self, **lambda_function)
            self._lambda_functions.append(_lambda_function)

            _lambda_function.add_event_source(lambda_sources.SqsEventSource(queue=self._sqs_queue, batch_size=10))

        # Defining Topic Rule properties
        action = iot.CfnTopicRule.SqsActionProperty(queue_url=self._sqs_queue.queue_url, role_arn=role.role_arn)
        action_property = iot.CfnTopicRule.ActionProperty(sqs=action)

        rule_data = self._configuration["iot_rule"]
        self._iot_rule = base_iot_rule(self, action_property=action_property, **rule_data)
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case APIGATEWAY_LAMBDA_SIMPLE_WEB_SERVICE_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(
            configuration_schema=APIGATEWAY_SIMPLE_WEB_SERVICE_SCHEMA,
            configuration_received=self._configuration)

        # Define S3 Buckets Cluster
        if isinstance(self._configuration.get("buckets"), list):
            self._s3_buckets = [
                base_bucket(self, **bucket)
                for bucket in self._configuration["buckets"]
            ]

        api_configuration = self._configuration["api"]

        # Define Lambda Authorizer Function
        authorizer_functions = api_configuration.get("authorizer_function")
        self._authorizer_function = None
        if authorizer_functions is not None:
            if authorizer_functions.get("imported") is not None:
                self._authorizer_function = lambda_.Function.from_function_arn(
                    self,
                    id=authorizer_functions.get("imported").get("identifier"),
                    function_arn=authorizer_functions.get("imported").get(
                        "arn"),
                )
            elif authorizer_functions.get("origin") is not None:
                self._authorizer_function = base_lambda_function(
                    self, **authorizer_functions.get("origin"))

        # Define API Gateway Authorizer
        gateway_authorizer = None
        if self._authorizer_function is not None:
            # Define Gateway Token Authorizer
            authorizer_name = api_configuration[
                "apigateway_name"] + "_" + "authorizer"
            if authorizer_functions.get("results_cache_ttl") is not None:
                results_cache_ttl = core.Duration.minutes(
                    authorizer_functions.get("results_cache_ttl"))
            else:
                results_cache_ttl = None
            gateway_authorizer = api_gateway.TokenAuthorizer(
                self,
                id=authorizer_name,
                authorizer_name=authorizer_name,
                handler=self._authorizer_function,
                results_cache_ttl=results_cache_ttl)

        # Defining Custom Domain
        domain_options = None
        custom_domain = api_configuration["root_resource"].get("custom_domain")
        if custom_domain is not None:
            domain_name = custom_domain["domain_name"]
            certificate_arn = custom_domain["certificate_arn"]
            domain_options = api_gateway.DomainNameOptions(
                certificate=cert_manager.Certificate.from_certificate_arn(
                    self, id=domain_name, certificate_arn=certificate_arn),
                domain_name=domain_name,
            )

        # Define API Gateway Lambda Handler
        self._handler_function = base_lambda_function(
            self, **api_configuration["root_resource"]["handler"])

        if api_configuration["proxy"] is False and api_configuration.get(
                "root_resource").get("methods") is None:
            print(
                "Unable to check which method to use for the API! Use proxy: True or define methods..."
            )
            raise RuntimeError

        self._lambda_rest_api = api_gateway.LambdaRestApi(
            self,
            id=api_configuration["apigateway_name"],
            rest_api_name=api_configuration["apigateway_name"],
            description=api_configuration["apigateway_description"],
            domain_name=domain_options,
            handler=self._handler_function,
            proxy=api_configuration["proxy"],
            cloud_watch_role=True,
        )

        # Add Custom responses
        self._lambda_rest_api.add_gateway_response(
            f"{self.prefix}_4XXresponse_{self.environment_}",
            type=api_gateway.ResponseType.DEFAULT_4_XX,
            response_headers={"Access-Control-Allow-Origin": "'*'"},
        )
        self._lambda_rest_api.add_gateway_response(
            f"{self.prefix}_5XXresponse_{self.environment_}",
            type=api_gateway.ResponseType.DEFAULT_5_XX,
            response_headers={"Access-Control-Allow-Origin": "'*'"},
        )

        # Define Gateway Resource and Methods
        resource = self._lambda_rest_api.root.add_resource(
            api_configuration["root_resource"]["name"])
        allowed_origins = api_configuration["root_resource"].get(
            "allowed_origins")
        if api_configuration["proxy"] is False:
            gateway_methods = api_configuration["root_resource"]["methods"]
            for method in gateway_methods:
                resource.add_method(http_method=method,
                                    authorizer=gateway_authorizer)

            if allowed_origins is not None:
                resource.add_cors_preflight(allow_origins=allowed_origins,
                                            allow_methods=gateway_methods)
        else:
            if allowed_origins is not None:
                resource.add_cors_preflight(allow_origins=allowed_origins)
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case APIGATEWAY_LAMBDA_SIMPLE_WEB_SERVICE_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(
            configuration_schema=APIGATEWAY_ASYNC_WEB_SERVICE_SCHEMA,
            configuration_received=self._configuration)
        # Define S3 Buckets Cluster
        if isinstance(self._configuration.get("buckets"), list):
            self._s3_buckets = [
                base_bucket(self, **bucket)
                for bucket in self._configuration["buckets"]
            ]

        api_configuration = self._configuration["api"]

        # Define Lambda Authorizer Function
        authorizer_functions = api_configuration.get("authorizer_function")
        self._authorizer_function = None
        if authorizer_functions is not None:
            if authorizer_functions.get("imported") is not None:
                self._authorizer_function = lambda_.Function.from_function_arn(
                    self,
                    id=authorizer_functions.get("imported").get("identifier"),
                    function_arn=authorizer_functions.get("imported").get(
                        "arn"),
                )
            elif authorizer_functions.get("origin") is not None:
                self._authorizer_function = base_lambda_function(
                    self, **authorizer_functions.get("origin"))

        # Define NEW-FUNCTION Lambda Authorizers
        for lambda_function in authorizer_functions["origin"]:
            try:
                function_runtime = getattr(lambda_.Runtime,
                                           lambda_function["runtime"])
            except Exception:
                raise WrongRuntimePassed(
                    detail=
                    f"Wrong function runtime {lambda_function['runtime']} specified",
                    tb=traceback.format_exc())

            obtainer_code_path = lambda_function.get("code_path")
            if obtainer_code_path is not None:
                code_path = obtainer_code_path
            elif obtainer_code_path is None and DEFAULT_LAMBDA_CODE_PATH_EXISTS is True:
                code_path = DEFAULT_LAMBDA_CODE_PATH
            else:
                raise RuntimeError(
                    f"Code path for Lambda Function {lambda_function['lambda_name']} is not valid!"
                )

            # Defining Lambda function
            _lambda_function = lambda_.Function(
                self,
                id=self.prefix + "_" + lambda_function["lambda_name"] +
                "_lambda_" + self.environment_,
                function_name=self.prefix + "_" +
                lambda_function["lambda_name"] + "_lambda_" +
                self.environment_,
                code=lambda_.Code.from_asset(path=code_path),
                handler=lambda_function["handler"],
                runtime=function_runtime,
                layers=None,
                description=lambda_function.get("description"),
                tracing=lambda_.Tracing.ACTIVE,
                environment=lambda_function.get("environment_vars"),
                timeout=core.Duration.seconds(lambda_function.get("timeout")),
                reserved_concurrent_executions=lambda_function.get(
                    "reserved_concurrent_executions"),
            )

            # Defining Lambda Function IAM policies to access other services
            self.iam_policies = list()
            for iam_actions in configuration["iam_actions"]:
                self.iam_policies.append(iam_actions)

            policy_statement = iam.PolicyStatement(actions=self.iam_policies,
                                                   resources=["*"])
            _lambda_function.add_to_role_policy(statement=policy_statement)
            self._authorizer_lambda_functions.append(_lambda_function)
Exemple #12
0
    def __init__(self, scope: core.Construct, id: str, *, prefix: str, environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case SNS_CONFIG_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(configuration_schema=USER_SERVERLESS_BACKEND_SCHEMA, configuration_received=self._configuration)

        # Define Lambda Authorizer Function
        authorizer_functions = self._configuration.get("authorizer_function")
        self._authorizer_function = None
        if authorizer_functions is not None:
            if authorizer_functions.get("imported") is not None:
                self._authorizer_function = lambda_.Function.from_function_arn(
                    self,
                    id=authorizer_functions.get("imported").get("identifier"),
                    function_arn=authorizer_functions.get("imported").get("arn"),
                )
            elif authorizer_functions.get("origin") is not None:
                self._authorizer_function = base_lambda_function(self, **authorizer_functions.get("origin"))

        # Define DynamoDB Tables
        self._dynamodb_tables_lambda_functions = list()
        for table in self._configuration.get("dynamo_tables", []):
            table, stream = base_dynamodb_table(self, **table)
            stream_lambda = None
            if stream is True and table["stream"].get("function") is not None:
                stream_lambda = base_lambda_function(self, **table["stream"]["function"])

                # Add DynamoDB Stream Trigger to Lambda Function
                stream_lambda.add_event_source(
                    source=event_sources.DynamoEventSource(
                        table=table, starting_position=lambda_.StartingPosition.TRIM_HORIZON, batch_size=1
                    )
                )

            self._dynamodb_tables_lambda_functions.append({"table": table, "stream_lambda": stream_lambda})

        # Define S3 Buckets Cluster
        if isinstance(self._configuration.get("buckets"), list):
            self._s3_buckets = [base_bucket(self, **bucket) for bucket in self._configuration["buckets"]]

        # Define Cognito User Pool
        user_pool_config = self._configuration["user_pool"]
        self._user_pool, self._user_pool_client = base_cognito_user_pool(self, **user_pool_config)

        if user_pool_config.get("identity_pool") is not None and self._user_pool_client is not None:
            self._identity_pool = base_cognito_user_identity_pool(
                self,
                user_pool_client_id=self._user_pool_client.user_pool_client_id,
                user_pool_provider_name=self._user_pool.user_pool_provider_name,
                **user_pool_config["identity_pool"],
            )
Exemple #13
0
    def set_authorizer(self):
        # Define API Gateway Authorizer
        gateway_authorizer = None

        api_configuration = self._configuration["api"]
        authorizer_configuration = api_configuration.get("authorizer")
        if authorizer_configuration is None:
            return gateway_authorizer

        authorizer_name = f"{self.prefix}_{api_configuration['apigateway_name']}_authorizer_{self.environment_}"

        token_authorizer_config = authorizer_configuration.get("token")
        request_authorizer_config = authorizer_configuration.get("request")
        cognito_authorizer_config = authorizer_configuration.get("cognito")

        authorizer_config = token_authorizer_config or request_authorizer_config or cognito_authorizer_config

        if token_authorizer_config or request_authorizer_config:
            # Define Lambda Authorizer Function
            authorizer_functions = authorizer_config.get("function")
            if authorizer_functions.get("imported") is not None:
                self._authorizer_function = lambda_.Function.from_function_arn(
                    self,
                    id=authorizer_functions.get("imported").get("identifier"),
                    function_arn=authorizer_functions.get("imported").get(
                        "arn"),
                )
            elif authorizer_functions.get("origin") is not None:
                self._authorizer_function = base_lambda_function(
                    self, **authorizer_functions.get("origin"))
            else:
                raise RuntimeError("Undefined function type used...")

            # Define Gateway Token or Request Authorizer
            if token_authorizer_config:
                authorizer = api_gateway.TokenAuthorizer
            elif request_authorizer_config:
                authorizer = api_gateway.RequestAuthorizer
            else:
                raise RuntimeError("Undefined authorizer configured...")

            if authorizer_functions.get("results_cache_ttl") is not None:
                results_cache_ttl = core.Duration.minutes(
                    authorizer_functions.get("results_cache_ttl"))
            else:
                results_cache_ttl = None

            gateway_authorizer = authorizer(
                self,
                id=authorizer_name,
                authorizer_name=authorizer_name,
                handler=self._authorizer_function,
                results_cache_ttl=results_cache_ttl)

        elif cognito_authorizer_config:
            authorizer = api_gateway.CognitoUserPoolsAuthorizer

            if cognito_authorizer_config.get("results_cache_ttl") is not None:
                results_cache_ttl = core.Duration.minutes(
                    cognito_authorizer_config.get("results_cache_ttl"))
            else:
                results_cache_ttl = None

            user_pools = list()
            for index, pool_id in enumerate(
                    cognito_authorizer_config.get("user_pool_ids")):
                cognito_pool = cognito.UserPool.from_user_pool_id(
                    self,
                    id=f"imported_pool_auth_{index}",
                    user_pool_id=pool_id)
                user_pools.append(cognito_pool)
            # user_pools = [
            #     cognito.UserPool.from_user_pool_id(self, id=f"imported_pool_auth_{pool_id}", user_pool_id=pool_id)
            #     for pool_id
            #     in cognito_authorizer_config.get("user_pool_ids")
            # ]

            gateway_authorizer = authorizer(
                self,
                id=authorizer_name,
                authorizer_name=authorizer_name,
                results_cache_ttl=results_cache_ttl,
                cognito_user_pools=user_pools)

        else:
            raise RuntimeError("Error undefined gateway authorizer used...")

        return gateway_authorizer
Exemple #14
0
    def __init__(self, scope: core.Construct, id: str, *, prefix: str,
                 environment: str, configuration, **kwargs):
        """
        :param scope: Stack class, used by CDK.
        :param id: ID of the construct, used by CDK.
        :param prefix: Prefix of the construct, used for naming purposes.
        :param environment: Environment of the construct, used for naming purposes.
        :param configuration: Configuration of the construct. In this case APIGATEWAY_LAMBDA_SIMPLE_WEB_SERVICE_SCHEMA.
        :param kwargs: Other parameters that could be used by the construct.
        """
        super().__init__(scope, id, **kwargs)
        self.prefix = prefix
        self.environment_ = environment
        self._configuration = configuration

        # Validating that the payload passed is correct
        validate_configuration(
            configuration_schema=APIGATEWAY_ROBUST_WEB_SERVICE_SCHEMA,
            configuration_received=self._configuration)
        # Define S3 Buckets Cluster
        if isinstance(self._configuration.get("buckets"), list):
            self._s3_buckets = [
                base_bucket(self, **bucket)
                for bucket in self._configuration["buckets"]
            ]

        api_configuration = self._configuration["api"]
        api_gateway_name = self.prefix + "_" + api_configuration[
            "apigateway_name"] + "_" + self.environment_
        api_gateway_name_description = api_configuration.get(
            "apigateway_description")

        # # Define Lambda Authorizer Function
        # authorizer_functions = api_configuration.get("authorizer_function")
        # self._authorizer_function = None
        # if authorizer_functions is not None:
        #     if authorizer_functions.get("imported") is not None:
        #         self._authorizer_function = lambda_.Function.from_function_arn(
        #             self,
        #             id=authorizer_functions.get("imported").get("identifier"),
        #             function_arn=authorizer_functions.get("imported").get("arn"),
        #         )
        #     elif authorizer_functions.get("origin") is not None:
        #         self._authorizer_function = base_lambda_function(self, **authorizer_functions.get("origin"))
        #
        # # Define API Gateway Authorizer
        # gateway_authorizer = None
        # if self._authorizer_function is not None:
        #     # Define Gateway Token Authorizer
        #     authorizer_name = api_configuration["apigateway_name"] + "_" + "authorizer"
        #     if authorizer_functions.get("results_cache_ttl") is not None:
        #         results_cache_ttl = core.Duration.minutes(authorizer_functions.get("results_cache_ttl"))
        #     else:
        #         results_cache_ttl = None
        #     gateway_authorizer = api_gateway.TokenAuthorizer(
        #         self,
        #         id=authorizer_name,
        #         authorizer_name=authorizer_name,
        #         handler=self._authorizer_function,
        #         results_cache_ttl=results_cache_ttl
        #     )
        #
        #     api_gateway.TokenAuthorizer
        #     api_gateway.RequestAuthorizer
        #     api_gateway.CognitoUserPoolsAuthorizer

        # Define API Gateway Authorizer
        self._authorizer_function = None
        self._gateway_authorizer = self.set_authorizer()

        # Defining Custom Domain
        domain_options = None
        custom_domain = api_configuration["settings"].get("custom_domain")
        if custom_domain is not None:
            domain_name = custom_domain["domain_name"]
            certificate_arn = custom_domain["certificate_arn"]
            domain_options = api_gateway.DomainNameOptions(
                certificate=cert_manager.Certificate.from_certificate_arn(
                    self, id=domain_name, certificate_arn=certificate_arn),
                domain_name=domain_name,
            )

        # Define API Gateway Lambda Handler
        self._handler_function = base_lambda_function(
            self, **api_configuration["settings"]["default_handler"])

        # Validating Proxy configuration for API Gateway
        proxy_configuration = api_configuration["settings"]["proxy"]
        if proxy_configuration is False and api_configuration["settings"].get(
                "default_http_methods") is None:
            print(
                "Unable to check which method to use for the API! Use proxy: True or define methods..."
            )
            raise RuntimeError

        # Defining allowed binary media types by API Gateway
        binary_media_types = api_configuration["settings"].get(
            "default_media_types")

        # Defining CORS preflight options
        default_cors_options = None
        default_cors_configuration = api_configuration["settings"].get(
            "default_cors_options")
        if default_cors_configuration is not None:
            default_cors_options = api_gateway.CorsOptions(
                allow_origins=default_cors_configuration["allow_origins"],
                allow_methods=["ANY"],
                status_code=default_cors_configuration["options_status_code"],
            )

        # Defining STAGE Options
        default_stage_options = None
        default_stage_configuration = api_configuration["settings"].get(
            "default_stage_options")
        if default_stage_configuration is not None:
            logging_level = api_gateway.MethodLoggingLevel.ERROR
            logging_level_configuration = default_stage_configuration[
                "logging_level"]
            for element in api_gateway.MethodLoggingLevel:
                if logging_level_configuration in str(element):
                    logging_level = element
            default_stage_options = api_gateway.StageOptions(
                logging_level=logging_level,
                metrics_enabled=default_stage_configuration["metrics_enabled"],
            )

        # Defining Rest API Gateway with Lambda Integration
        self._lambda_rest_api = api_gateway.LambdaRestApi(
            self,
            id=api_gateway_name,
            rest_api_name=api_gateway_name,
            description=api_gateway_name_description,
            domain_name=domain_options,
            handler=self._handler_function,
            proxy=proxy_configuration,
            binary_media_types=binary_media_types,
            default_cors_preflight_options=default_cors_options,
            cloud_watch_role=True,
            deploy_options=default_stage_options,
        )

        # Add Custom responses
        self._lambda_rest_api.add_gateway_response(
            f"{self.prefix}_4XXresponse_{self.environment_}",
            type=api_gateway.ResponseType.DEFAULT_4_XX,
            response_headers={"Access-Control-Allow-Origin": "'*'"},
        )
        self._lambda_rest_api.add_gateway_response(
            f"{self.prefix}_5XXresponse_{self.environment_}",
            type=api_gateway.ResponseType.DEFAULT_5_XX,
            response_headers={"Access-Control-Allow-Origin": "'*'"},
        )

        # Define API Gateway Root Methods
        root_methods = api_configuration["settings"].get(
            "default_http_methods", list())
        for method in root_methods:
            self._lambda_rest_api.root.add_method(
                http_method=method, authorizer=self._gateway_authorizer)

        # Defining Resource Trees for API Gateway with Custom Integrations
        resource_trees = api_configuration["resource_trees"]
        for resource_tree in resource_trees:
            resource_base = self._lambda_rest_api.root.add_resource(
                path_part=resource_tree["resource_name"])
            resource_base_handler = base_lambda_function(
                self, **resource_tree["handler"])
            for method in resource_tree["methods"]:
                resource_base.add_method(
                    http_method=method,
                    integration=api_gateway.LambdaIntegration(
                        handler=resource_base_handler),
                    authorizer=self._gateway_authorizer,
                )
            # resource_base.add_cors_preflight(allow_methods=resource_tree["methods"], allow_origins=["*"])

            resource_base_child_definition = resource_tree.get("child")
            if resource_base_child_definition is not None:
                resource_base_child = resource_base.add_resource(
                    path_part=resource_base_child_definition["resource_name"])
                resource_base_child_handler = base_lambda_function(
                    self, **resource_base_child_definition["handler"])
                for method in resource_base_child_definition["methods"]:
                    resource_base_child.add_method(
                        http_method=method,
                        integration=api_gateway.LambdaIntegration(
                            handler=resource_base_child_handler),
                        authorizer=self._gateway_authorizer,
                    )
                # resource_base_child.add_cors_preflight(
                #     allow_methods=resource_base_child_definition["methods"], allow_origins=["*"]
                # )

                resource_base_child_trees = resource_base_child_definition.get(
                    "childs", list())
                for resource_base_grandchild_tree in resource_base_child_trees:
                    resource_base_grandchild = resource_base_child.add_resource(
                        path_part=resource_base_grandchild_tree[
                            "resource_name"])
                    resource_base_grandchild_handler = base_lambda_function(
                        self, **resource_base_grandchild_tree["handler"])
                    for method in resource_base_grandchild_tree["methods"]:
                        resource_base_grandchild.add_method(
                            http_method=method,
                            integration=api_gateway.LambdaIntegration(
                                handler=resource_base_grandchild_handler),
                            authorizer=self._gateway_authorizer,
                        )