cfn-check 0.3.2__py3-none-any.whl → 0.3.3__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.
@@ -47,7 +47,7 @@ class Evaluator:
47
47
 
48
48
  composite_keys = updated_keys
49
49
 
50
- assert len(composite_keys) == len(items), f'❌ {len(items)} returned for {len(composite_keys)} keys. Are you sure you used a range ([*]) selector?'
50
+ assert len(composite_keys) == len(items), f'❌ {len(items)} matches returned for {len(composite_keys)} keys. Are you sure you used a range ([*]) selector?'
51
51
 
52
52
  results: list[tuple[str, Data]] = []
53
53
  for idx, item in enumerate(list(items)):
@@ -258,7 +258,10 @@ class Token:
258
258
  return None, None
259
259
 
260
260
  if isinstance(node, dict):
261
- return ['*'], node.values()
261
+ return (
262
+ ['*' for _ in node],
263
+ node.values()
264
+ )
262
265
 
263
266
  elif isinstance(node, list):
264
267
  return (
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cfn-check
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Validate Cloud Formation
5
5
  Author-email: Ada Lundhe <adalundhe@lundhe.audio>
6
6
  License: MIT License
@@ -50,7 +50,7 @@ Dynamic: license-file
50
50
 
51
51
  | Package | cfn-check |
52
52
  | ----------- | ----------- |
53
- | Version | 0.3.2 |
53
+ | Version | 0.3.3 |
54
54
  | Download | https://pypi.org/project/cfn-check/ |
55
55
  | Source | https://github.com/adalundhe/cfn-check |
56
56
  | Keywords | cloud-formation, testing, aws, cli |
@@ -537,5 +537,51 @@ With Nested Ranges, this can be shortened to:
537
537
 
538
538
  ```
539
539
  Resources::AppendItemToListFunction::Properties::Code::ZipFile::[[]]
540
+ ```
540
541
 
541
542
  Which is both more concise *and* more representitave of our intention to select only the array.
543
+
544
+ <br/>
545
+
546
+ # Using Pydantic Models
547
+
548
+ In addition to traditional `pytest`-like assert statements, `cfn-lint` can validate results returned by queries via `Pydantic` models.
549
+
550
+ For example, consider again the initial example where we validate the `Type` field of `Resource` objects.
551
+
552
+ ```python
553
+ from cfn_check import Collection, Rule
554
+
555
+
556
+ class ValidateResourceType(Collection):
557
+
558
+ @Rule(
559
+ "Resources::*::Type",
560
+ "It checks Resource::Type is correctly definined",
561
+ )
562
+ def validate_test(self, value: str):
563
+ assert value is not None, '❌ Resource Type not defined'
564
+ assert isinstance(value, str), '❌ Resource Type not a string'
565
+ ```
566
+
567
+ Rather than explicitly querying for the type field and writing assertions, we can instead define a `Pydantic` schema, then pass all `Resource` objects to that schema by specifying it as a Python type hint in our `Rule` method's signature.
568
+
569
+ ```python
570
+ from cfn_check import Collection, Rule
571
+ from pydantic import BaseModel, StrictStr
572
+
573
+ class Resource(BaseModel):
574
+ Type: StrictStr
575
+
576
+
577
+ class ValidateResourceType(Collection):
578
+
579
+ @Rule(
580
+ "Resources::*",
581
+ "It checks Resource::Type is correctly definined",
582
+ )
583
+ def validate_test(self, value: Resource):
584
+ assert value is not None
585
+ ```
586
+
587
+ By deferring type and existence assertions to `Pydantic` models, you can focus your actual assertion logic on business/security policy checks.
@@ -9,11 +9,11 @@ cfn_check/collection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hS
9
9
  cfn_check/collection/collection.py,sha256=wNxahoOqQge3C56blz5VtOq6lX5MZ9F2JjQIyZ3_SxU,27
10
10
  cfn_check/evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  cfn_check/evaluation/errors.py,sha256=yPJdtRYo67le4yMC9sYqcboCnkqKsJ3KPbSPFY2-Pi8,773
12
- cfn_check/evaluation/evaluator.py,sha256=weFBAYKVc9TjTB2zNMIVX77Bi9kIaWp2KRJa1ISSLNs,2240
12
+ cfn_check/evaluation/evaluator.py,sha256=RomoSlgimTNTjaUE0BdSslrPvPbFj6X8ScFinatERjs,2248
13
13
  cfn_check/evaluation/validate.py,sha256=yy8byYAoHxFqkS2HfewHup22B3bYtrUH2PhPuNAc--A,1547
14
14
  cfn_check/evaluation/parsing/__init__.py,sha256=s5TxU4mzsbNIpbMynbwibGR8ac0dTcf_2qUfGkAEDvQ,52
15
15
  cfn_check/evaluation/parsing/query_parser.py,sha256=4J3CJQKAyb11gugfx6OZT-mfSdNDB5Al8Jiy9DbJZMw,3459
16
- cfn_check/evaluation/parsing/token.py,sha256=_mf1hMnnu5TFXvnyfxAy-GjdVW9kvhgv1NLaSh4GF4k,6993
16
+ cfn_check/evaluation/parsing/token.py,sha256=nrg7Tca182WY0VhRqfsZ1UgpxsUX73vdLToSeK50DZE,7055
17
17
  cfn_check/evaluation/parsing/token_type.py,sha256=E5AVBerinBszMLjjc7ejwSSWEc0p0Ju_CNFhpoZi63c,325
18
18
  cfn_check/loader/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  cfn_check/loader/loader.py,sha256=7yiDLLW_vNp_8O47erLXjQQtAB47fU3nimb91N5N_R8,532
@@ -25,10 +25,11 @@ cfn_check/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,
25
25
  cfn_check/shared/types.py,sha256=-om3DyZsjK_tJd-I8SITkoE55W0nB2WA3LOc87Cs7xI,414
26
26
  cfn_check/validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
27
  cfn_check/validation/validator.py,sha256=FGPeb8Uc8lvX3Y5rs-fxeJKIOqzUXwXh_gCFcy6d3b0,1182
28
- cfn_check-0.3.2.dist-info/licenses/LICENSE,sha256=EbCpGNzOkyQ53ig7J2Iwgmy4Og0dgHe8COo3WylhIKk,1069
28
+ cfn_check-0.3.3.dist-info/licenses/LICENSE,sha256=EbCpGNzOkyQ53ig7J2Iwgmy4Og0dgHe8COo3WylhIKk,1069
29
+ example/pydantic_rules.py,sha256=oWBBGBauSwRbrvZSYBk4ej3dsCY55zm3cHwl8vH_2lU,350
29
30
  example/rules.py,sha256=mWHB0DK283lb0CeSHgnyO5qiVTJJpybuwWXb4Yoa3zQ,3148
30
- cfn_check-0.3.2.dist-info/METADATA,sha256=aAqR3dS-h4J_kHL4K6vCtl2DSFgYvOCHps_PvoraX5Q,19047
31
- cfn_check-0.3.2.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
32
- cfn_check-0.3.2.dist-info/entry_points.txt,sha256=B4lCHoDHmwisABxKgRLShwqqFv7QwwDAFXoAChOnkwg,53
33
- cfn_check-0.3.2.dist-info/top_level.txt,sha256=hUn9Ya50yY1fpgWxEhG5iMgfMDDVX7qWQnM1xrgZnhM,18
34
- cfn_check-0.3.2.dist-info/RECORD,,
31
+ cfn_check-0.3.3.dist-info/METADATA,sha256=-ElH6YysxwAbW9jdR5tpNn-CAQa3Z8NUY7vE5GzB77g,20459
32
+ cfn_check-0.3.3.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
33
+ cfn_check-0.3.3.dist-info/entry_points.txt,sha256=B4lCHoDHmwisABxKgRLShwqqFv7QwwDAFXoAChOnkwg,53
34
+ cfn_check-0.3.3.dist-info/top_level.txt,sha256=hUn9Ya50yY1fpgWxEhG5iMgfMDDVX7qWQnM1xrgZnhM,18
35
+ cfn_check-0.3.3.dist-info/RECORD,,
@@ -0,0 +1,15 @@
1
+ from cfn_check import Collection, Rule
2
+ from pydantic import BaseModel, StrictStr
3
+
4
+ class Resource(BaseModel):
5
+ Type: StrictStr
6
+
7
+
8
+ class ValidateResourceType(Collection):
9
+
10
+ @Rule(
11
+ "Resources::*",
12
+ "It checks Resource::Type is correctly definined",
13
+ )
14
+ def validate_test(self, value: Resource):
15
+ assert value is not None