cdk-factory 0.15.4__py3-none-any.whl → 0.15.6__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.

@@ -129,8 +129,11 @@ class EcsServiceConfig:
129
129
  return self._config.get("ssm_exports", {})
130
130
 
131
131
  @property
132
- def ssm_imports(self) -> Dict[str, str]:
132
+ def ssm_imports(self) -> Dict[str, Any]:
133
133
  """SSM parameter imports"""
134
+ # Check both nested and flat structures for backwards compatibility
135
+ if "ssm" in self._config and "imports" in self._config["ssm"]:
136
+ return self._config["ssm"]["imports"]
134
137
  return self._config.get("ssm_imports", {})
135
138
 
136
139
  @property
@@ -143,3 +143,11 @@ class LoadBalancerConfig(EnhancedBaseConfig):
143
143
  return self.__config.get("ip_whitelist", {}).get(
144
144
  "block_response", default_response
145
145
  )
146
+
147
+ @property
148
+ def ssm_imports(self) -> Dict[str, Any]:
149
+ """SSM parameter imports for the Load Balancer"""
150
+ # Check both nested and flat structures for backwards compatibility
151
+ if "ssm" in self.__config and "imports" in self.__config["ssm"]:
152
+ return self.__config["ssm"]["imports"]
153
+ return self.__config.get("ssm_imports", {})
@@ -134,4 +134,7 @@ class RdsConfig(EnhancedBaseConfig):
134
134
  @property
135
135
  def ssm_imports(self) -> Dict[str, str]:
136
136
  """SSM parameter imports for the RDS instance"""
137
+ # Check both nested and flat structures for backwards compatibility
138
+ if "ssm" in self.__config and "imports" in self.__config["ssm"]:
139
+ return self.__config["ssm"]["imports"]
137
140
  return self.__config.get("ssm_imports", {})
@@ -65,4 +65,7 @@ class SecurityGroupFullStackConfig:
65
65
  @property
66
66
  def ssm_imports(self) -> Dict[str, str]:
67
67
  """SSM parameter imports for the Security Group"""
68
+ # Check both nested and flat structures for backwards compatibility
69
+ if "ssm" in self.__config and "imports" in self.__config["ssm"]:
70
+ return self.__config["ssm"]["imports"]
68
71
  return self.__config.get("ssm_imports", {})
@@ -49,6 +49,8 @@ class EcsServiceStack(IStack, EnhancedSsmParameterMixin):
49
49
  self.service: Optional[ecs.FargateService] = None
50
50
  self.task_definition: Optional[ecs.FargateTaskDefinition] = None
51
51
  self._vpc: Optional[ec2.IVpc] = None
52
+ # SSM imported values
53
+ self.ssm_imported_values: Dict[str, Any] = {}
52
54
 
53
55
  def build(
54
56
  self,
@@ -77,6 +79,9 @@ class EcsServiceStack(IStack, EnhancedSsmParameterMixin):
77
79
 
78
80
  service_name = deployment.build_resource_name(self.ecs_config.name)
79
81
 
82
+ # Process SSM imports first
83
+ self._process_ssm_imports()
84
+
80
85
  # Load VPC
81
86
  self._load_vpc()
82
87
 
@@ -98,16 +103,79 @@ class EcsServiceStack(IStack, EnhancedSsmParameterMixin):
98
103
 
99
104
  def _load_vpc(self) -> None:
100
105
  """Load VPC from configuration"""
101
- vpc_id = self.ecs_config.vpc_id or self.workload.vpc_id
106
+ # Check SSM imported values first
107
+ if "vpc_id" in self.ssm_imported_values:
108
+ vpc_id = self.ssm_imported_values["vpc_id"]
109
+
110
+ # Build VPC attributes
111
+ vpc_attrs = {
112
+ "vpc_id": vpc_id,
113
+ "availability_zones": ["us-east-1a", "us-east-1b"]
114
+ }
115
+
116
+ # Use from_vpc_attributes() for SSM tokens
117
+ self._vpc = ec2.Vpc.from_vpc_attributes(self, "VPC", **vpc_attrs)
118
+ else:
119
+ vpc_id = self.ecs_config.vpc_id or self.workload.vpc_id
120
+
121
+ if not vpc_id:
122
+ raise ValueError("VPC ID is required for ECS service")
123
+
124
+ self._vpc = ec2.Vpc.from_lookup(
125
+ self,
126
+ "VPC",
127
+ vpc_id=vpc_id
128
+ )
129
+
130
+ def _process_ssm_imports(self) -> None:
131
+ """
132
+ Process SSM imports from configuration.
133
+ Follows the same pattern as RDS, Load Balancer, and Security Group stacks.
134
+ """
135
+ from aws_cdk import aws_ssm as ssm
102
136
 
103
- if not vpc_id:
104
- raise ValueError("VPC ID is required for ECS service")
137
+ ssm_imports = self.ecs_config.ssm_imports
105
138
 
106
- self._vpc = ec2.Vpc.from_lookup(
107
- self,
108
- "VPC",
109
- vpc_id=vpc_id
110
- )
139
+ if not ssm_imports:
140
+ logger.debug("No SSM imports configured for ECS Service")
141
+ return
142
+
143
+ logger.info(f"Processing {len(ssm_imports)} SSM imports for ECS Service")
144
+
145
+ for param_key, param_value in ssm_imports.items():
146
+ try:
147
+ # Handle list values (like security_group_ids)
148
+ if isinstance(param_value, list):
149
+ imported_list = []
150
+ for idx, param_path in enumerate(param_value):
151
+ if not param_path.startswith('/'):
152
+ param_path = f"/{param_path}"
153
+
154
+ construct_id = f"ssm-import-{param_key}-{idx}-{hash(param_path) % 10000}"
155
+ param = ssm.StringParameter.from_string_parameter_name(
156
+ self, construct_id, param_path
157
+ )
158
+ imported_list.append(param.string_value)
159
+
160
+ self.ssm_imported_values[param_key] = imported_list
161
+ logger.info(f"Imported SSM parameter list: {param_key} with {len(imported_list)} items")
162
+ else:
163
+ # Handle string values
164
+ param_path = param_value
165
+ if not param_path.startswith('/'):
166
+ param_path = f"/{param_path}"
167
+
168
+ construct_id = f"ssm-import-{param_key}-{hash(param_path) % 10000}"
169
+ param = ssm.StringParameter.from_string_parameter_name(
170
+ self, construct_id, param_path
171
+ )
172
+
173
+ self.ssm_imported_values[param_key] = param.string_value
174
+ logger.info(f"Imported SSM parameter: {param_key} from {param_path}")
175
+
176
+ except Exception as e:
177
+ logger.error(f"Failed to import SSM parameter {param_key}: {e}")
178
+ raise
111
179
 
112
180
  def _create_or_load_cluster(self) -> None:
113
181
  """Create a new ECS cluster or load an existing one"""
@@ -48,6 +48,8 @@ class LoadBalancerStack(IStack, EnhancedSsmParameterMixin):
48
48
  self._vpc = None
49
49
  self._hosted_zone = None
50
50
  self._record_names = None
51
+ # SSM imported values
52
+ self.ssm_imported_values: Dict[str, str] = {}
51
53
 
52
54
  def build(
53
55
  self,
@@ -74,6 +76,9 @@ class LoadBalancerStack(IStack, EnhancedSsmParameterMixin):
74
76
  )
75
77
  lb_name = deployment.build_resource_name(self.lb_config.name)
76
78
 
79
+ # Process SSM imports first
80
+ self._process_ssm_imports()
81
+
77
82
  self._prep_dns()
78
83
 
79
84
  # set up SSL certificate if configured
@@ -148,6 +153,18 @@ class LoadBalancerStack(IStack, EnhancedSsmParameterMixin):
148
153
  if self._vpc:
149
154
  return self._vpc
150
155
 
156
+ # Check SSM imported values first (tokens from SSM parameters)
157
+ if "vpc_id" in self.ssm_imported_values:
158
+ vpc_id = self.ssm_imported_values["vpc_id"]
159
+
160
+ # Build VPC attributes
161
+ vpc_attrs = {
162
+ "vpc_id": vpc_id,
163
+ "availability_zones": ["us-east-1a", "us-east-1b"]
164
+ }
165
+
166
+ # Use from_vpc_attributes() instead of from_lookup() because SSM imports return tokens
167
+ self._vpc = ec2.Vpc.from_vpc_attributes(self, "VPC", **vpc_attrs)
151
168
  elif self.lb_config.vpc_id:
152
169
  self._vpc = ec2.Vpc.from_lookup(self, "VPC", vpc_id=self.lb_config.vpc_id)
153
170
  elif self.workload.vpc_id:
@@ -162,13 +179,72 @@ class LoadBalancerStack(IStack, EnhancedSsmParameterMixin):
162
179
 
163
180
  return self._vpc
164
181
 
182
+ def _process_ssm_imports(self) -> None:
183
+ """
184
+ Process SSM imports from configuration.
185
+ Follows the same pattern as RDS and Security Group stacks.
186
+ """
187
+ from aws_cdk import aws_ssm as ssm
188
+
189
+ ssm_imports = self.lb_config.ssm_imports
190
+
191
+ if not ssm_imports:
192
+ logger.debug("No SSM imports configured for Load Balancer")
193
+ return
194
+
195
+ logger.info(f"Processing {len(ssm_imports)} SSM imports for Load Balancer")
196
+
197
+ for param_key, param_value in ssm_imports.items():
198
+ try:
199
+ # Handle list values (like security_groups)
200
+ if isinstance(param_value, list):
201
+ imported_list = []
202
+ for idx, param_path in enumerate(param_value):
203
+ if not param_path.startswith('/'):
204
+ param_path = f"/{param_path}"
205
+
206
+ construct_id = f"ssm-import-{param_key}-{idx}-{hash(param_path) % 10000}"
207
+ param = ssm.StringParameter.from_string_parameter_name(
208
+ self, construct_id, param_path
209
+ )
210
+ imported_list.append(param.string_value)
211
+
212
+ self.ssm_imported_values[param_key] = imported_list
213
+ logger.info(f"Imported SSM parameter list: {param_key} with {len(imported_list)} items")
214
+ else:
215
+ # Handle string values
216
+ param_path = param_value
217
+ if not param_path.startswith('/'):
218
+ param_path = f"/{param_path}"
219
+
220
+ construct_id = f"ssm-import-{param_key}-{hash(param_path) % 10000}"
221
+ param = ssm.StringParameter.from_string_parameter_name(
222
+ self, construct_id, param_path
223
+ )
224
+
225
+ self.ssm_imported_values[param_key] = param.string_value
226
+ logger.info(f"Imported SSM parameter: {param_key} from {param_path}")
227
+
228
+ except Exception as e:
229
+ logger.error(f"Failed to import SSM parameter {param_key}: {e}")
230
+ raise
231
+
165
232
  def _get_security_groups(self) -> List[ec2.ISecurityGroup]:
166
233
  """Get security groups for the Load Balancer"""
167
234
  security_groups = []
168
- for sg_id in self.lb_config.security_groups:
235
+
236
+ # Check SSM imported values first
237
+ if "security_groups" in self.ssm_imported_values:
238
+ sg_ids = self.ssm_imported_values["security_groups"]
239
+ if not isinstance(sg_ids, list):
240
+ sg_ids = [sg_ids]
241
+ else:
242
+ sg_ids = self.lb_config.security_groups
243
+
244
+ for idx, sg_id in enumerate(sg_ids):
169
245
  security_groups.append(
170
246
  ec2.SecurityGroup.from_security_group_id(
171
- self, f"SecurityGroup-{sg_id}", sg_id
247
+ self, f"SecurityGroup-{idx}", sg_id
172
248
  )
173
249
  )
174
250
  return security_groups
@@ -176,9 +252,21 @@ class LoadBalancerStack(IStack, EnhancedSsmParameterMixin):
176
252
  def _get_subnets(self) -> List[ec2.ISubnet]:
177
253
  """Get subnets for the Load Balancer"""
178
254
  subnets = []
179
- for subnet_id in self.lb_config.subnets:
255
+
256
+ # Check SSM imported values first
257
+ if "subnet_ids" in self.ssm_imported_values:
258
+ subnet_ids = self.ssm_imported_values["subnet_ids"]
259
+ # SSM returns comma-separated string for StringList, need to split
260
+ if isinstance(subnet_ids, str):
261
+ subnet_ids = [s.strip() for s in subnet_ids.split(',')]
262
+ elif not isinstance(subnet_ids, list):
263
+ subnet_ids = [subnet_ids]
264
+ else:
265
+ subnet_ids = self.lb_config.subnets
266
+
267
+ for idx, subnet_id in enumerate(subnet_ids):
180
268
  subnets.append(
181
- ec2.Subnet.from_subnet_id(self, f"Subnet-{subnet_id}", subnet_id)
269
+ ec2.Subnet.from_subnet_id(self, f"Subnet-{idx}", subnet_id)
182
270
  )
183
271
  return subnets
184
272
 
cdk_factory/version.py CHANGED
@@ -1 +1 @@
1
- __version__ = "0.15.4"
1
+ __version__ = "0.15.6"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cdk_factory
3
- Version: 0.15.4
3
+ Version: 0.15.6
4
4
  Summary: CDK Factory. A QuickStarter and best practices setup for CDK projects
5
5
  Author-email: Eric Wilson <eric.wilson@geekcafe.com>
6
6
  License: MIT License
@@ -2,7 +2,7 @@ cdk_factory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  cdk_factory/app.py,sha256=RnX0-pwdTAPAdKJK_j13Zl8anf9zYKBwboR0KA8K8xM,10346
3
3
  cdk_factory/cdk.json,sha256=SKZKhJ2PBpFH78j-F8S3VDYW-lf76--Q2I3ON-ZIQfw,3106
4
4
  cdk_factory/cli.py,sha256=FGbCTS5dYCNsfp-etshzvFlGDCjC28r6rtzYbe7KoHI,6407
5
- cdk_factory/version.py,sha256=Ypoj4dM4zqbnGvYnOqiUlHcf_l1wO2M39u5_-ECRTQU,23
5
+ cdk_factory/version.py,sha256=So0qfsz_A4mujJ9XBWY4PqtrU6DdTz1l5TygxPTJj1Y,23
6
6
  cdk_factory/builds/README.md,sha256=9BBWd7bXpyKdMU_g2UljhQwrC9i5O_Tvkb6oPvndoZk,90
7
7
  cdk_factory/commands/command_loader.py,sha256=QbLquuP_AdxtlxlDy-2IWCQ6D-7qa58aphnDPtp_uTs,3744
8
8
  cdk_factory/configurations/base_config.py,sha256=JKjhNsy0RCUZy1s8n5D_aXXI-upR9izaLtCTfKYiV9k,9624
@@ -30,15 +30,15 @@ cdk_factory/configurations/resources/cognito.py,sha256=udX2AJ1ITLhy4f1XiJQwrva6F
30
30
  cdk_factory/configurations/resources/docker.py,sha256=hUbuxkuhcQu9LnLX7I8_57eTmHefEAGVnOHO37MkqC4,2166
31
31
  cdk_factory/configurations/resources/dynamodb.py,sha256=HsZMOaRwfuNPwKIzokeeE3f5zAQLTB5hRb_GzYq2ibg,2903
32
32
  cdk_factory/configurations/resources/ecr.py,sha256=o9hHzEBVPoxUvWZGXGbRJ-98FmP6fMLY5a1-qg42jL0,8253
33
- cdk_factory/configurations/resources/ecs_service.py,sha256=NlFkSgWhO58QtCGZZRFQECA3km7O5D_Ee0BIfAcfDxE,4729
33
+ cdk_factory/configurations/resources/ecs_service.py,sha256=fAW4EuBNhPrE7G0QcHXongKoAnFeGMRS6iP7OuGP5Fw,4926
34
34
  cdk_factory/configurations/resources/exisiting.py,sha256=EVOLnkB-DGfTlmDgyQ5DD5k2zYfpFxqI3gugDR7mifI,478
35
35
  cdk_factory/configurations/resources/lambda_edge.py,sha256=MjmiwDkys4aoRvDQhH3MT6BgeShzJXNWL7761HJrLtQ,3404
36
36
  cdk_factory/configurations/resources/lambda_function.py,sha256=VENZ9-ABJ5mjcN8J8wdLH4KHDYr1kWO0iFDH0B2mJXA,14659
37
37
  cdk_factory/configurations/resources/lambda_layers.py,sha256=gVeP_-LC3Eq0lkPaG_JfFUwboM5evRPr99SfKj53m7A,633
38
38
  cdk_factory/configurations/resources/lambda_triggers.py,sha256=MD7cdMNKEulNBhtMLIFnWJuJ5R-yyIqa0LHUgbSQerA,834
39
- cdk_factory/configurations/resources/load_balancer.py,sha256=DHVKuEDaTfbB0UKYBt7UQQCPCM4FY-ThT1T52lcwg_E,4897
39
+ cdk_factory/configurations/resources/load_balancer.py,sha256=idpKdvkkCM7J9J2pNjMBOY1DNaFR1tk1tFjTg76bvrY,5267
40
40
  cdk_factory/configurations/resources/monitoring.py,sha256=zsfDMa7yph33Ql8iP7lIqqLAyixh-Mesi0imtZJFdcE,2310
41
- cdk_factory/configurations/resources/rds.py,sha256=NhXOPTqjfOZhJWyNd0yhBnkk1J0VOPgNLe6VldaJe6k,4628
41
+ cdk_factory/configurations/resources/rds.py,sha256=fYyS9qlsdHCdGQ5jS3f-edQUvbNYX30T96gxEwlz9tM,4828
42
42
  cdk_factory/configurations/resources/resource_mapping.py,sha256=cwv3n63RJ6E59ErsmSTdkW4i-g8huhHtKI0ExbRhJxA,2182
43
43
  cdk_factory/configurations/resources/resource_naming.py,sha256=VE9S2cpzp11qqPL2z1sX79wXH0o1SntO2OG74nEmWC8,5508
44
44
  cdk_factory/configurations/resources/resource_types.py,sha256=1WQHyDoErb-M-tETZZzyLDtbq_jdC85-I403dM48pgE,2317
@@ -47,7 +47,7 @@ cdk_factory/configurations/resources/route53_hosted_zone.py,sha256=qjEYPCSxSOx5b
47
47
  cdk_factory/configurations/resources/rum.py,sha256=5aNLhyJEl97spby2gEV59RsMIQpUto2hGh1DeSyIp_I,5149
48
48
  cdk_factory/configurations/resources/s3.py,sha256=LBwTOZ4tOxNbgiu1fFGHOTyF5jlzeVphc_9VAqNw8zA,6042
49
49
  cdk_factory/configurations/resources/security_group.py,sha256=8kQtaaRVEn2aDm8XoC7QFh2mDOFbPbgobmssIuqU8MA,2259
50
- cdk_factory/configurations/resources/security_group_full_stack.py,sha256=J56ui5cR4ULcT-20LdK43UNXhcicB2M45Wl8Y9SIWCA,2202
50
+ cdk_factory/configurations/resources/security_group_full_stack.py,sha256=3LHIJw4BEsagb0EMnc8C2_g4OQxUe0kQTn3XqQltUIE,2402
51
51
  cdk_factory/configurations/resources/sqs.py,sha256=fAh2dqttJ6PX46enFRULuiLEu3TEj0Vb2xntAOgUpYE,4346
52
52
  cdk_factory/configurations/resources/vpc.py,sha256=sNn6w76bHFwmt6N76gZZhqpsuNB9860C1SZu6tebaXY,3835
53
53
  cdk_factory/constructs/cloudfront/cloudfront_distribution_construct.py,sha256=LHgjvTNghCMTpHh90VWl7AbE100Er-S9EgyEVt12J_c,25809
@@ -93,11 +93,11 @@ cdk_factory/stack_library/dynamodb/dynamodb_stack.py,sha256=TVyOrUhgaSuN8uymkpaQ
93
93
  cdk_factory/stack_library/ecr/README.md,sha256=xw2wPx9WN03Y4BBwqvbi9lAFGNyaD1FUNpqxVJX14Oo,179
94
94
  cdk_factory/stack_library/ecr/ecr_stack.py,sha256=1xA68sxFVyqreYjXrP_7U9I8RF9RtFeR6KeEfSWuC2U,2118
95
95
  cdk_factory/stack_library/ecs/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
96
- cdk_factory/stack_library/ecs/ecs_service_stack.py,sha256=zuGdZEP5KmeVDTJb-H47LYhvs-85-Fi4Xb78nsA-lF4,24685
96
+ cdk_factory/stack_library/ecs/ecs_service_stack.py,sha256=IVqzrV6cJCJXQV-eS2mPInUr1bjjIwGIKDNH2Gc-LFM,27709
97
97
  cdk_factory/stack_library/lambda_edge/__init__.py,sha256=ByBJ_CWdc4UtTmFBZH-6pzBMNkjkdtE65AmnB0Fs6lM,156
98
98
  cdk_factory/stack_library/lambda_edge/lambda_edge_stack.py,sha256=CdId_1kcZmYr1lLI9AD3-KqtE6voC3641PIloJmWiNI,16414
99
99
  cdk_factory/stack_library/load_balancer/__init__.py,sha256=wZpKw2OecLJGdF5mPayCYAEhu2H3c2gJFFIxwXftGDU,52
100
- cdk_factory/stack_library/load_balancer/load_balancer_stack.py,sha256=t5JUe5lMUbQCRFZR08k8nO-g-53yWY8gKB9v8ZnedBs,24391
100
+ cdk_factory/stack_library/load_balancer/load_balancer_stack.py,sha256=SBB-Cknon7U317iR2chFNWjny-lp8BFmzFMCYLP-8Uo,28253
101
101
  cdk_factory/stack_library/monitoring/__init__.py,sha256=k1G_KDx47Aw0UugaL99PN_TKlyLK4nkJVApCaAK7GJg,153
102
102
  cdk_factory/stack_library/monitoring/monitoring_stack.py,sha256=N_1YvEXE7fboH_S3kv_dSKZsufxMuPdFMjGzlNFpuSo,19283
103
103
  cdk_factory/stack_library/rds/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -129,8 +129,8 @@ cdk_factory/utilities/lambda_function_utilities.py,sha256=S1GvBsY_q2cyUiaud3HORJ
129
129
  cdk_factory/utilities/os_execute.py,sha256=5Op0LY_8Y-pUm04y1k8MTpNrmQvcLmQHPQITEP7EuSU,1019
130
130
  cdk_factory/utils/api_gateway_utilities.py,sha256=If7Xu5s_UxmuV-kL3JkXxPLBdSVUKoLtohm0IUFoiV8,4378
131
131
  cdk_factory/workload/workload_factory.py,sha256=mM8GU_5mKq_0OyK060T3JrUSUiGAcKf0eqNlT9mfaws,6028
132
- cdk_factory-0.15.4.dist-info/METADATA,sha256=f7hhvfGsvbMtz0P6ahc_dLgJQyMEZz-VOTZ38w9MQIM,2451
133
- cdk_factory-0.15.4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
134
- cdk_factory-0.15.4.dist-info/entry_points.txt,sha256=S1DPe0ORcdiwEALMN_WIo3UQrW_g4YdQCLEsc_b0Swg,53
135
- cdk_factory-0.15.4.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
136
- cdk_factory-0.15.4.dist-info/RECORD,,
132
+ cdk_factory-0.15.6.dist-info/METADATA,sha256=qanYZlntfcMe0rhD-XjfZePXjUPb2N2_vVjXLgdN8PU,2451
133
+ cdk_factory-0.15.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
134
+ cdk_factory-0.15.6.dist-info/entry_points.txt,sha256=S1DPe0ORcdiwEALMN_WIo3UQrW_g4YdQCLEsc_b0Swg,53
135
+ cdk_factory-0.15.6.dist-info/licenses/LICENSE,sha256=NOtdOeLwg2il_XBJdXUPFPX8JlV4dqTdDGAd2-khxT8,1066
136
+ cdk_factory-0.15.6.dist-info/RECORD,,