Skip to content

Commit 6e5bf6a

Browse files
authored
feat: add region filtering to --update-specs (#4382)
Allow users to specify which regions to update when running --update-specs by using the --regions flag. This reduces download time and bandwidth usage when only specific regions are needed. Usage: - cfn-lint --update-specs (updates all regions, default behavior) - cfn-lint --update-specs --regions us-east-1 us-west-2 (updates only specified regions) - cfn-lint --update-specs --regions ALL_REGIONS (explicit all regions) Changes: - Add regions parameter to update_resource_specs() and ProviderSchemaManager.update() - Pass regions from CLI config to update functions when explicitly specified - Add test coverage for region-specific updates
1 parent f84f897 commit 6e5bf6a

4 files changed

Lines changed: 34 additions & 7 deletions

File tree

src/cfnlint/maintenance.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,13 @@
2020
)
2121

2222

23-
def update_resource_specs(force: bool = False) -> int:
23+
def update_resource_specs(force: bool = False, regions: list[str] | None = None) -> int:
2424
"""Update provider schemas
2525
26+
Args:
27+
force: force the schemas to be downloaded
28+
regions: list of regions to update, None for all regions
29+
2630
Returns:
2731
int: exit code (0=success, 1=partial failure, 2=complete failure)
2832
"""
@@ -31,7 +35,7 @@ def update_resource_specs(force: bool = False) -> int:
3135
# so it will fail Python2.7 style linting, as well as throw AttributeError
3236

3337
# Update provider Schemas
34-
return PROVIDER_SCHEMA_MANAGER.update(force)
38+
return PROVIDER_SCHEMA_MANAGER.update(force, regions)
3539

3640

3741
def patch_resource_specs():

src/cfnlint/runner/cli.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,13 @@ def cli(self) -> None:
269269
configure_logging(self.config.debug, self.config.info)
270270

271271
if self.config.update_specs:
272-
exit_code = cfnlint.maintenance.update_resource_specs(self.config.force)
272+
# For update-specs, only use regions if explicitly specified
273+
regions = None
274+
if self.config._get_argument_value("regions", True, True):
275+
regions = self.config.regions
276+
exit_code = cfnlint.maintenance.update_resource_specs(
277+
self.config.force, regions
278+
)
273279
sys.exit(exit_code)
274280

275281
if self.config.patch_specs:

src/cfnlint/schema/manager.py

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -247,20 +247,24 @@ def get_resource_types(self, region: str) -> list[str]:
247247

248248
return resource_types
249249

250-
def update(self, force: bool) -> int:
250+
def update(self, force: bool, regions: list[str] | None = None) -> int:
251251
"""Update every regions provider schemas
252252
253253
Args:
254254
force (bool): force the schemas to be downloaded
255+
regions (list[str] | None): list of regions to update, None for all regions
255256
Returns:
256257
int: exit code (0=success, 1=partial failure, 2=complete failure)
257258
"""
258259
import hashlib
259260
from pathlib import Path
260261

262+
# Use all regions if none specified
263+
target_regions = regions if regions else REGIONS
264+
261265
# Separate ISO regions (not publicly accessible) from regular regions
262-
iso_regions = [r for r in REGIONS if "iso" in r or r.startswith("eusc")]
263-
regular_regions = [r for r in REGIONS if r not in iso_regions]
266+
iso_regions = [r for r in target_regions if "iso" in r or r.startswith("eusc")]
267+
regular_regions = [r for r in target_regions if r not in iso_regions]
264268

265269
# Download all regular regions in parallel
266270
downloaded_regions: dict[str, dict[str, dict]] = {}

test/unit/module/runner/test_cli.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,20 @@ def test_update_specs(self, mock_maintenance):
4646
runner.cli()
4747

4848
self.assertEqual(e.exception.code, 0)
49-
mock_maintenance.assert_called_once()
49+
mock_maintenance.assert_called_once_with(False, None)
50+
51+
@patch("cfnlint.maintenance.update_resource_specs")
52+
def test_update_specs_with_regions(self, mock_maintenance):
53+
mock_maintenance.return_value = 0
54+
config = ConfigMixIn(["--update-specs", "--regions", "us-east-1", "us-west-2"])
55+
56+
runner = Runner(config)
57+
58+
with self.assertRaises(SystemExit) as e:
59+
runner.cli()
60+
61+
self.assertEqual(e.exception.code, 0)
62+
mock_maintenance.assert_called_once_with(False, ["us-east-1", "us-west-2"])
5063

5164
@patch("cfnlint.maintenance.patch_resource_specs")
5265
def test_patch_specs(self, mock_maintenance):

0 commit comments

Comments
 (0)