cloud-radar 0.14.0a8__py3-none-any.whl → 0.14.0a9__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.
@@ -81,6 +81,7 @@ class Template:
81
81
  self.transforms: Optional[Union[str, List[str]]] = self.template.get(
82
82
  "Transform", None
83
83
  )
84
+ self.allowed_functions: functions.Dispatch = self.load_allowed_functions()
84
85
 
85
86
  # All loaded, validate against any template level hooks
86
87
  # that have been configured
@@ -207,7 +208,7 @@ class Template:
207
208
  # If we get this far then we do not support this type of configuration file
208
209
  raise ValueError("Parameter file is not in a supported format")
209
210
 
210
- def load_allowed_functions(self) -> functions.Dispatch:
211
+ def load_allowed_functions(self):
211
212
  """Loads the allowed functions for this template.
212
213
 
213
214
  Raises:
@@ -231,8 +232,9 @@ class Template:
231
232
  return {**functions.ALL_FUNCTIONS, **transform_functions}
232
233
 
233
234
  if isinstance(self.transforms, list):
234
- # dict of transform functions
235
+
235
236
  transform_functions = {}
237
+
236
238
  for transform in self.transforms:
237
239
  if transform not in functions.TRANSFORMS:
238
240
  raise ValueError(f"Transform {transform} not supported")
@@ -249,13 +251,8 @@ class Template:
249
251
  def render_all_sections(self, template: Dict[str, Any]) -> Dict[str, Any]:
250
252
  """Solves all conditionals, references and pseudo variables for all sections"""
251
253
 
252
- allowed_functions = self.load_allowed_functions()
253
-
254
254
  if "Conditions" in template:
255
- template["Conditions"] = self.resolve_values(
256
- template["Conditions"],
257
- allowed_functions,
258
- )
255
+ template["Conditions"] = self.resolve_values(template["Conditions"])
259
256
 
260
257
  template_sections = ["Resources", "Outputs"]
261
258
 
@@ -278,10 +275,7 @@ class Template:
278
275
  if not condition_value:
279
276
  continue
280
277
 
281
- template[section][r_name] = self.resolve_values(
282
- r_value,
283
- allowed_functions,
284
- )
278
+ template[section][r_name] = self.resolve_values(r_value)
285
279
 
286
280
  return template
287
281
 
@@ -346,7 +340,6 @@ class Template:
346
340
  def resolve_values( # noqa: max-complexity: 13
347
341
  self,
348
342
  data: Any,
349
- allowed_func: functions.Dispatch,
350
343
  ) -> Any:
351
344
  """Recurses through a Cloudformation template. Solving all
352
345
  references and variables along the way.
@@ -366,10 +359,7 @@ class Template:
366
359
  # This takes care of keys that not intrinsic functions,
367
360
  # except for the condition func
368
361
  if "Fn::" not in key and key != "Condition":
369
- data[key] = self.resolve_values(
370
- value,
371
- allowed_func,
372
- )
362
+ data[key] = self.resolve_values(value)
373
363
  continue
374
364
 
375
365
  # Takes care of the tricky 'Condition' key
@@ -387,21 +377,15 @@ class Template:
387
377
  return functions.condition(self, value)
388
378
 
389
379
  # Normal key like in an IAM role
390
- data[key] = self.resolve_values(
391
- value,
392
- allowed_func,
393
- )
380
+ data[key] = self.resolve_values(value)
394
381
  continue
395
382
 
396
- if key not in allowed_func:
383
+ if key not in self.allowed_functions:
397
384
  raise ValueError(f"{key} with value ({value}) not allowed here")
398
385
 
399
- value = self.resolve_values(
400
- value,
401
- functions.ALLOWED_FUNCTIONS[key],
402
- )
386
+ value = self.resolve_values(value)
403
387
 
404
- funct_result = allowed_func[key](self, value)
388
+ funct_result = self.allowed_functions[key](self, value)
405
389
 
406
390
  if isinstance(funct_result, str):
407
391
  # If the result is a string then process any
@@ -412,13 +396,7 @@ class Template:
412
396
 
413
397
  return data
414
398
  elif isinstance(data, list):
415
- return [
416
- self.resolve_values(
417
- item,
418
- allowed_func,
419
- )
420
- for item in data
421
- ]
399
+ return [self.resolve_values(item) for item in data]
422
400
  elif isinstance(data, str):
423
401
  return self.resolve_dynamic_references(data)
424
402
  else:
@@ -283,9 +283,7 @@ def condition(template: "Template", name: Any) -> bool:
283
283
  condition_value = template.template["Conditions"][name]
284
284
 
285
285
  if not isinstance(condition_value, bool):
286
- condition_value: bool = template.resolve_values( # type: ignore
287
- condition_value, allowed_func=ALLOWED_NESTED_CONDITIONS
288
- )
286
+ condition_value: bool = template.resolve_values(condition_value) # type: ignore
289
287
 
290
288
  return condition_value
291
289
 
@@ -942,106 +940,6 @@ ALL_FUNCTIONS: Dispatch = {
942
940
  **INTRINSICS,
943
941
  }
944
942
 
945
- ALLOWED_NESTED_CONDITIONS: Dispatch = {
946
- "Fn::FindInMap": find_in_map,
947
- "Ref": ref,
948
- **CONDITIONS,
949
- }
950
-
951
- # Cloudformation only allows certain functions to be called from inside
952
- # other functions. The keys are the function name and the values are the
953
- # functions that are allowed to be nested inside it.
954
- ALLOWED_FUNCTIONS: Dict[str, Dispatch] = {
955
- "Fn::And": ALLOWED_NESTED_CONDITIONS,
956
- "Fn::Equals": {**ALLOWED_NESTED_CONDITIONS, "Fn::Join": join, "Fn::Select": select},
957
- "Fn::If": {
958
- "Fn::Base64": base64,
959
- "Fn::FindInMap": find_in_map,
960
- "Fn::GetAtt": get_att,
961
- "Fn::GetAZs": get_azs,
962
- "Fn::If": if_,
963
- "Fn::Join": join,
964
- "Fn::Select": select,
965
- "Fn::Sub": sub,
966
- "Ref": ref,
967
- "Fn::ImportValue": import_value,
968
- },
969
- "Fn::Not": ALLOWED_NESTED_CONDITIONS,
970
- "Fn::Or": ALLOWED_NESTED_CONDITIONS,
971
- "Condition": {}, # Only allows strings
972
- "Fn::Base64": ALL_FUNCTIONS,
973
- "Fn::Cidr": {
974
- "Fn::Select": select,
975
- "Ref": ref,
976
- },
977
- "Fn::FindInMap": {
978
- "Fn::FindInMap": find_in_map,
979
- "Ref": ref,
980
- },
981
- "Fn::GetAtt": {}, # This one is complicated =/
982
- "Fn::GetAZs": {
983
- "Ref": ref,
984
- },
985
- "Fn::ImportValue": {
986
- "Fn::Base64": base64,
987
- "Fn::FindInMap": find_in_map,
988
- "Fn::If": if_,
989
- "Fn::Join": join,
990
- "Fn::Select": select,
991
- "Fn::Split": split,
992
- "Fn::Sub": sub,
993
- "Ref": ref,
994
- }, # Import value can't depend on resources (not implemented)
995
- "Fn::Join": {
996
- "Fn::Base64": base64,
997
- "Fn::FindInMap": find_in_map,
998
- "Fn::GetAtt": get_att,
999
- "Fn::GetAZs": get_azs,
1000
- "Fn::If": if_,
1001
- "Fn::ImportValue": import_value,
1002
- "Fn::Join": join,
1003
- "Fn::Split": split,
1004
- "Fn::Select": select,
1005
- "Fn::Sub": sub,
1006
- "Ref": ref,
1007
- },
1008
- "Fn::Select": {
1009
- "Fn::FindInMap": find_in_map,
1010
- "Fn::GetAtt": get_att,
1011
- "Fn::GetAZs": get_azs,
1012
- "Fn::If": if_,
1013
- "Fn::Split": split,
1014
- "Ref": ref,
1015
- },
1016
- "Fn::Split": {
1017
- "Fn::Base64": base64,
1018
- "Fn::FindInMap": find_in_map,
1019
- "Fn::GetAtt": get_att,
1020
- "Fn::GetAZs": get_azs,
1021
- "Fn::If": if_,
1022
- "Fn::ImportValue": import_value,
1023
- "Fn::Join": join,
1024
- "Fn::Split": split,
1025
- "Fn::Select": select,
1026
- "Fn::Sub": sub,
1027
- "Ref": ref,
1028
- },
1029
- "Fn::Sub": {
1030
- "Fn::Base64": base64,
1031
- "Fn::FindInMap": find_in_map,
1032
- "Fn::GetAtt": get_att,
1033
- "Fn::GetAZs": get_azs,
1034
- "Fn::If": if_,
1035
- "Fn::ImportValue": import_value,
1036
- "Fn::Join": join,
1037
- "Fn::Select": select,
1038
- "Ref": ref,
1039
- "Fn::Sub": sub,
1040
- },
1041
- "Fn::Transform": {}, # Transform isn't fully implemented
1042
- "Ref": {}, # String only.
1043
- }
1044
-
1045
943
  # Extra functions that are allowed if the template is using a transform.
1046
944
  TRANSFORMS: Dict[str, Dispatch] = {
1047
945
  "AWS::CodeDeployBlueGreen": {},
@@ -7,40 +7,38 @@ from cloud_radar.cf.unit._template import Template
7
7
 
8
8
  def test_load_allowed_functions_no_transforms():
9
9
  template = Template({})
10
- result = template.load_allowed_functions()
11
- assert result == functions.ALL_FUNCTIONS
10
+ template.load_allowed_functions()
11
+ assert template.allowed_functions == functions.ALL_FUNCTIONS
12
12
 
13
13
 
14
14
  def test_load_allowed_functions_single_transform():
15
15
  template = Template({"Transform": "AWS::Serverless-2016-10-31"})
16
- result = template.load_allowed_functions()
16
+ template.load_allowed_functions()
17
17
  expected = {
18
18
  **functions.ALL_FUNCTIONS,
19
19
  **functions.TRANSFORMS["AWS::Serverless-2016-10-31"],
20
20
  }
21
- assert result == expected
21
+ assert template.allowed_functions == expected
22
22
 
23
23
 
24
24
  def test_load_allowed_functions_multiple_transforms():
25
25
  template = Template({"Transform": ["AWS::Serverless-2016-10-31", "AWS::Include"]})
26
- result = template.load_allowed_functions()
26
+ template.load_allowed_functions()
27
27
  expected = {
28
28
  **functions.ALL_FUNCTIONS,
29
29
  **functions.TRANSFORMS["AWS::Serverless-2016-10-31"],
30
30
  **functions.TRANSFORMS["AWS::Include"],
31
31
  }
32
- assert result == expected
32
+ assert template.allowed_functions == expected
33
33
 
34
34
 
35
35
  def test_load_allowed_functions_invalid_transform():
36
- template = Template({"Transform": "InvalidTransform"})
36
+
37
37
  with pytest.raises(ValueError):
38
- template.load_allowed_functions()
38
+ Template({"Transform": "InvalidTransform"})
39
39
 
40
40
 
41
41
  def test_load_allowed_functions_invalid_transforms():
42
- template = Template(
43
- {"Transform": ["AWS::Serverless-2016-10-31", "InvalidTransform"]}
44
- )
42
+
45
43
  with pytest.raises(ValueError):
46
- template.load_allowed_functions()
44
+ Template({"Transform": ["AWS::Serverless-2016-10-31", "InvalidTransform"]})
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: cloud-radar
3
- Version: 0.14.0a8
3
+ Version: 0.14.0a9
4
4
  Summary: Run functional tests on cloudformation stacks.
5
5
  License: Apache-2.0
6
6
  Keywords: aws,cloudformation,cloud-radar,testing,taskcat,cloud,radar
@@ -9,10 +9,10 @@ cloud_radar/cf/unit/_output.py,sha256=rhQQ4aJu06bxAoG7GOXkuOPzAmLCrTA2Ytb8rNXA4V
9
9
  cloud_radar/cf/unit/_parameter.py,sha256=AdPIqc2ggSW1VR0USF30zjphX3z1HHbGKQt8n-Kzhfo,3199
10
10
  cloud_radar/cf/unit/_resource.py,sha256=dWaR-5s6ea5mIu6Dhf1hY31Wd4WLHbHsbyxnu2Tz6QI,8512
11
11
  cloud_radar/cf/unit/_stack.py,sha256=_S0L9O7Lw-QAJDKubClp2b6UYtYfyzg272_7WQkUdo8,5785
12
- cloud_radar/cf/unit/_template.py,sha256=ESpor5rputwtCKJuvlfp_M0VUuYrciRaLNE8TfdqhRU,32782
13
- cloud_radar/cf/unit/functions.py,sha256=iWBhc9JmyObusAAZ2iAXf7dXof36mdqoHOLR4UzuC58,29234
14
- cloud_radar/cf/unit/test__template.py,sha256=jVPMJTn6Q0sSZ8BjRGyutuR9-NjdHdwDTVsd2kvjQbs,1491
15
- cloud_radar-0.14.0a8.dist-info/LICENSE.txt,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
- cloud_radar-0.14.0a8.dist-info/METADATA,sha256=7Wq8pX3tWCJa_Np9l6NKLb9yclnwFGLcSzVG1h1D-hc,16784
17
- cloud_radar-0.14.0a8.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
18
- cloud_radar-0.14.0a8.dist-info/RECORD,,
12
+ cloud_radar/cf/unit/_template.py,sha256=RSZjqD0FgBYMgyZb_KUkIOaO_mTODLJH9czvhZ_ii3U,32196
13
+ cloud_radar/cf/unit/functions.py,sha256=NSJh14wJK4dmTibmGqB0aK_kAP1RFW9RjdkZZsD11tc,26332
14
+ cloud_radar/cf/unit/test__template.py,sha256=nHc9WziIeGDo0d-rsn3HV4X7BsoKmwwHUxcp3qzuZo8,1414
15
+ cloud_radar-0.14.0a9.dist-info/LICENSE.txt,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
16
+ cloud_radar-0.14.0a9.dist-info/METADATA,sha256=C9i9uowVgleXdUvo0i9lrmbwlSZ9SudJPIEYBCChQGA,16784
17
+ cloud_radar-0.14.0a9.dist-info/WHEEL,sha256=XbeZDeTWKc1w7CSIyre5aMDU_-PohRwTQceYnisIYYY,88
18
+ cloud_radar-0.14.0a9.dist-info/RECORD,,