8000 Refactor CFn conditions & mappings (#8546) · codeperl/localstack@bee5f76 · GitHub
[go: up one dir, main page]

Skip to content

Commit bee5f76

Browse files
Refactor CFn conditions & mappings (localstack#8546)
1 parent 37e9ab3 commit bee5f76

24 files changed

+1809
-108
lines changed

localstack/services/cloudformation/engine/entities.py

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ def __init__(
104104
self.events = []
105105
# list of stack change sets
106106
self.change_sets = []
107+
# self.evaluated_conditions = {}
107108

108109
def set_resolved_parameters(self, resolved_parameters: dict[str, Parameter]):
109110
self.resolved_parameters = resolved_parameters
@@ -247,21 +248,14 @@ def resources(self): # TODO: not actually resources, split apart
247248
{k: map_to_legacy_structure(k, v) for k, v in self.resolved_parameters.items()}
248249
)
249250

250-
# TODO: conditions and mappings don't really belong here and should be handled separately
251+
# TODO: conditions don't really belong here and should be handled separately
251252
for name, value in self.conditions.items():
252253
if name not in result:
253254
result[name] = {
254255
"Type": "Parameter",
255256
"LogicalResourceId": name,
256257
"Properties": {"Value": value},
257258
}
258-
for name, value in self.mappings.items():
259-
if name not in result:
260-
result[name] = {
261-
"Type": "Parameter",
262-
"LogicalResourceId": name,
263-
"Properties": {"Value": value},
264-
}
265259

266260
return result
267261

localstack/services/cloudformation/engine/template_deployer.py

Lines changed: 98 additions & 91 deletions
Large diffs are not rendered by default.

localstack/services/cloudformation/engine/template_preparer.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,14 @@ def template_to_json(template: str) -> str:
4040

4141

4242
# TODO: consider moving to transformers.py as well
43-
def transform_template(template: dict, parameters: list, stack_name: str, resources: dict) -> dict:
43+
def transform_template(
44+
template: dict, parameters: list, stack_name: str, resources: dict, mappings: dict
45+
) -> dict:
4446
result = dict(template)
4547

4648
# apply 'Fn::Transform' intrinsic functions (note: needs to be applied before global
4749
# transforms below, as some utils - incl samtransformer - expect them to be resolved already)
48-
result = apply_transform_intrinsic_functions(result, stack_name, resources)
50+
result = apply_transform_intrinsic_functions(result, stack_name, resources, mappings)
4951

5052
# apply global transforms
5153
transformations = format_transforms(result.get("Transform", []))

localstack/services/cloudformation/engine/transformers.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,9 @@ def transform(self, parameters: dict) -> TransformResult:
3939
transformers: Dict[str, Type] = {"AWS::Include": AwsIncludeTransformer}
4040

4141

42-
def apply_transform_intrinsic_functions(template: dict, stack_name: str, resources: dict) -> dict:
42+
def apply_transform_intrinsic_functions(
43+
template: dict, stack_name: str, resources: dict, mappings: dict
44+
) -> dict:
4345
"""Resolve constructs using the 'Fn::Transform' intrinsic function."""
4446
from localstack.services.cloudformation.engine.template_deployer import resolve_refs_recursively
4547

@@ -51,7 +53,7 @@ def _visit(obj, **_):
5153
if transformer_class:
5254
transformer = transformer_class()
5355
parameters = transform.get("Parameters") or {}
54-
parameters = resolve_refs_recursively(stack_name, resources, parameters)
56+
parameters = resolve_refs_recursively(stack_name, resources, mappings, parameters)
5557
return transformer.transform(parameters)
5658
return obj
5759

localstack/services/cloudformation/provider.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,7 @@ def create_stack(self, context: RequestContext, request: CreateStackInput) -> Cr
189189
"Requires capabilities : [CAPABILITY_AUTO_EXPAND]"
190190
)
191191

192+
# resolve stack parameters
192193
new_parameters: dict[str, Parameter] = param_resolver.convert_stack_parameters_to_dict(
193194
request.get("Parameters")
194195
)
@@ -199,11 +200,16 @@ def create_stack(self, context: RequestContext, request: CreateStackInput) -> Cr
199200
old_parameters={},
200201
)
201202

203+
# handle conditions
202204
stack = Stack(request, template)
203205

204206
try:
205207
template = template_preparer.transform_template(
206-
template, list(resolved_parameters.values()), stack.stack_name, stack.resources
208+
template,
209+
list(resolved_parameters.values()),
210+
stack.stack_name,
211+
stack.resources,
212+
stack.mappings,
207213
)
208214
except FailedTransformationException as e:
209215
stack.add_stack_event(
@@ -283,7 +289,11 @@ def update_stack(
283289

284290
try:
285291
template = template_preparer.transform_template(
286-
template, list(resolved_parameters.values()), stack.stack_name, stack.resources
292+
template,
293+
list(resolved_parameters.values()),
294+
stack.stack_name,
295+
stack.resources,
296+
stack.mappings,
287297
)
288298
except FailedTransformationException as e:
289299
stack.add_stack_event(
@@ -506,7 +516,7 @@ def create_change_set(
506516
)
507517
raise ValidationError(msg)
508518

509-
# apply template transformations
519+
# resolve parameters
510520
new_parameters: dict[str, Parameter] = param_resolver.convert_stack_parameters_to_dict(
511521
request.get("Parameters")
512522
)
@@ -526,15 +536,24 @@ def create_change_set(
526536
temp_stack = Stack(req_params_copy, template)
527537
temp_stack.set_resolved_parameters(resolved_parameters)
528538

539+
# TODO: everything below should be async
540+
# apply template transformations
529541
transformed_template = template_preparer.transform_template(
530-
template, parameters, stack_name=temp_stack.stack_name, resources=temp_stack.resources
542+
template,
543+
parameters,
544+
stack_name=temp_stack.stack_name,
545+
resources=temp_stack.resources,
546+
mappings=temp_stack.mappings,
531547
)
532548

533549
# create change set for the stack and apply changes
534550
change_set = StackChangeSet(stack, req_params, transformed_template)
535551
# only set parameters for the changeset, then switch to stack on execute_change_set
536552
change_set.set_resolved_parameters(resolved_parameters)
537553

554+
# TODO: evaluate conditions
555+
# change_set.set_resolved_conditions(resolved_conditions)
556+
538557
deployer = template_deployer.TemplateDeployer(change_set)
539558
changes = deployer.construct_changes(
540559
stack,

localstack/services/cloudformation/resource_provider.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -397,12 +397,13 @@ def update(self, request: ResourceRequest[Properties]) -> ProgressEvent[Properti
397397
request.logical_resource_id,
398398
)
399399
# TODO: should not really claim the update was successful, but the
400-
# API does not really let us signal this in any other way.
400+
# API does not really let us signal this in any other way.
401401
return ProgressEvent(
402402
status=OperationStatus.SUCCESS, resource_model=request.desired_state
403403
)
404404

405405
LOG.info("Updating resource %s of type %s", request.logical_resource_id, self.resource_type)
406+
406407
resource_provider.update_resource(
407408
self.all_resources[request.logical_resource_id],
408409
stack_name=request.stack_name,
@@ -431,6 +432,11 @@ def create_or_delete(self, request: ResourceRequest[Properties]) -> ProgressEven
431432
},
432433
region_name=request.region_name,
433434
)
435+
# TODO: only really necessary for the create and update operation
436+
resource_provider.add_defaults(
437+
self.all_resources[request.logical_resource_id], request.stack_name
438+
)
439+
434440
func_details = resource_provider.get_deploy_templates()
435441
# TODO: be less strict about the return value of func_details
436442
LOG.debug(

tests/integration/cloudformation/engine/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)
0