Skip to content

Commit 5eb8e45

Browse files
authored
Create a schema manager for non resource schemas (#4131)
* Create a schema manager for non resource schemas
1 parent ceb30ae commit 5eb8e45

30 files changed

+579
-228
lines changed

src/cfnlint/rules/functions/Base64.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
SPDX-License-Identifier: MIT-0
44
"""
55

6-
import cfnlint.data.schemas.other.functions
76
from cfnlint.helpers import FUNCTIONS_SINGLE
8-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails
7+
from cfnlint.rules.functions._BaseFn import BaseFn
98

109

1110
class Base64(BaseFn):
@@ -22,8 +21,5 @@ def __init__(self) -> None:
2221
"Fn::Base64",
2322
("string",),
2423
tuple(FUNCTIONS_SINGLE),
25-
schema_details=SchemaDetails(
26-
cfnlint.data.schemas.other.functions, "base64.json"
27-
),
2824
)
2925
self.fn_base64 = self.validate

src/cfnlint/rules/functions/Cidr.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
from __future__ import annotations
77

8-
import cfnlint.data.schemas.other.functions
9-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails
8+
from cfnlint.rules.functions._BaseFn import BaseFn
109

1110

1211
class Cidr(BaseFn):
@@ -23,8 +22,5 @@ def __init__(self) -> None:
2322
"Fn::Cidr",
2423
("array",),
2524
None,
26-
schema_details=SchemaDetails(
27-
cfnlint.data.schemas.other.functions, "cidr.json"
28-
),
2925
)
3026
self.fn_cidr = self.validate

src/cfnlint/rules/functions/FindInMap.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
from __future__ import annotations
77

8-
import cfnlint.data.schemas.other.functions
9-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails, singular_types
8+
from cfnlint.rules.functions._BaseFn import BaseFn, singular_types
109

1110

1211
class FindInMap(BaseFn):
@@ -22,9 +21,6 @@ def __init__(self) -> None:
2221
super().__init__(
2322
"Fn::FindInMap",
2423
("array",) + singular_types,
25-
schema_details=SchemaDetails(
26-
cfnlint.data.schemas.other.functions, "findinmap.json"
27-
),
2824
resolved_rule="W1034",
2925
)
3026
self.fn_findinmap = self.validate

src/cfnlint/rules/functions/GetAtt.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@
1010

1111
import regex as re
1212

13-
import cfnlint.data.schemas.other.functions
1413
from cfnlint.helpers import ensure_list, is_types_compatible
1514
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
16-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails, all_types
15+
from cfnlint.rules.functions._BaseFn import BaseFn, all_types
1716
from cfnlint.schema import PROVIDER_SCHEMA_MANAGER
1817

1918

@@ -33,9 +32,6 @@ def __init__(self) -> None:
3332
super().__init__(
3433
"Fn::GetAtt",
3534
all_types,
36-
schema_details=SchemaDetails(
37-
cfnlint.data.schemas.other.functions, "getatt.json"
38-
),
3935
)
4036

4137
def _resolve_getatt(

src/cfnlint/rules/functions/If.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@
88
from collections import deque
99
from typing import Any
1010

11-
import cfnlint.data.schemas.other.functions
1211
from cfnlint.context.conditions.exceptions import Unsatisfiable
1312
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
14-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails, all_types
13+
from cfnlint.rules.functions._BaseFn import BaseFn, all_types
1514

1615

1716
class If(BaseFn):
@@ -27,9 +26,6 @@ def __init__(self) -> None:
2726
super().__init__(
2827
"Fn::If",
2928
all_types,
30-
schema_details=SchemaDetails(
31-
cfnlint.data.schemas.other.functions, "if.json"
32-
),
3329
)
3430
self.child_rules["W1028"] = None
3531

src/cfnlint/rules/functions/ImportValue.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@
55

66
from typing import Any, Iterator
77

8-
import cfnlint.data.schemas.other.functions
98
from cfnlint.jsonschema import ValidationError, Validator
10-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails, singular_types
9+
from cfnlint.rules.functions._BaseFn import BaseFn, singular_types
1110

1211

1312
class ImportValue(BaseFn):
@@ -23,9 +22,6 @@ def __init__(self) -> None:
2322
super().__init__(
2423
"Fn::ImportValue",
2524
singular_types,
26-
schema_details=SchemaDetails(
27-
cfnlint.data.schemas.other.functions, "importvalue.json"
28-
),
2925
)
3026
self.child_rules = {
3127
"W6001": None,

src/cfnlint/rules/functions/Join.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77

88
from typing import Any
99

10-
import cfnlint.data.schemas.other.functions
1110
from cfnlint.jsonschema import ValidationResult
1211
from cfnlint.jsonschema.protocols import Validator
13-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails
12+
from cfnlint.rules.functions._BaseFn import BaseFn
1413

1514

1615
class Join(BaseFn):
@@ -27,9 +26,6 @@ def __init__(self) -> None:
2726
"Fn::Join",
2827
("string",),
2928
resolved_rule="W1032",
30-
schema_details=SchemaDetails(
31-
cfnlint.data.schemas.other.functions, "join.json"
32-
),
3329
)
3430
self.child_rules.update(
3531
{

src/cfnlint/rules/functions/Length.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,8 @@
77

88
from typing import Any
99

10-
import cfnlint.data.schemas.other.functions
1110
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
12-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails
11+
from cfnlint.rules.functions._BaseFn import BaseFn
1312

1413

1514
class Length(BaseFn):
@@ -25,9 +24,6 @@ def __init__(self) -> None:
2524
super().__init__(
2625
"Fn::Length",
2726
("integer",),
28-
schema_details=SchemaDetails(
29-
cfnlint.data.schemas.other.functions, "length.json"
30-
),
3127
)
3228

3329
def fn_length(

src/cfnlint/rules/functions/Ref.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77

88
from typing import Any
99

10-
import cfnlint.data.schemas.other.functions
1110
from cfnlint.helpers import VALID_PARAMETER_TYPES, VALID_PARAMETER_TYPES_LIST
1211
from cfnlint.jsonschema import ValidationError, Validator
13-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails, all_types
12+
from cfnlint.rules.functions._BaseFn import BaseFn, all_types
1413

1514

1615
class Ref(BaseFn):
@@ -27,9 +26,6 @@ def __init__(self) -> None:
2726
"Ref",
2827
all_types,
2928
resolved_rule="W1030",
30-
schema_details=SchemaDetails(
31-
cfnlint.data.schemas.other.functions, "ref.json"
32-
),
3329
)
3430
self._all_refs = [
3531
"W2010",

src/cfnlint/rules/functions/Select.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55

66
from __future__ import annotations
77

8-
import cfnlint.data.schemas.other.functions
9-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails, all_types
8+
from cfnlint.rules.functions._BaseFn import BaseFn, all_types
109

1110

1211
class Select(BaseFn):
@@ -22,9 +21,6 @@ def __init__(self) -> None:
2221
super().__init__(
2322
"Fn::Select",
2423
all_types,
25-
schema_details=SchemaDetails(
26-
cfnlint.data.schemas.other.functions, "select.json"
27-
),
2824
resolved_rule="W1035",
2925
)
3026
self.fn_select = self.validate

src/cfnlint/rules/functions/Split.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,9 @@
1111

1212
import regex as re
1313

14-
import cfnlint.data.schemas.other.functions
1514
from cfnlint.helpers import REGEX_DYN_REF
1615
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
17-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails
16+
from cfnlint.rules.functions._BaseFn import BaseFn
1817

1918

2019
class Split(BaseFn):
@@ -30,9 +29,6 @@ def __init__(self) -> None:
3029
super().__init__(
3130
"Fn::Split",
3231
("array",),
33-
schema_details=SchemaDetails(
34-
cfnlint.data.schemas.other.functions, "split.json"
35-
),
3632
resolved_rule="W1033",
3733
)
3834

src/cfnlint/rules/functions/Sub.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,9 @@
1010

1111
import regex as re
1212

13-
import cfnlint.data.schemas.other.functions
1413
from cfnlint.helpers import REGEX_SUB_PARAMETERS, is_function
1514
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
16-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails
15+
from cfnlint.rules.functions._BaseFn import BaseFn
1716

1817

1918
class Sub(BaseFn):
@@ -30,9 +29,6 @@ def __init__(self) -> None:
3029
"Fn::Sub",
3130
("string",),
3231
resolved_rule="W1031",
33-
schema_details=SchemaDetails(
34-
cfnlint.data.schemas.other.functions, "sub.json"
35-
),
3632
)
3733
self.child_rules.update(
3834
{

src/cfnlint/rules/functions/ToJsonString.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@
77

88
from typing import Any
99

10-
import cfnlint.data.schemas.other.functions
1110
from cfnlint.helpers import TRANSFORM_LANGUAGE_EXTENSION
1211
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
13-
from cfnlint.rules.functions._BaseFn import BaseFn, SchemaDetails
12+
from cfnlint.rules.functions._BaseFn import BaseFn
1413

1514

1615
class ToJsonString(BaseFn):
@@ -27,9 +26,6 @@ def __init__(self) -> None:
2726
"Fn::ToJsonString",
2827
("string",),
2928
resolved_rule="W1040",
30-
schema_details=SchemaDetails(
31-
cfnlint.data.schemas.other.functions, "tojsonstring.json"
32-
),
3329
)
3430

3531
def fn_tojsonstring(

src/cfnlint/rules/functions/_BaseFn.py

+5-12
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,10 @@
88
from collections import deque
99
from typing import Any, Tuple
1010

11-
import jsonpatch
12-
1311
from cfnlint.helpers import ToPy, ensure_list, is_types_compatible
1412
from cfnlint.jsonschema import ValidationError, ValidationResult, Validator
1513
from cfnlint.rules.jsonschema.CfnLintJsonSchema import CfnLintJsonSchema, SchemaDetails
14+
from cfnlint.schema import OTHER_SCHEMA_MANAGER
1615
from cfnlint.schema.resolver import RefResolver
1716

1817
all_types = ("array", "boolean", "integer", "number", "object", "string")
@@ -34,16 +33,10 @@ def __init__(
3433
self.functions = functions or tuple([])
3534
self.resolved_rule = resolved_rule
3635
self.child_rules[self.resolved_rule] = None
37-
self.config_definition = {
38-
"patches": {"default": [], "type": "list", "itemtype": "object"}
39-
}
40-
41-
def configure(self, configs=None, experimental=False):
42-
super().configure(configs, experimental)
43-
44-
jsonpatch.JsonPatch(self.config.get("patches")).apply(
45-
self._schema, in_place=True
46-
)
36+
if name and name != "Fn::GetAZs":
37+
self._schema = OTHER_SCHEMA_MANAGER.get_schema(
38+
f"other.functions.{name.replace('Fn::', '').lower()}"
39+
)
4740

4841
def key_value(self, instance: dict[str, Any]) -> Tuple[str, Any]:
4942
return list(instance.keys())[0], instance.get(self.fn.name)

src/cfnlint/runner.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from cfnlint.helpers import REGIONS
2424
from cfnlint.rules import Match, Rules
2525
from cfnlint.rules.errors import ConfigError, ParseError, TransformError
26-
from cfnlint.schema import PROVIDER_SCHEMA_MANAGER
26+
from cfnlint.schema import PROVIDER_SCHEMA_MANAGER, patch
2727
from cfnlint.template.template import Template
2828

2929
LOGGER = logging.getLogger(__name__)
@@ -241,9 +241,7 @@ def __init__(self, config: ConfigMixIn) -> None:
241241
PROVIDER_SCHEMA_MANAGER.load_registry_schemas(path)
242242
# now we can patch after loading all registry schemas
243243
if self.config.override_spec:
244-
PROVIDER_SCHEMA_MANAGER.patch(
245-
self.config.override_spec, self.config.regions
246-
)
244+
patch(self.config.override_spec, self.config.regions)
247245

248246
def _get_rules(self) -> None:
249247
"""

src/cfnlint/schema/__init__.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@
44
"GetAtt",
55
"GetAttType",
66
"PROVIDER_SCHEMA_MANAGER",
7+
"OTHER_SCHEMA_MANAGER",
78
"Schema",
89
"SchemaPatch",
10+
"patch",
11+
"reset",
912
]
1013

1114
from cfnlint.schema._exceptions import ResourceNotFoundError
1215
from cfnlint.schema._getatts import AttributeDict
16+
from cfnlint.schema._patch import SchemaPatch, patch, reset
1317
from cfnlint.schema._schema import Schema
1418
from cfnlint.schema.manager import PROVIDER_SCHEMA_MANAGER
15-
from cfnlint.schema.patch import SchemaPatch
19+
from cfnlint.schema.other_schema_manager import OTHER_SCHEMA_MANAGER

src/cfnlint/schema/_exceptions.py

+5
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,8 @@
99
class ResourceNotFoundError(Exception):
1010
def __init__(self, resource_type: str, region: str):
1111
super().__init__(f"Resource type '{resource_type}' is not found in '{region}'")
12+
13+
14+
class SchemaNotFoundError(Exception):
15+
def __init__(self, path: str):
16+
super().__init__(f"Schema '{path}' is not found")

0 commit comments

Comments
 (0)