cdk-factory 0.8.0__py3-none-any.whl → 0.8.2__py3-none-any.whl
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/configurations/enhanced_ssm_config.py +3 -1
- cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py +30 -19
- cdk_factory/stack_library/api_gateway/api_gateway_stack.py +20 -1
- cdk_factory/utilities/api_gateway_integration_utility.py +7 -0
- cdk_factory/utilities/json_loading_utility.py +55 -27
- cdk_factory/version.py +1 -1
- {cdk_factory-0.8.0.dist-info → cdk_factory-0.8.2.dist-info}/METADATA +1 -1
- {cdk_factory-0.8.0.dist-info → cdk_factory-0.8.2.dist-info}/RECORD +10 -10
- {cdk_factory-0.8.0.dist-info → cdk_factory-0.8.2.dist-info}/WHEEL +0 -0
- {cdk_factory-0.8.0.dist-info → cdk_factory-0.8.2.dist-info}/licenses/LICENSE +0 -0
|
@@ -86,7 +86,9 @@ class EnhancedSsmConfig:
|
|
|
86
86
|
self, attribute: str, custom_path: Optional[str] = None
|
|
87
87
|
) -> str:
|
|
88
88
|
"""Generate SSM parameter path using pattern or custom path"""
|
|
89
|
-
|
|
89
|
+
# Handle custom_path - must be a string starting with "/"
|
|
90
|
+
# Protect against incorrect config like: "exports": {"enabled": true}
|
|
91
|
+
if custom_path and isinstance(custom_path, str) and custom_path.startswith("/"):
|
|
90
92
|
return custom_path
|
|
91
93
|
|
|
92
94
|
# Convert underscore attribute names to hyphen format for consistent SSM paths
|
|
@@ -142,28 +142,39 @@ class EnhancedSsmParameterMixin:
|
|
|
142
142
|
Returns:
|
|
143
143
|
Created SSM parameter
|
|
144
144
|
"""
|
|
145
|
-
# Handle different value types
|
|
146
|
-
if isinstance(value, list):
|
|
147
|
-
string_value = ",".join(str(v) for v in value)
|
|
148
|
-
cdk_param_type = ssm.ParameterType.STRING_LIST
|
|
149
|
-
elif param_type == "SecureString":
|
|
150
|
-
string_value = str(value)
|
|
151
|
-
cdk_param_type = ssm.ParameterType.SECURE_STRING
|
|
152
|
-
else:
|
|
153
|
-
string_value = str(value)
|
|
154
|
-
cdk_param_type = ssm.ParameterType.STRING
|
|
155
|
-
|
|
156
145
|
# Generate a unique construct ID from the path
|
|
157
146
|
construct_id = f"ssm-param-{path.replace('/', '-').replace('_', '-')}"
|
|
158
147
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
148
|
+
# Handle different value types - use appropriate CDK constructs
|
|
149
|
+
if isinstance(value, list):
|
|
150
|
+
# For list values, use StringListParameter
|
|
151
|
+
return ssm.StringListParameter(
|
|
152
|
+
self.scope,
|
|
153
|
+
construct_id,
|
|
154
|
+
parameter_name=path,
|
|
155
|
+
string_list_value=value,
|
|
156
|
+
description=description
|
|
157
|
+
)
|
|
158
|
+
elif param_type == "SecureString":
|
|
159
|
+
# For secure strings, use L1 CfnParameter with Type=SecureString
|
|
160
|
+
return ssm.CfnParameter(
|
|
161
|
+
self.scope,
|
|
162
|
+
construct_id,
|
|
163
|
+
name=path,
|
|
164
|
+
value=str(value),
|
|
165
|
+
type="SecureString",
|
|
166
|
+
description=description
|
|
167
|
+
)
|
|
168
|
+
else:
|
|
169
|
+
# For regular strings, use StringParameter (no type parameter needed in CDK v2)
|
|
170
|
+
return ssm.StringParameter(
|
|
171
|
+
self.scope,
|
|
172
|
+
construct_id,
|
|
173
|
+
parameter_name=path,
|
|
174
|
+
string_value=str(value),
|
|
175
|
+
description=description
|
|
176
|
+
# Note: 'type' parameter removed - deprecated in CDK v2
|
|
177
|
+
)
|
|
167
178
|
|
|
168
179
|
def _import_enhanced_ssm_parameter(self, path: str, attribute: str) -> Optional[str]:
|
|
169
180
|
"""
|
|
@@ -304,9 +304,28 @@ class ApiGatewayStack(IStack, EnhancedSsmParameterMixin):
|
|
|
304
304
|
)
|
|
305
305
|
|
|
306
306
|
def _setup_cognito_authorizer(self, api_gateway, api_id):
|
|
307
|
-
"""Setup Cognito authorizer if configured"""
|
|
307
|
+
"""Setup Cognito authorizer if configured AND if any routes need it"""
|
|
308
308
|
if not self.api_config.cognito_authorizer:
|
|
309
309
|
return None
|
|
310
|
+
|
|
311
|
+
# Check if any routes actually need the authorizer
|
|
312
|
+
# Don't create it if all routes are public (authorization_type: NONE)
|
|
313
|
+
routes = self.api_config.routes or []
|
|
314
|
+
needs_authorizer = any(
|
|
315
|
+
route.get("authorization_type") != "NONE"
|
|
316
|
+
for route in routes
|
|
317
|
+
)
|
|
318
|
+
|
|
319
|
+
# If we're not creating an authorizer but Cognito is configured,
|
|
320
|
+
# inform the integration utility so it can still perform security validations
|
|
321
|
+
if not needs_authorizer:
|
|
322
|
+
logger.info(
|
|
323
|
+
"Cognito authorizer configured but no routes require authorization. "
|
|
324
|
+
"Skipping authorizer creation but maintaining security validation context."
|
|
325
|
+
)
|
|
326
|
+
# Set a flag so the integration utility knows Cognito was available
|
|
327
|
+
self.integration_utility.cognito_configured = True
|
|
328
|
+
return None
|
|
310
329
|
|
|
311
330
|
route_config = ApiGatewayConfigRouteConfig({})
|
|
312
331
|
return self.integration_utility.get_or_create_authorizer(
|
|
@@ -40,6 +40,7 @@ class ApiGatewayIntegrationUtility:
|
|
|
40
40
|
self.account = scope.account
|
|
41
41
|
self.api_gateway = None
|
|
42
42
|
self.authorizer = None
|
|
43
|
+
self.cognito_configured = False # Flag for when Cognito is configured but authorizer not created
|
|
43
44
|
self._log_group = None
|
|
44
45
|
self._log_role = None
|
|
45
46
|
|
|
@@ -55,8 +56,10 @@ class ApiGatewayIntegrationUtility:
|
|
|
55
56
|
raise ValueError("API Gateway config is missing in Lambda function config")
|
|
56
57
|
|
|
57
58
|
# Validate authorization configuration for security
|
|
59
|
+
# Check if Cognito is available (either authorizer created OR configured but not created)
|
|
58
60
|
has_cognito_authorizer = (
|
|
59
61
|
self.authorizer is not None
|
|
62
|
+
or self.cognito_configured
|
|
60
63
|
or self._get_existing_authorizer_id_with_ssm_fallback(
|
|
61
64
|
api_config, stack_config
|
|
62
65
|
)
|
|
@@ -614,6 +617,10 @@ class ApiGatewayIntegrationUtility:
|
|
|
614
617
|
authorizer_name=authorizer_name,
|
|
615
618
|
identity_source=identity_source,
|
|
616
619
|
)
|
|
620
|
+
|
|
621
|
+
# The authorizer is automatically attached to the API Gateway when used in a method
|
|
622
|
+
# But we need to ensure it's created in the context of the API's scope
|
|
623
|
+
# The actual attachment happens when the authorizer is referenced in method creation
|
|
617
624
|
|
|
618
625
|
return self.authorizer
|
|
619
626
|
|
|
@@ -61,35 +61,63 @@ class JsonLoadingUtility:
|
|
|
61
61
|
"""Resolve references in a configuration section."""
|
|
62
62
|
if isinstance(section, dict):
|
|
63
63
|
if self.nested_key in section:
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
elif
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
64
|
+
nested_paths = section.pop(self.nested_key)
|
|
65
|
+
|
|
66
|
+
# Support both single path (string) and multiple paths (list)
|
|
67
|
+
if isinstance(nested_paths, str):
|
|
68
|
+
nested_paths = [nested_paths]
|
|
69
|
+
elif not isinstance(nested_paths, list):
|
|
70
|
+
raise ValueError(f"__inherits__ must be a string or list, got {type(nested_paths)}")
|
|
71
|
+
|
|
72
|
+
# Process each path and merge results
|
|
73
|
+
merged_section = None
|
|
74
|
+
|
|
75
|
+
for nested_path in nested_paths:
|
|
76
|
+
nested_path = str(nested_path)
|
|
77
|
+
# print(f"Resolving parent path: {nested_path}")
|
|
78
|
+
|
|
79
|
+
if nested_path.endswith(".json"):
|
|
80
|
+
nested_root_path = os.path.join(self.base_path, nested_path)
|
|
81
|
+
nested_section = self.__load_json_file(nested_root_path)
|
|
82
|
+
elif os.path.isdir(os.path.join(self.base_path, nested_path)):
|
|
83
|
+
nested_section = []
|
|
84
|
+
dir_path = os.path.join(self.base_path, nested_path)
|
|
85
|
+
for filename in os.listdir(dir_path):
|
|
86
|
+
if filename.endswith(".json"):
|
|
87
|
+
file_path = os.path.join(dir_path, filename)
|
|
88
|
+
# print(f"Loading file: {file_path}")
|
|
89
|
+
file_section = self.__load_json_file(file_path)
|
|
90
|
+
nested_section.append(file_section)
|
|
91
|
+
# print("done with nested sections")
|
|
92
|
+
else:
|
|
93
|
+
nested_section = self.get_nested_config(root_config, nested_path)
|
|
94
|
+
|
|
95
|
+
nested_section_resolved = self.resolve_references(
|
|
96
|
+
nested_section, root_config
|
|
97
|
+
)
|
|
98
|
+
|
|
99
|
+
# Merge resolved sections
|
|
100
|
+
if merged_section is None:
|
|
101
|
+
merged_section = nested_section_resolved
|
|
102
|
+
else:
|
|
103
|
+
# Merge logic based on type
|
|
104
|
+
if isinstance(merged_section, dict) and isinstance(nested_section_resolved, dict):
|
|
105
|
+
self.merge_sections(merged_section, nested_section_resolved)
|
|
106
|
+
elif isinstance(merged_section, list) and isinstance(nested_section_resolved, list):
|
|
107
|
+
merged_section.extend(nested_section_resolved)
|
|
108
|
+
else:
|
|
109
|
+
raise RuntimeError(
|
|
110
|
+
f"Cannot merge incompatible types: {type(merged_section)} and {type(nested_section_resolved)}"
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Apply any additional properties from the section
|
|
114
|
+
if len(section) > 0 and isinstance(merged_section, dict):
|
|
115
|
+
merged_section.update(section)
|
|
116
|
+
elif len(section) > 0 and isinstance(merged_section, list):
|
|
89
117
|
raise RuntimeError("we need to resolve this section")
|
|
90
|
-
#
|
|
118
|
+
# merged_section.append(section)
|
|
91
119
|
|
|
92
|
-
section =
|
|
120
|
+
section = merged_section
|
|
93
121
|
|
|
94
122
|
if isinstance(section, dict):
|
|
95
123
|
for key, value in section.items():
|
cdk_factory/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.8.
|
|
1
|
+
__version__ = "0.8.2"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
cdk_factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
2
|
cdk_factory/app.py,sha256=xv863N7O6HPKznB68_t7O4la9JacrkG87t9TjoDUk7s,2827
|
|
3
3
|
cdk_factory/cdk.json,sha256=SKZKhJ2PBpFH78j-F8S3VDYW-lf76--Q2I3ON-ZIQfw,3106
|
|
4
|
-
cdk_factory/version.py,sha256=
|
|
4
|
+
cdk_factory/version.py,sha256=B7GiO0rd49YwtLYjvPg4lmCZEDlMTonslQKdSImaMJk,22
|
|
5
5
|
cdk_factory/builds/README.md,sha256=9BBWd7bXpyKdMU_g2UljhQwrC9i5O_Tvkb6oPvndoZk,90
|
|
6
6
|
cdk_factory/commands/command_loader.py,sha256=QbLquuP_AdxtlxlDy-2IWCQ6D-7qa58aphnDPtp_uTs,3744
|
|
7
7
|
cdk_factory/configurations/base_config.py,sha256=JKjhNsy0RCUZy1s8n5D_aXXI-upR9izaLtCTfKYiV9k,9624
|
|
@@ -10,7 +10,7 @@ cdk_factory/configurations/deployment.py,sha256=LO2gd1yv1nqlX_2MIjRXptylFybWiTKs
|
|
|
10
10
|
cdk_factory/configurations/deployment_wave.py,sha256=TFX7CYgr5SmLyziEb-R_OTteFWtlMHB4pT53ekV3d1Y,233
|
|
11
11
|
cdk_factory/configurations/devops.py,sha256=PG-s2ldZmMULheWdKf2lf2LSugLoKiOKyLELTZJJxu8,2506
|
|
12
12
|
cdk_factory/configurations/enhanced_base_config.py,sha256=Y1gcGZxyf_O2KFnVpCBORSGHWHqHxw0vNx_ijMad_QA,6654
|
|
13
|
-
cdk_factory/configurations/enhanced_ssm_config.py,sha256=
|
|
13
|
+
cdk_factory/configurations/enhanced_ssm_config.py,sha256=VDmIUSrj8nYS6fE9DdOp5yi9jUfMfitz5A7kCuPS-kI,12895
|
|
14
14
|
cdk_factory/configurations/management.py,sha256=TSOIyxO9hGNxbgiTsS8a3pz03ungXiNqPPtZtfOpr8M,1373
|
|
15
15
|
cdk_factory/configurations/pipeline.py,sha256=3RmRP1GIk42rjYZ-A9H3357RcO13IA47N-2IQcBkySQ,4939
|
|
16
16
|
cdk_factory/configurations/pipeline_stage.py,sha256=eAT-FoIepIuv5tObk4TXlCN47FaatQO2rrFchgbMdXU,3415
|
|
@@ -57,7 +57,7 @@ cdk_factory/constructs/s3_buckets/s3_bucket_construct.py,sha256=5DK5aVUAveJYBjmP
|
|
|
57
57
|
cdk_factory/constructs/s3_buckets/s3_bucket_replication_destination_construct.py,sha256=H-EJ2Q71LI5FPQ9thMkXDGRuwJdFc_2OzGIrWA98lxg,2517
|
|
58
58
|
cdk_factory/constructs/s3_buckets/s3_bucket_replication_source_construct.py,sha256=ZLKbRcMK1q73VruxCH62XbymebKt-lKV5Kul9OjkZiA,3763
|
|
59
59
|
cdk_factory/constructs/sqs/policies/sqs_policies.py,sha256=4p0G8G-fqNKSr68I55fvqH-DkhIeXyGaFBKkICIJ-qM,1277
|
|
60
|
-
cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py,sha256=
|
|
60
|
+
cdk_factory/interfaces/enhanced_ssm_parameter_mixin.py,sha256=GYFaUo_vzmuox8dK0U-cI9d-OBhToXlTkrWeveGZr3k,13522
|
|
61
61
|
cdk_factory/interfaces/istack.py,sha256=bhTBs-o9FgKwvJMSuwxjUV6D3nUlvZHVzfm27jP9x9Y,987
|
|
62
62
|
cdk_factory/interfaces/live_ssm_resolver.py,sha256=3FIr9a02SXqZmbFs3RT0WxczWEQR_CF7QSt7kWbDrVE,8163
|
|
63
63
|
cdk_factory/interfaces/ssm_parameter_mixin.py,sha256=uA2j8HmAOpuEA9ynRj51s0WjUHMVLsbLQN-QS9NKyHA,12089
|
|
@@ -73,7 +73,7 @@ cdk_factory/stack/stack_module_registry.py,sha256=J14-A75VZESzRQa8p-Fepdap7Z8T7m
|
|
|
73
73
|
cdk_factory/stack/stack_modules.py,sha256=kgEK-j0smZPozVwTCfM1g1V17EyTBT0TXAQZq4vZz0o,784
|
|
74
74
|
cdk_factory/stack_library/__init__.py,sha256=5Y9TpIe8ZK1688G60PGcuP-hM0RvYEY_3Hl2qJCJJrw,581
|
|
75
75
|
cdk_factory/stack_library/stack_base.py,sha256=tTleSFmlf26DuKVF_ytftf8P7IVWb5iex8cYfYupfvQ,4940
|
|
76
|
-
cdk_factory/stack_library/api_gateway/api_gateway_stack.py,sha256=
|
|
76
|
+
cdk_factory/stack_library/api_gateway/api_gateway_stack.py,sha256=5rWHwLc6kI99YHUA1xqLtzcEhDmMB4p-xB9gLQ6o8JE,37916
|
|
77
77
|
cdk_factory/stack_library/auto_scaling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
78
78
|
cdk_factory/stack_library/auto_scaling/auto_scaling_stack.py,sha256=UsFqUb_3XPJAlmZ6F75nXna3elOggD1KuFmmdmhi0Lg,19070
|
|
79
79
|
cdk_factory/stack_library/aws_lambdas/lambda_stack.py,sha256=SFbBPvvCopbyiuYtq-O5sQkFCf94Wzua6aDUXiFDSB4,26161
|
|
@@ -100,19 +100,19 @@ cdk_factory/stack_library/vpc/__init__.py,sha256=7pIqP97Gf2AJbv9Ebp1WbQGHYhgEbWJ
|
|
|
100
100
|
cdk_factory/stack_library/vpc/vpc_stack.py,sha256=zdDiGilf03esxuya5Z8zVYSVMAIuZBeD-ZKgfnEd6aw,10077
|
|
101
101
|
cdk_factory/stack_library/websites/static_website_stack.py,sha256=KBQiV6PI09mpHGtH-So5Hk3uhfFLDepoXInGbfin0cY,7938
|
|
102
102
|
cdk_factory/stages/websites/static_website_stage.py,sha256=X4fpKXkhb0zIbSHx3QyddBhVSLBryb1vf1Cg2fMTqog,755
|
|
103
|
-
cdk_factory/utilities/api_gateway_integration_utility.py,sha256=
|
|
103
|
+
cdk_factory/utilities/api_gateway_integration_utility.py,sha256=yblKiMIHGXqKb7JK5IbzGM_TXjX9j893BMqgqBT44DE,63449
|
|
104
104
|
cdk_factory/utilities/commandline_args.py,sha256=0FiNEJFbWVN8Ct7r0VHnJEx7rhUlaRKT7R7HMNJBSTI,2216
|
|
105
105
|
cdk_factory/utilities/configuration_loader.py,sha256=z0ZdGLNbTO4_yfluB9zUh_i_Poc9qj-7oRyjMRlNkN8,1522
|
|
106
106
|
cdk_factory/utilities/docker_utilities.py,sha256=9r8C-lXYpymqEfi3gTeWCQzHldvfjttPqn6p3j2khTE,8111
|
|
107
107
|
cdk_factory/utilities/environment_services.py,sha256=cd2T0efJtFPMLa1Fm7MPL-sqUlhKXCB7_XHsR8sfymE,9696
|
|
108
108
|
cdk_factory/utilities/file_operations.py,sha256=HCZevKlmnHNB2wkIEPtdm-g2nJSKT3B9uipLk8Kx_Yk,8946
|
|
109
109
|
cdk_factory/utilities/git_utilities.py,sha256=7Xac8PaThc7Lmk5jtDBHaJOj-fWRT017cgZmgXkVizM,3155
|
|
110
|
-
cdk_factory/utilities/json_loading_utility.py,sha256=
|
|
110
|
+
cdk_factory/utilities/json_loading_utility.py,sha256=Yeqdjkkly0JLa7-V8j7ipmybsPoyPIKdRe7My7JTk3o,9203
|
|
111
111
|
cdk_factory/utilities/lambda_function_utilities.py,sha256=j3tBdv_gC2MdEwBINDwAqYey5vgn7YiQtJ0XZybTsCQ,15197
|
|
112
112
|
cdk_factory/utilities/os_execute.py,sha256=5Op0LY_8Y-pUm04y1k8MTpNrmQvcLmQHPQITEP7EuSU,1019
|
|
113
113
|
cdk_factory/utils/api_gateway_utilities.py,sha256=If7Xu5s_UxmuV-kL3JkXxPLBdSVUKoLtohm0IUFoiV8,4378
|
|
114
114
|
cdk_factory/workload/workload_factory.py,sha256=yBUDGIuB8-5p_mGcVFxsD2ZoZIziak3yh3LL3JvS0M4,5903
|
|
115
|
-
cdk_factory-0.8.
|
|
116
|
-
cdk_factory-0.8.
|
|
117
|
-
cdk_factory-0.8.
|
|
118
|
-
cdk_factory-0.8.
|
|
115
|
+
cdk_factory-0.8.2.dist-info/METADATA,sha256=PbYIaV_hrIj-7YZxLTQvR-GdLk6WErUYjuYP99HsjHA,2450
|
|
116
|
+
cdk_factory-0.8.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
117
|
+
cdk_factory-0.8.2.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
|
|
118
|
+
cdk_factory-0.8.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|