cfn-check 0.1.1__py3-none-any.whl → 0.2.1__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 cfn-check might be problematic. Click here for more details.
- cfn_check/__init__.py +1 -1
- cfn_check/cli/utils/attributes.py +2 -2
- cfn_check/cli/utils/files.py +50 -2
- cfn_check/cli/validate.py +3 -3
- cfn_check/collection/__init__.py +0 -0
- cfn_check/collection/collection.py +2 -0
- {cfn_check-0.1.1.dist-info → cfn_check-0.2.1.dist-info}/METADATA +9 -9
- {cfn_check-0.1.1.dist-info → cfn_check-0.2.1.dist-info}/RECORD +13 -12
- example/rules.py +2 -2
- cfn_check/rules/rules.py +0 -2
- {cfn_check-0.1.1.dist-info → cfn_check-0.2.1.dist-info}/WHEEL +0 -0
- {cfn_check-0.1.1.dist-info → cfn_check-0.2.1.dist-info}/entry_points.txt +0 -0
- {cfn_check-0.1.1.dist-info → cfn_check-0.2.1.dist-info}/licenses/LICENSE +0 -0
- {cfn_check-0.1.1.dist-info → cfn_check-0.2.1.dist-info}/top_level.txt +0 -0
cfn_check/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
from .
|
|
1
|
+
from .collection.collection import Collection as Collection
|
|
2
2
|
from .rules.rule import Rule as Rule
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from cfn_check.
|
|
1
|
+
from cfn_check.collection.collection import Collection
|
|
2
2
|
from cfn_check.validation.validator import Validator
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
def bind(
|
|
6
|
-
rule_set:
|
|
6
|
+
rule_set: Collection,
|
|
7
7
|
validation: Validator
|
|
8
8
|
):
|
|
9
9
|
validation.func = validation.func.__get__(rule_set, rule_set.__class__)
|
cfn_check/cli/utils/files.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
|
|
2
2
|
import asyncio
|
|
3
3
|
import os
|
|
4
|
+
import pathlib
|
|
4
5
|
import yaml
|
|
5
6
|
from cfn_check.loader.loader import (
|
|
6
7
|
Loader,
|
|
@@ -9,23 +10,62 @@ from cfn_check.loader.loader import (
|
|
|
9
10
|
)
|
|
10
11
|
from cfn_check.shared.types import YamlObject, Data
|
|
11
12
|
|
|
12
|
-
def open_template(path: str) -> YamlObject |
|
|
13
|
+
def open_template(path: str) -> YamlObject | None:
|
|
14
|
+
|
|
15
|
+
if os.path.exists(path) is False:
|
|
16
|
+
return None
|
|
17
|
+
|
|
13
18
|
try:
|
|
14
19
|
with open(path, 'r') as f:
|
|
15
20
|
return yaml.load(f, Loader=Loader)
|
|
16
|
-
except
|
|
21
|
+
except Exception as e:
|
|
17
22
|
raise e
|
|
18
23
|
|
|
19
24
|
def is_file(path: str) -> bool:
|
|
20
25
|
return os.path.isdir(path) is False
|
|
21
26
|
|
|
22
27
|
|
|
28
|
+
async def path_exists(path: str, loop: asyncio.AbstractEventLoop):
|
|
29
|
+
return await loop.run_in_executor(
|
|
30
|
+
None,
|
|
31
|
+
os.path.exists,
|
|
32
|
+
path,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
async def convert_to_cwd(loop: asyncio.AbstractEventLoop):
|
|
36
|
+
return await loop.run_in_executor(
|
|
37
|
+
None,
|
|
38
|
+
os.getcwd,
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
async def localize_path(path: str, loop: asyncio.AbstractEventLoop):
|
|
42
|
+
localized = path.replace('~/', '')
|
|
43
|
+
|
|
44
|
+
home_directory = await loop.run_in_executor(
|
|
45
|
+
None,
|
|
46
|
+
pathlib.Path.home,
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
return await loop.run_in_executor(
|
|
50
|
+
None,
|
|
51
|
+
os.path.join,
|
|
52
|
+
home_directory,
|
|
53
|
+
localized,
|
|
54
|
+
)
|
|
55
|
+
|
|
23
56
|
async def load_templates(
|
|
24
57
|
path: str,
|
|
25
58
|
tags: list[str],
|
|
26
59
|
file_pattern: str | None = None,
|
|
27
60
|
):
|
|
61
|
+
|
|
28
62
|
loop = asyncio.get_event_loop()
|
|
63
|
+
|
|
64
|
+
if path == '.':
|
|
65
|
+
path = await convert_to_cwd(loop)
|
|
66
|
+
|
|
67
|
+
elif path.startswith('~/'):
|
|
68
|
+
path = await localize_path(path, loop)
|
|
29
69
|
|
|
30
70
|
if await loop.run_in_executor(
|
|
31
71
|
None,
|
|
@@ -36,6 +76,8 @@ async def load_templates(
|
|
|
36
76
|
path,
|
|
37
77
|
]
|
|
38
78
|
|
|
79
|
+
assert await path_exists(path) is True, f'❌ Template at {path} does not exist'
|
|
80
|
+
|
|
39
81
|
elif file_pattern:
|
|
40
82
|
|
|
41
83
|
template_filepaths = await loop.run_in_executor(
|
|
@@ -65,4 +107,10 @@ async def load_templates(
|
|
|
65
107
|
) for template_path in template_filepaths
|
|
66
108
|
])
|
|
67
109
|
|
|
110
|
+
found_templates = [
|
|
111
|
+
template for template in templates if template is not None
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
assert len(found_templates) > 0, "❌ Could not open any templates"
|
|
115
|
+
|
|
68
116
|
return templates
|
cfn_check/cli/validate.py
CHANGED
|
@@ -7,7 +7,7 @@ from cfn_check.cli.utils.attributes import bind
|
|
|
7
7
|
from cfn_check.cli.utils.files import load_templates
|
|
8
8
|
from cfn_check.evaluation.validate import run_validations
|
|
9
9
|
from cfn_check.logging.models import InfoLog
|
|
10
|
-
from cfn_check.
|
|
10
|
+
from cfn_check.collection.collection import Collection
|
|
11
11
|
from cfn_check.validation.validator import Validator
|
|
12
12
|
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ from cfn_check.validation.validator import Validator
|
|
|
15
15
|
async def validate(
|
|
16
16
|
path: str,
|
|
17
17
|
file_pattern: str | None = None,
|
|
18
|
-
rules: ImportType[
|
|
18
|
+
rules: ImportType[Collection] = None,
|
|
19
19
|
tags: list[str] = [
|
|
20
20
|
'Ref',
|
|
21
21
|
'Sub',
|
|
@@ -38,7 +38,7 @@ async def validate(
|
|
|
38
38
|
'''
|
|
39
39
|
Validate Cloud Foundation
|
|
40
40
|
|
|
41
|
-
@param rules Path to a file containing
|
|
41
|
+
@param rules Path to a file containing Collections
|
|
42
42
|
@param file_pattern A string pattern used to find template files
|
|
43
43
|
@param tags List of CloudFormation intrinsic function tags
|
|
44
44
|
@param log_level The log level to use
|
|
File without changes
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cfn-check
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Validate Cloud Formation
|
|
5
5
|
Author-email: Ada Lundhe <adalundhe@lundhe.audio>
|
|
6
6
|
License: MIT License
|
|
@@ -39,7 +39,7 @@ Requires-Dist: hyperlight-cocoa
|
|
|
39
39
|
Requires-Dist: async-logging
|
|
40
40
|
Dynamic: license-file
|
|
41
41
|
|
|
42
|
-
# <b>CFN
|
|
42
|
+
# <b>CFN-Check</b>
|
|
43
43
|
<b>A tool for checking CloudFormation</b>
|
|
44
44
|
|
|
45
45
|
[](https://pypi.org/project/cfn-check/)
|
|
@@ -48,16 +48,16 @@ Dynamic: license-file
|
|
|
48
48
|
[](https://pypi.org/project/cfn-check/)
|
|
49
49
|
|
|
50
50
|
|
|
51
|
-
| Package |
|
|
51
|
+
| Package | cfn-check |
|
|
52
52
|
| ----------- | ----------- |
|
|
53
|
-
| Version | 0.
|
|
53
|
+
| Version | 0.2.0 |
|
|
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 |
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
CFN-Check is a small, fast, friendly tool for validating AWS CloudFormation YAML templates. It is code-driven, with
|
|
60
|
-
rules written as simple, `Rule` decorator wrapped python class methods for `
|
|
60
|
+
rules written as simple, `Rule` decorator wrapped python class methods for `Collection`-inheriting classes.
|
|
61
61
|
|
|
62
62
|
<br/>
|
|
63
63
|
|
|
@@ -88,7 +88,7 @@ Cloud Formation easy while offering both CLI and Python API interfaces.
|
|
|
88
88
|
|
|
89
89
|
- `Python 3.12`
|
|
90
90
|
- Any number of valid CloudFormation templates or a path to said templates.
|
|
91
|
-
- A `.py` file containing at least one `
|
|
91
|
+
- A `.py` file containing at least one `Collection` class with at least one valid `@Rule()` decorated method
|
|
92
92
|
|
|
93
93
|
To get started (we recommend using `uv`), run:
|
|
94
94
|
|
|
@@ -106,10 +106,10 @@ Next open the `rules.py` file and create a basic Python class
|
|
|
106
106
|
as below.
|
|
107
107
|
|
|
108
108
|
```python
|
|
109
|
-
from cfn_check import
|
|
109
|
+
from cfn_check import Collection, Rule
|
|
110
110
|
|
|
111
111
|
|
|
112
|
-
class ValidateResourceType(
|
|
112
|
+
class ValidateResourceType(Collection):
|
|
113
113
|
|
|
114
114
|
@Rule(
|
|
115
115
|
"Resources::*::Type",
|
|
@@ -241,7 +241,7 @@ cfn-lint validate -r rules.py template.yaml
|
|
|
241
241
|
which outputs:
|
|
242
242
|
|
|
243
243
|
```
|
|
244
|
-
2025-09-17T01:46:41.542078+00:00 - INFO - 19783474 - /Users/adalundhe/Documents/
|
|
244
|
+
2025-09-17T01:46:41.542078+00:00 - INFO - 19783474 - /Users/adalundhe/Documents/adalundhe/cfn-check/cfn_check/cli/validate.py:validate.80 - ✅ 1 validations met for 1 templates
|
|
245
245
|
```
|
|
246
246
|
|
|
247
247
|
Congrats! You've just made the cloud a bit better place!
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
cfn_check/__init__.py,sha256=
|
|
1
|
+
cfn_check/__init__.py,sha256=ccUo2YxBmuEmak1M5o-8J0ECLXNkDDUsLJ4mkm31GvU,96
|
|
2
2
|
cfn_check/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
3
3
|
cfn_check/cli/root.py,sha256=dHq9zzXyj-Wrj-fzirtFjptShzWbBGsO3n9tspm-pec,1688
|
|
4
|
-
cfn_check/cli/validate.py,sha256=
|
|
4
|
+
cfn_check/cli/validate.py,sha256=e20Hyfs3GJSrBbMRPt8dy3L0yjVnYo36ol_zOVhZco8,2013
|
|
5
5
|
cfn_check/cli/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
cfn_check/cli/utils/attributes.py,sha256=
|
|
7
|
-
cfn_check/cli/utils/files.py,sha256=
|
|
6
|
+
cfn_check/cli/utils/attributes.py,sha256=iIUIgl6cT5XEUOW7D54-xxmMpTis84ySQY1b9osB47E,339
|
|
7
|
+
cfn_check/cli/utils/files.py,sha256=pkN-3jqI2cwiCBhnKYmaoEPqFw_qypOhKlLk-SvINFw,2557
|
|
8
|
+
cfn_check/collection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
|
+
cfn_check/collection/collection.py,sha256=wNxahoOqQge3C56blz5VtOq6lX5MZ9F2JjQIyZ3_SxU,27
|
|
8
10
|
cfn_check/evaluation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
9
11
|
cfn_check/evaluation/check.py,sha256=5GgoZY0YfyOeOP92VJVH4Y3AYB7jUGjxwsr0qsbVGeo,414
|
|
10
12
|
cfn_check/evaluation/errors.py,sha256=yPJdtRYo67le4yMC9sYqcboCnkqKsJ3KPbSPFY2-Pi8,773
|
|
@@ -16,15 +18,14 @@ cfn_check/logging/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
|
|
|
16
18
|
cfn_check/logging/models.py,sha256=-tBaK6p8mJ0cO8h2keEJ-VmtFX_VW4XzwAw2PtqbkF0,490
|
|
17
19
|
cfn_check/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
18
20
|
cfn_check/rules/rule.py,sha256=r6-eKCUdPaNIena2NDv3J_QlcWes1KLObI9ukRZZz1o,500
|
|
19
|
-
cfn_check/rules/rules.py,sha256=d7VvF6nlXER1puY9lEbQjFQv7RJMmD-wF4RoDCm8mQ0,22
|
|
20
21
|
cfn_check/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
21
22
|
cfn_check/shared/types.py,sha256=-om3DyZsjK_tJd-I8SITkoE55W0nB2WA3LOc87Cs7xI,414
|
|
22
23
|
cfn_check/validation/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
23
24
|
cfn_check/validation/validator.py,sha256=FGPeb8Uc8lvX3Y5rs-fxeJKIOqzUXwXh_gCFcy6d3b0,1182
|
|
24
|
-
cfn_check-0.
|
|
25
|
-
example/rules.py,sha256=
|
|
26
|
-
cfn_check-0.
|
|
27
|
-
cfn_check-0.
|
|
28
|
-
cfn_check-0.
|
|
29
|
-
cfn_check-0.
|
|
30
|
-
cfn_check-0.
|
|
25
|
+
cfn_check-0.2.1.dist-info/licenses/LICENSE,sha256=EbCpGNzOkyQ53ig7J2Iwgmy4Og0dgHe8COo3WylhIKk,1069
|
|
26
|
+
example/rules.py,sha256=XVsOkY5gxEier6oVyMVwuJ3ftwbv987udEkg2qZe_Zs,369
|
|
27
|
+
cfn_check-0.2.1.dist-info/METADATA,sha256=c7EmyUA8rmPum59hiaXuyULhPWlrQVbwxssUl3Obgt0,8472
|
|
28
|
+
cfn_check-0.2.1.dist-info/WHEEL,sha256=zaaOINJESkSfm_4HQVc5ssNzHCPXhJm0kEUakpsEHaU,91
|
|
29
|
+
cfn_check-0.2.1.dist-info/entry_points.txt,sha256=B4lCHoDHmwisABxKgRLShwqqFv7QwwDAFXoAChOnkwg,53
|
|
30
|
+
cfn_check-0.2.1.dist-info/top_level.txt,sha256=hUn9Ya50yY1fpgWxEhG5iMgfMDDVX7qWQnM1xrgZnhM,18
|
|
31
|
+
cfn_check-0.2.1.dist-info/RECORD,,
|
example/rules.py
CHANGED
cfn_check/rules/rules.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|