Skip to content

Commit 2e2034c

Browse files
authored
Load registry schemas if type match (#3450)
* Load registry schemas if type match
1 parent 36ff520 commit 2e2034c

File tree

5 files changed

+57
-34
lines changed

5 files changed

+57
-34
lines changed

src/cfnlint/rules/resources/PrimaryIdentifiers.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,9 @@ def match(self, cfn: Template) -> RuleMatches:
145145
# by the customer so if any primary identifiers are read
146146
# only we have to skip evaluation
147147
primary_ids = schema.schema.get("primaryIdentifier", [])
148+
if not primary_ids:
149+
continue
150+
148151
read_only_ids = schema.schema.get("readOnlyProperties", [])
149152

150153
if any(id in read_only_ids for id in primary_ids):

src/cfnlint/schema/manager.py

Lines changed: 33 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -152,47 +152,49 @@ def get_resource_schema(self, region: str, resource_type: str) -> Schema:
152152
Returns:
153153
dict: returns the schema
154154
"""
155-
resource_type = self._normalize_resource_type(resource_type)
155+
if resource_type not in self._registry_schemas:
156+
resource_type = self._normalize_resource_type(resource_type)
156157

157158
if resource_type in self._removed_types:
158159
raise ResourceNotFoundError(resource_type, region)
159160

160161
reg = ToPy(region)
161162
rt = ToPy(resource_type)
162163

163-
schema = self._schemas[reg.name].get(resource_type)
164-
if schema is None:
165-
# dynamically import the modules as needed
166-
self._provider_schema_modules[reg.name] = __import__(
167-
f"{self._root.module}.{reg.py}", fromlist=[""]
168-
)
169-
# check cfn-lint provided schemas
170-
if resource_type in self._registry_schemas:
171-
self._schemas[reg.name][rt.name] = self._registry_schemas[rt.name]
172-
return self._schemas[reg.name][rt.name]
173-
174-
# load the schema
175-
if f"{rt.provider}.json" in self._provider_schema_modules[reg.name].cached:
176-
schema_cached = copy(
177-
self.get_resource_schema(
178-
region=self._region_primary.name,
179-
resource_type=rt.name,
180-
)
164+
schema = self._schemas[reg.name].get(rt.name)
165+
if schema is not None:
166+
return schema
167+
168+
# dynamically import the modules as needed
169+
self._provider_schema_modules[reg.name] = __import__(
170+
f"{self._root.module}.{reg.py}", fromlist=[""]
171+
)
172+
# check cfn-lint provided schemas
173+
if rt.name in self._registry_schemas:
174+
self._schemas[reg.name][rt.name] = self._registry_schemas[rt.name]
175+
return self._schemas[reg.name][rt.name]
176+
177+
# load the schema
178+
if f"{rt.provider}.json" in self._provider_schema_modules[reg.name].cached:
179+
schema_cached = copy(
180+
self.get_resource_schema(
181+
region=self._region_primary.name,
182+
resource_type=rt.name,
181183
)
182-
schema_cached.is_cached = True
183-
self._schemas[reg.name][rt.name] = schema_cached
184-
return self._schemas[reg.name][rt.name]
185-
try:
186-
self._schemas[reg.name][rt.name] = Schema(
187-
load_resource(
188-
self._provider_schema_modules[reg.name],
189-
filename=f"{rt.provider}.json",
190-
)
184+
)
185+
schema_cached.is_cached = True
186+
self._schemas[reg.name][rt.name] = schema_cached
187+
return self._schemas[reg.name][rt.name]
188+
try:
189+
self._schemas[reg.name][rt.name] = Schema(
190+
load_resource(
191+
self._provider_schema_modules[reg.name],
192+
filename=f"{rt.provider}.json",
191193
)
192-
except Exception as e:
193-
raise ResourceNotFoundError(rt.name, region) from e
194+
)
194195
return self._schemas[reg.name][rt.name]
195-
return schema
196+
except Exception as e:
197+
raise ResourceNotFoundError(rt.name, region) from e
196198

197199
@lru_cache(maxsize=None)
198200
def get_resource_types(self, region: str) -> list[str]:

test/fixtures/templates/bad/resources/primary_identifiers.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,3 +154,11 @@ Resources:
154154
- !Ref 'AWS::NoValue'
155155
BadType:
156156
Type: !Ref AWS::Region
157+
Module1:
158+
Type: MyCompany::MODULE
159+
Properties:
160+
Attribute1: test
161+
Module2:
162+
Type: MyCompany::MODULE
163+
Properties:
164+
Attribute2: test

test/unit/module/schema/test_manager.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,3 +271,15 @@ def test_removed_types(self):
271271

272272
with self.assertRaises(ResourceNotFoundError):
273273
self.manager.get_resource_schema(region, rt)
274+
275+
def test_type_normalization(self):
276+
277+
rt = "MyCompany::MODULE"
278+
schema = self.manager.get_resource_schema("us-east-1", rt)
279+
280+
assert schema.schema.get("typeName") == "Module"
281+
282+
self.manager.get_resource_schema.cache_clear()
283+
self.manager._registry_schemas[rt] = True
284+
schema = self.manager.get_resource_schema("us-east-1", rt)
285+
assert schema is True

tox.ini

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,7 @@ isolated_build = true
55
[testenv]
66
skip_install = True
77
commands =
8-
pip install -e .
9-
pip install -e .[sarif]
10-
pip install -e .[junit]
8+
pip install -e .[full]
119
coverage run -m pytest {posargs:test}
1210
coverage xml
1311
deps =

0 commit comments

Comments
 (0)