cdk-factory 0.9.12__tar.gz → 0.9.13__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cdk-factory might be problematic. Click here for more details.
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/PKG-INFO +1 -1
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/pyproject.toml +1 -1
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/run-tests.sh +10 -6
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/auto_scaling.py +27 -0
- cdk_factory-0.9.13/src/cdk_factory/configurations/resources/cloudfront.py +124 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/ecs_service.py +12 -0
- cdk_factory-0.9.13/src/cdk_factory/configurations/resources/lambda_edge.py +97 -0
- cdk_factory-0.9.13/src/cdk_factory/configurations/resources/monitoring.py +74 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/s3.py +3 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py +69 -1
- cdk_factory-0.9.13/src/cdk_factory/lambdas/edge/ip_gate/handler.py +104 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py +99 -0
- cdk_factory-0.9.13/src/cdk_factory/stack_library/cloudfront/__init__.py +6 -0
- cdk_factory-0.9.13/src/cdk_factory/stack_library/cloudfront/cloudfront_stack.py +627 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/ecs/ecs_service_stack.py +90 -0
- cdk_factory-0.9.13/src/cdk_factory/stack_library/lambda_edge/__init__.py +6 -0
- cdk_factory-0.9.13/src/cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py +258 -0
- cdk_factory-0.9.13/src/cdk_factory/stack_library/monitoring/__init__.py +6 -0
- cdk_factory-0.9.13/src/cdk_factory/stack_library/monitoring/monitoring_stack.py +492 -0
- cdk_factory-0.9.13/src/cdk_factory/version.py +1 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/workload/workload_factory.py +2 -0
- cdk_factory-0.9.12/src/cdk_factory/configurations/resources/cloudfront.py +0 -34
- cdk_factory-0.9.12/src/cdk_factory/version.py +0 -1
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/.gitignore +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/.windsurfrules +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/LICENSE +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/README.md +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/archive/README.md +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/archive/migrate_to_enhanced_ssm.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/examples/json-imports/README.md +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/examples/separate-api-gateway/README.md +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/examples/separate-api-gateway/api-gateway-stack.json +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/examples/separate-api-gateway/config.json +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/examples/separate-api-gateway/lambda-stack.json +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/mypy.ini +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/publish_to_pypi.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/publish_to_pypi.sh +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/pysetup.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/pysetup.sh +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/requirements.dev.txt +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/requirements.tests.txt +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/requirements.txt +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/run-checks.sh +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/run-tests-clean-venv.sh +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/app.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/builds/README.md +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/cdk.json +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/cli.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/commands/command_loader.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/base_config.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/cdk_config.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/deployment.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/deployment_wave.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/devops.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/enhanced_base_config.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/enhanced_ssm_config.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/management.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/pipeline.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/pipeline_stage.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/_resources.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/api_gateway.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/apigateway_route_config.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/cloudwatch_widget.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/code_artifact.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/code_artifact_login.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/code_repository.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/cognito.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/docker.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/dynamodb.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/ecr.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/exisiting.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/lambda_function.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/lambda_layers.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/lambda_triggers.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/load_balancer.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/rds.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/resource_mapping.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/resource_naming.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/resource_types.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/route53.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/route53_hosted_zone.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/rum.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/security_group.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/security_group_full_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/sqs.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/vpc.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/workload.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/ecr/ecr_construct.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/lambdas/lambda_function_construct.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/lambdas/lambda_function_docker_construct.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/lambdas/lambda_function_role_construct.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/lambdas/policies/policy_docs.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/lambdas/policies/policy_statements.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/s3_buckets/s3_bucket_construct.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_destination_construct.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/s3_buckets/s3_bucket_replication_source_construct.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/constructs/sqs/policies/sqs_policies.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/interfaces/istack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/interfaces/live_ssm_resolver.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/interfaces/ssm_parameter_mixin.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/lambdas/health_handler.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/pipeline/path_utils.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/pipeline/pipeline_factory.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/pipeline/security/policies.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/pipeline/security/roles.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/pipeline/stage.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack/istack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack/stack_factory.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack/stack_module_loader.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack/stack_module_registry.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack/stack_modules.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/api_gateway/api_gateway_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/auto_scaling/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/aws_lambdas/lambda_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/buckets/README.md +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/buckets/bucket_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/code_artifact/code_artifact_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/cognito/cognito_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/dynamodb/dynamodb_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/ecr/README.md +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/ecr/ecr_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/ecs/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/load_balancer/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/load_balancer/load_balancer_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/rds/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/rds/rds_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/route53/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/route53/route53_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/rum/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/rum/rum_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/security_group/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/security_group/security_group_full_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/security_group/security_group_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/simple_queue_service/sqs_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/stack_base.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/vpc/__init__.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/vpc/vpc_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stack_library/websites/static_website_stack.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/stages/websites/static_website_stage.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/templates/README.md +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/templates/app.py.template +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/templates/cdk.json.template +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/api_gateway_integration_utility.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/commandline_args.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/configuration_loader.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/docker_utilities.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/environment_services.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/file_operations.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/git_utilities.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/json_loading_utility.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/lambda_function_utilities.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utilities/os_execute.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/utils/api_gateway_utilities.py +0 -0
- {cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/handlers/test/handler.py +0 -0
|
@@ -24,15 +24,19 @@ echo "=================================="
|
|
|
24
24
|
if [ ! -d ".venv" ]; then
|
|
25
25
|
echo -e "${YELLOW}Creating virtual environment...${NC}"
|
|
26
26
|
python3 -m venv .venv
|
|
27
|
+
# Install dependencies
|
|
28
|
+
echo -e "${YELLOW}Installing dependencies...${NC}"
|
|
29
|
+
pip install -q -r requirements.dev.txt
|
|
30
|
+
pip install -q -r requirements.tests.txt
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# see if it's activated
|
|
34
|
+
if [ ! -f ".venv/bin/activate" ]; then
|
|
35
|
+
echo -e "${YELLOW}Activating virtual environment...${NC}"
|
|
36
|
+
source ./.venv/bin/activate
|
|
27
37
|
fi
|
|
28
38
|
|
|
29
|
-
echo -e "${YELLOW}Activating virtual environment...${NC}"
|
|
30
|
-
source ./.venv/bin/activate
|
|
31
39
|
|
|
32
|
-
# Install dependencies
|
|
33
|
-
echo -e "${YELLOW}Installing dependencies...${NC}"
|
|
34
|
-
pip install -q -r requirements.dev.txt
|
|
35
|
-
pip install -q -r requirements.tests.txt
|
|
36
40
|
|
|
37
41
|
# Check if pytest is installed in the virtual environment
|
|
38
42
|
if ! command -v pytest &> /dev/null; then
|
{cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/auto_scaling.py
RENAMED
|
@@ -148,3 +148,30 @@ class AutoScalingConfig(EnhancedBaseConfig):
|
|
|
148
148
|
def target_group_arns(self) -> List[str]:
|
|
149
149
|
"""Target group ARNs for the Auto Scaling Group"""
|
|
150
150
|
return self.__config.get("target_group_arns", [])
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def user_data_scripts(self) -> List[Dict[str, Any]]:
|
|
154
|
+
"""
|
|
155
|
+
User data scripts to inject from files.
|
|
156
|
+
Each script should have:
|
|
157
|
+
- type: 'file' or 'inline'
|
|
158
|
+
- path: path to script file (if type is 'file')
|
|
159
|
+
- content: script content (if type is 'inline')
|
|
160
|
+
- variables: dict of variables for substitution
|
|
161
|
+
"""
|
|
162
|
+
return self.__config.get("user_data_scripts", [])
|
|
163
|
+
|
|
164
|
+
@property
|
|
165
|
+
def iam_inline_policies(self) -> List[Dict[str, Any]]:
|
|
166
|
+
"""
|
|
167
|
+
IAM inline policies to attach to the instance role.
|
|
168
|
+
Each policy should have:
|
|
169
|
+
- name: policy name
|
|
170
|
+
- statements: list of IAM policy statements
|
|
171
|
+
"""
|
|
172
|
+
return self.__config.get("iam_inline_policies", [])
|
|
173
|
+
|
|
174
|
+
@property
|
|
175
|
+
def key_name(self) -> Optional[str]:
|
|
176
|
+
"""EC2 key pair name for SSH access"""
|
|
177
|
+
return self.__config.get("key_name")
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geek Cafe, LLC
|
|
3
|
+
Maintainers: Eric Wilson
|
|
4
|
+
MIT License. See Project Root for the license information.
|
|
5
|
+
"""
|
|
6
|
+
from typing import Dict, List, Any, Optional
|
|
7
|
+
from cdk_factory.configurations.enhanced_base_config import EnhancedBaseConfig
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CloudFrontConfig(EnhancedBaseConfig):
|
|
11
|
+
"""
|
|
12
|
+
CloudFront Distribution Configuration
|
|
13
|
+
Supports both S3 origins (static sites) and custom origins (ALB, API Gateway, etc.)
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
def __init__(self, config: dict = None, deployment=None) -> None:
|
|
17
|
+
super().__init__(
|
|
18
|
+
config or {},
|
|
19
|
+
resource_type="cloudfront",
|
|
20
|
+
resource_name=config.get("name", "cloudfront") if config else "cloudfront"
|
|
21
|
+
)
|
|
22
|
+
self._config = config or {}
|
|
23
|
+
self._deployment = deployment
|
|
24
|
+
|
|
25
|
+
@property
|
|
26
|
+
def name(self) -> str:
|
|
27
|
+
"""Distribution name"""
|
|
28
|
+
return self._config.get("name", "cloudfront")
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def description(self) -> str:
|
|
32
|
+
"""Distribution description"""
|
|
33
|
+
return self._config.get("description", "CloudFront Distribution")
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def comment(self) -> str:
|
|
37
|
+
"""Distribution comment"""
|
|
38
|
+
return self._config.get("comment", "")
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def enabled(self) -> bool:
|
|
42
|
+
"""Whether distribution is enabled"""
|
|
43
|
+
return self._config.get("enabled", True)
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def aliases(self) -> List[str]:
|
|
47
|
+
"""Alternate domain names (CNAMEs)"""
|
|
48
|
+
return self._config.get("aliases", [])
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def price_class(self) -> str:
|
|
52
|
+
"""Price class for edge locations"""
|
|
53
|
+
return self._config.get("price_class", "PriceClass_100")
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def http_version(self) -> str:
|
|
57
|
+
"""HTTP version (http2, http2_and_3)"""
|
|
58
|
+
return self._config.get("http_version", "http2_and_3")
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def certificate(self) -> Optional[Dict[str, Any]]:
|
|
62
|
+
"""ACM certificate configuration"""
|
|
63
|
+
return self._config.get("certificate")
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def origins(self) -> List[Dict[str, Any]]:
|
|
67
|
+
"""Origin configurations"""
|
|
68
|
+
return self._config.get("origins", [])
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def default_cache_behavior(self) -> Dict[str, Any]:
|
|
72
|
+
"""Default cache behavior"""
|
|
73
|
+
return self._config.get("default_cache_behavior", {})
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def cache_behaviors(self) -> List[Dict[str, Any]]:
|
|
77
|
+
"""Additional cache behaviors"""
|
|
78
|
+
return self._config.get("cache_behaviors", [])
|
|
79
|
+
|
|
80
|
+
@property
|
|
81
|
+
def custom_error_responses(self) -> List[Dict[str, Any]]:
|
|
82
|
+
"""Custom error responses"""
|
|
83
|
+
return self._config.get("custom_error_responses", [])
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def logging(self) -> Optional[Dict[str, Any]]:
|
|
87
|
+
"""Logging configuration"""
|
|
88
|
+
return self._config.get("logging")
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
def waf_web_acl_id(self) -> Optional[str]:
|
|
92
|
+
"""WAF Web ACL ID"""
|
|
93
|
+
return self._config.get("waf_web_acl_id")
|
|
94
|
+
|
|
95
|
+
@property
|
|
96
|
+
def default_root_object(self) -> str:
|
|
97
|
+
"""Default root object"""
|
|
98
|
+
return self._config.get("default_root_object", "index.html")
|
|
99
|
+
|
|
100
|
+
@property
|
|
101
|
+
def tags(self) -> Dict[str, str]:
|
|
102
|
+
"""Resource tags"""
|
|
103
|
+
return self._config.get("tags", {})
|
|
104
|
+
|
|
105
|
+
@property
|
|
106
|
+
def ssm_exports(self) -> Dict[str, str]:
|
|
107
|
+
"""SSM parameter exports"""
|
|
108
|
+
return self._config.get("ssm_exports", {})
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def ssm_imports(self) -> Dict[str, str]:
|
|
112
|
+
"""SSM parameter imports"""
|
|
113
|
+
return self._config.get("ssm_imports", {})
|
|
114
|
+
|
|
115
|
+
@property
|
|
116
|
+
def hosted_zone_id(self) -> str:
|
|
117
|
+
"""
|
|
118
|
+
Returns the hosted_zone_id for cloudfront
|
|
119
|
+
Use this when making dns changes when you want your custom domain
|
|
120
|
+
to be route through cloudfront.
|
|
121
|
+
|
|
122
|
+
As far as I know this Id is static and used for all of cloudfront
|
|
123
|
+
"""
|
|
124
|
+
return self._config.get("hosted_zone_id", "Z2FDTNDATAQYW2")
|
{cdk_factory-0.9.12 → cdk_factory-0.9.13}/src/cdk_factory/configurations/resources/ecs_service.py
RENAMED
|
@@ -142,3 +142,15 @@ class EcsServiceConfig:
|
|
|
142
142
|
def is_maintenance_mode(self) -> bool:
|
|
143
143
|
"""Whether this is a maintenance mode deployment"""
|
|
144
144
|
return self.deployment_type == "maintenance"
|
|
145
|
+
|
|
146
|
+
@property
|
|
147
|
+
def volumes(self) -> List[Dict[str, Any]]:
|
|
148
|
+
"""
|
|
149
|
+
Volume definitions for the task.
|
|
150
|
+
Supports host volumes for EC2 launch type and EFS volumes.
|
|
151
|
+
Each volume should have:
|
|
152
|
+
- name: volume name
|
|
153
|
+
- host: {source_path: "/path/on/host"} for bind mounts
|
|
154
|
+
- efs: {...} for EFS volumes
|
|
155
|
+
"""
|
|
156
|
+
return self.task_definition.get("volumes", [])
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Lambda@Edge Configuration for CDK-Factory
|
|
3
|
+
Geek Cafe, LLC
|
|
4
|
+
Maintainers: Eric Wilson
|
|
5
|
+
MIT License. See Project Root for the license information.
|
|
6
|
+
"""
|
|
7
|
+
from typing import Dict, Optional
|
|
8
|
+
from cdk_factory.configurations.enhanced_base_config import EnhancedBaseConfig
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class LambdaEdgeConfig(EnhancedBaseConfig):
|
|
12
|
+
"""
|
|
13
|
+
Configuration class for Lambda@Edge functions.
|
|
14
|
+
Lambda@Edge has specific constraints:
|
|
15
|
+
- Must be deployed in us-east-1
|
|
16
|
+
- Max timeout: 5 seconds for origin-request/response, 30s for viewer-request/response
|
|
17
|
+
- Max memory: 10GB (but typically use 128-512MB for edge functions)
|
|
18
|
+
- Must use versioned functions (not $LATEST)
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
def __init__(self, config: dict = None, deployment=None) -> None:
|
|
22
|
+
super().__init__(
|
|
23
|
+
config or {},
|
|
24
|
+
resource_type="lambda_edge",
|
|
25
|
+
resource_name=config.get("name", "lambda-edge") if config else "lambda-edge"
|
|
26
|
+
)
|
|
27
|
+
self._config = config or {}
|
|
28
|
+
self._deployment = deployment
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def name(self) -> str:
|
|
32
|
+
"""Function name"""
|
|
33
|
+
return self._config.get("name", "lambda-edge")
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def handler(self) -> str:
|
|
37
|
+
"""Handler function (e.g., 'handler.lambda_handler')"""
|
|
38
|
+
return self._config.get("handler", "handler.lambda_handler")
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def runtime(self) -> str:
|
|
42
|
+
"""Lambda runtime (e.g., 'python3.11')"""
|
|
43
|
+
return self._config.get("runtime", "python3.11")
|
|
44
|
+
|
|
45
|
+
@property
|
|
46
|
+
def memory_size(self) -> int:
|
|
47
|
+
"""Memory size in MB (128-10240)"""
|
|
48
|
+
return int(self._config.get("memory_size", 128))
|
|
49
|
+
|
|
50
|
+
@property
|
|
51
|
+
def timeout(self) -> int:
|
|
52
|
+
"""Timeout in seconds (max 5 for origin-request)"""
|
|
53
|
+
timeout = int(self._config.get("timeout", 5))
|
|
54
|
+
if timeout > 5:
|
|
55
|
+
raise ValueError("Lambda@Edge origin-request timeout cannot exceed 5 seconds")
|
|
56
|
+
return timeout
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def code_path(self) -> str:
|
|
60
|
+
"""Path to Lambda function code directory"""
|
|
61
|
+
return self._config.get("code_path", "./lambdas/edge/ip_gate")
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def environment(self) -> Dict[str, str]:
|
|
65
|
+
"""Environment variables for the Lambda function"""
|
|
66
|
+
return self._config.get("environment", {})
|
|
67
|
+
|
|
68
|
+
@property
|
|
69
|
+
def description(self) -> str:
|
|
70
|
+
"""Function description"""
|
|
71
|
+
return self._config.get("description", "Lambda@Edge function")
|
|
72
|
+
|
|
73
|
+
@property
|
|
74
|
+
def event_type(self) -> str:
|
|
75
|
+
"""
|
|
76
|
+
Lambda@Edge event type:
|
|
77
|
+
- viewer-request: Executes when CloudFront receives a request from viewer
|
|
78
|
+
- origin-request: Executes before CloudFront forwards request to origin
|
|
79
|
+
- origin-response: Executes after CloudFront receives response from origin
|
|
80
|
+
- viewer-response: Executes before CloudFront returns response to viewer
|
|
81
|
+
"""
|
|
82
|
+
return self._config.get("event_type", "origin-request")
|
|
83
|
+
|
|
84
|
+
@property
|
|
85
|
+
def publish_version(self) -> bool:
|
|
86
|
+
"""Whether to publish a new version (required for Lambda@Edge)"""
|
|
87
|
+
return self._config.get("publish_version", True)
|
|
88
|
+
|
|
89
|
+
@property
|
|
90
|
+
def include_body(self) -> bool:
|
|
91
|
+
"""Whether to include request body in origin-request events"""
|
|
92
|
+
return self._config.get("include_body", False)
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def tags(self) -> Dict[str, str]:
|
|
96
|
+
"""Tags to apply to the Lambda function"""
|
|
97
|
+
return self._config.get("tags", {})
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Monitoring Configuration
|
|
3
|
+
Geek Cafe, LLC
|
|
4
|
+
Maintainers: Eric Wilson
|
|
5
|
+
MIT License. See Project Root for the license information.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Dict, List, Any, Optional
|
|
9
|
+
from cdk_factory.configurations.enhanced_base_config import EnhancedBaseConfig
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class MonitoringConfig(EnhancedBaseConfig):
|
|
13
|
+
"""
|
|
14
|
+
Monitoring Configuration for CloudWatch Alarms and Dashboards
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
def __init__(self, config: dict = None, deployment=None) -> None:
|
|
18
|
+
super().__init__(
|
|
19
|
+
config or {},
|
|
20
|
+
resource_type="monitoring",
|
|
21
|
+
resource_name=config.get("name", "monitoring") if config else "monitoring"
|
|
22
|
+
)
|
|
23
|
+
self._config = config or {}
|
|
24
|
+
self._deployment = deployment
|
|
25
|
+
|
|
26
|
+
@property
|
|
27
|
+
def name(self) -> str:
|
|
28
|
+
"""Monitoring stack name"""
|
|
29
|
+
return self._config.get("name", "monitoring")
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def sns_topics(self) -> List[Dict[str, Any]]:
|
|
33
|
+
"""SNS topics for alarm notifications"""
|
|
34
|
+
return self._config.get("sns_topics", [])
|
|
35
|
+
|
|
36
|
+
@property
|
|
37
|
+
def alarms(self) -> List[Dict[str, Any]]:
|
|
38
|
+
"""CloudWatch alarms configuration"""
|
|
39
|
+
return self._config.get("alarms", [])
|
|
40
|
+
|
|
41
|
+
@property
|
|
42
|
+
def dashboards(self) -> List[Dict[str, Any]]:
|
|
43
|
+
"""CloudWatch dashboards configuration"""
|
|
44
|
+
return self._config.get("dashboards", [])
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def composite_alarms(self) -> List[Dict[str, Any]]:
|
|
48
|
+
"""Composite alarms (combine multiple alarms)"""
|
|
49
|
+
return self._config.get("composite_alarms", [])
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def log_metric_filters(self) -> List[Dict[str, Any]]:
|
|
53
|
+
"""CloudWatch Logs metric filters"""
|
|
54
|
+
return self._config.get("log_metric_filters", [])
|
|
55
|
+
|
|
56
|
+
@property
|
|
57
|
+
def enable_anomaly_detection(self) -> bool:
|
|
58
|
+
"""Enable CloudWatch anomaly detection"""
|
|
59
|
+
return self._config.get("enable_anomaly_detection", False)
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def tags(self) -> Dict[str, str]:
|
|
63
|
+
"""Resource tags"""
|
|
64
|
+
return self._config.get("tags", {})
|
|
65
|
+
|
|
66
|
+
@property
|
|
67
|
+
def ssm_exports(self) -> Dict[str, str]:
|
|
68
|
+
"""SSM parameter exports"""
|
|
69
|
+
return self._config.get("ssm_exports", {})
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def ssm_imports(self) -> Dict[str, str]:
|
|
73
|
+
"""SSM parameter imports for resource ARNs"""
|
|
74
|
+
return self._config.get("ssm_imports", {})
|
|
@@ -123,6 +123,9 @@ class S3BucketConfig(EnhancedBaseConfig):
|
|
|
123
123
|
def removal_policy(self) -> cdk.RemovalPolicy:
|
|
124
124
|
"""The Removal policy"""
|
|
125
125
|
value = self.config.get("removal_policy", "retain")
|
|
126
|
+
if isinstance(value, str):
|
|
127
|
+
value = value.lower()
|
|
128
|
+
|
|
126
129
|
if value == "destroy":
|
|
127
130
|
return cdk.RemovalPolicy.DESTROY
|
|
128
131
|
elif value == "snapshot":
|
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
from typing import Any, List, Mapping
|
|
1
|
+
from typing import Any, List, Mapping, Optional
|
|
2
2
|
|
|
3
3
|
from aws_cdk import Duration
|
|
4
4
|
from aws_cdk import aws_certificatemanager as acm
|
|
5
5
|
from aws_cdk import aws_cloudfront as cloudfront
|
|
6
6
|
from aws_cdk import aws_cloudfront_origins as origins
|
|
7
7
|
from aws_cdk import aws_iam as iam
|
|
8
|
+
from aws_cdk import aws_lambda as _lambda
|
|
8
9
|
from aws_cdk import aws_s3 as s3
|
|
10
|
+
from aws_cdk import aws_ssm as ssm
|
|
11
|
+
from aws_lambda_powertools import Logger
|
|
9
12
|
from constructs import Construct
|
|
10
13
|
from cdk_factory.configurations.stack import StackConfig
|
|
11
14
|
|
|
15
|
+
logger = Logger(__name__)
|
|
16
|
+
|
|
12
17
|
|
|
13
18
|
class CloudFrontDistributionConstruct(Construct):
|
|
14
19
|
"""
|
|
@@ -123,6 +128,7 @@ class CloudFrontDistributionConstruct(Construct):
|
|
|
123
128
|
origin=origin,
|
|
124
129
|
viewer_protocol_policy=cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
|
|
125
130
|
function_associations=self.__get_function_associations(),
|
|
131
|
+
edge_lambdas=self.__get_lambda_edge_associations(),
|
|
126
132
|
),
|
|
127
133
|
default_root_object="index.html",
|
|
128
134
|
error_responses=self._error_responses(),
|
|
@@ -218,6 +224,68 @@ class CloudFrontDistributionConstruct(Construct):
|
|
|
218
224
|
|
|
219
225
|
return function_associations
|
|
220
226
|
|
|
227
|
+
def __get_lambda_edge_associations(self) -> Optional[List[cloudfront.EdgeLambda]]:
|
|
228
|
+
"""
|
|
229
|
+
Get the Lambda@Edge associations for the distribution from config.
|
|
230
|
+
|
|
231
|
+
Returns:
|
|
232
|
+
List[cloudfront.EdgeLambda] or None: list of Lambda@Edge associations
|
|
233
|
+
"""
|
|
234
|
+
edge_lambdas = []
|
|
235
|
+
|
|
236
|
+
if self.stack_config and isinstance(self.stack_config, StackConfig):
|
|
237
|
+
cloudfront_config = self.stack_config.dictionary.get("cloudfront", {})
|
|
238
|
+
lambda_edge_associations = cloudfront_config.get("lambda_edge_associations", [])
|
|
239
|
+
|
|
240
|
+
for association in lambda_edge_associations:
|
|
241
|
+
event_type_str = association.get("event_type", "origin-request")
|
|
242
|
+
lambda_arn = association.get("lambda_arn")
|
|
243
|
+
include_body = association.get("include_body", False)
|
|
244
|
+
|
|
245
|
+
if not lambda_arn:
|
|
246
|
+
continue # Skip if no ARN provided
|
|
247
|
+
|
|
248
|
+
# Check if ARN is an SSM parameter reference
|
|
249
|
+
if lambda_arn.startswith("{{ssm:") and lambda_arn.endswith("}}"):
|
|
250
|
+
ssm_param_path = lambda_arn[6:-2] # Extract parameter path
|
|
251
|
+
logger.info(f"Importing Lambda ARN from SSM parameter: {ssm_param_path}")
|
|
252
|
+
|
|
253
|
+
# Import SSM parameter - this creates a reference that resolves at deployment time
|
|
254
|
+
param = ssm.StringParameter.from_string_parameter_name(
|
|
255
|
+
self,
|
|
256
|
+
f"lambda-edge-arn-{hash(ssm_param_path) % 10000}",
|
|
257
|
+
ssm_param_path
|
|
258
|
+
)
|
|
259
|
+
lambda_arn = param.string_value
|
|
260
|
+
logger.info(f"Lambda ARN will be resolved from SSM: {ssm_param_path}")
|
|
261
|
+
|
|
262
|
+
# Map event type string to CloudFront enum
|
|
263
|
+
event_type_map = {
|
|
264
|
+
"viewer-request": cloudfront.LambdaEdgeEventType.VIEWER_REQUEST,
|
|
265
|
+
"origin-request": cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST,
|
|
266
|
+
"origin-response": cloudfront.LambdaEdgeEventType.ORIGIN_RESPONSE,
|
|
267
|
+
"viewer-response": cloudfront.LambdaEdgeEventType.VIEWER_RESPONSE,
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
event_type = event_type_map.get(event_type_str, cloudfront.LambdaEdgeEventType.ORIGIN_REQUEST)
|
|
271
|
+
|
|
272
|
+
# Import the Lambda function version by ARN
|
|
273
|
+
lambda_version = _lambda.Version.from_version_arn(
|
|
274
|
+
self,
|
|
275
|
+
f"LambdaEdge-{event_type_str}",
|
|
276
|
+
version_arn=lambda_arn
|
|
277
|
+
)
|
|
278
|
+
|
|
279
|
+
edge_lambdas.append(
|
|
280
|
+
cloudfront.EdgeLambda(
|
|
281
|
+
function_version=lambda_version,
|
|
282
|
+
event_type=event_type,
|
|
283
|
+
include_body=include_body
|
|
284
|
+
)
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
return edge_lambdas if edge_lambdas else None
|
|
288
|
+
|
|
221
289
|
def __get_combined_function(self, hosts: List[str]) -> cloudfront.Function:
|
|
222
290
|
"""
|
|
223
291
|
Creates a combined CloudFront function that does both URL rewriting and host restrictions.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Lambda@Edge Origin-Request Handler for IP-based Access Gating
|
|
3
|
+
Geek Cafe, LLC
|
|
4
|
+
Maintainers: Eric Wilson
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import ipaddress
|
|
8
|
+
import json
|
|
9
|
+
import os
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def lambda_handler(event, context):
|
|
13
|
+
"""
|
|
14
|
+
Lambda@Edge origin-request handler that implements IP-based gating
|
|
15
|
+
with maintenance site fallback.
|
|
16
|
+
|
|
17
|
+
Features:
|
|
18
|
+
- Inject X-Viewer-IP header for origin visibility
|
|
19
|
+
- Check viewer IP against allowlist when gate is enabled
|
|
20
|
+
- Rewrite blocked IPs to maintenance CloudFront distribution, and serve up maintenance site
|
|
21
|
+
- Toggle via GATE_ENABLED environment variable
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
# Extract request from CloudFront event
|
|
25
|
+
request = event['Records'][0]['cf']['request']
|
|
26
|
+
client_ip = request['clientIp']
|
|
27
|
+
|
|
28
|
+
# Configuration from environment variables
|
|
29
|
+
gate_enabled = os.environ.get('GATE_ENABLED', 'false').lower() == 'true'
|
|
30
|
+
allow_cidrs_str = os.environ.get('ALLOW_CIDRS', '')
|
|
31
|
+
maint_cf_host = os.environ.get('MAINT_CF_HOST', '')
|
|
32
|
+
|
|
33
|
+
# Parse allowed CIDRs
|
|
34
|
+
allow_cidrs = [cidr.strip() for cidr in allow_cidrs_str.split(',') if cidr.strip()]
|
|
35
|
+
|
|
36
|
+
# Always inject viewer IP header
|
|
37
|
+
if 'headers' not in request:
|
|
38
|
+
request['headers'] = {}
|
|
39
|
+
|
|
40
|
+
request['headers']['x-viewer-ip'] = [{
|
|
41
|
+
'key': 'X-Viewer-IP',
|
|
42
|
+
'value': client_ip
|
|
43
|
+
}]
|
|
44
|
+
|
|
45
|
+
# If gate is disabled, pass through to origin
|
|
46
|
+
if not gate_enabled:
|
|
47
|
+
return request
|
|
48
|
+
|
|
49
|
+
# Check if IP is in allowlist
|
|
50
|
+
ip_allowed = False
|
|
51
|
+
try:
|
|
52
|
+
client_ip_obj = ipaddress.ip_address(client_ip)
|
|
53
|
+
for cidr in allow_cidrs:
|
|
54
|
+
try:
|
|
55
|
+
network = ipaddress.ip_network(cidr, strict=False)
|
|
56
|
+
if client_ip_obj in network:
|
|
57
|
+
ip_allowed = True
|
|
58
|
+
break
|
|
59
|
+
except (ValueError, ipaddress.AddressValueError):
|
|
60
|
+
# Invalid CIDR, skip
|
|
61
|
+
continue
|
|
62
|
+
except (ValueError, ipaddress.AddressValueError):
|
|
63
|
+
# Invalid client IP, block by default
|
|
64
|
+
ip_allowed = False
|
|
65
|
+
|
|
66
|
+
# If IP is allowed, pass through to origin
|
|
67
|
+
if ip_allowed:
|
|
68
|
+
return request
|
|
69
|
+
|
|
70
|
+
# IP not allowed - redirect to maintenance site
|
|
71
|
+
if not maint_cf_host:
|
|
72
|
+
# Safety: if maintenance host not configured, pass through with warning
|
|
73
|
+
# In production, you might want to return a fixed error response instead
|
|
74
|
+
return request
|
|
75
|
+
|
|
76
|
+
# Rewrite origin to maintenance CloudFront distribution
|
|
77
|
+
request['origin'] = {
|
|
78
|
+
'custom': {
|
|
79
|
+
'domainName': maint_cf_host,
|
|
80
|
+
'port': 443,
|
|
81
|
+
'protocol': 'https',
|
|
82
|
+
'path': '',
|
|
83
|
+
'sslProtocols': ['TLSv1.2'],
|
|
84
|
+
'readTimeout': 30,
|
|
85
|
+
'keepaliveTimeout': 5,
|
|
86
|
+
'customHeaders': {}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
# Update Host header to match new origin
|
|
91
|
+
request['headers']['host'] = [{
|
|
92
|
+
'key': 'Host',
|
|
93
|
+
'value': maint_cf_host
|
|
94
|
+
}]
|
|
95
|
+
|
|
96
|
+
# Normalize URI - redirect directory requests to index.html
|
|
97
|
+
uri = request.get('uri', '/')
|
|
98
|
+
if uri.endswith('/'):
|
|
99
|
+
request['uri'] = uri + 'index.html'
|
|
100
|
+
elif '.' not in uri.split('/')[-1]:
|
|
101
|
+
# No file extension, likely a directory
|
|
102
|
+
request['uri'] = uri + '/index.html'
|
|
103
|
+
|
|
104
|
+
return request
|