mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-10-29 14:54:30 +00:00
fix(sdk): detect shadowed provider plug-ins without loading them
- Match shadowing entry point by name instead of calling ep.load() - Prevent plug-in code from executing during a built-in run - Update regression test to assert ep.load is never called
This commit is contained in:
1 parent
5070ce39c2
commit
64e82682bd
2 files changed
+16
-7
No files matched your search
@@ -275,7 +275,11 @@ class Provider(ABC):
|
||||
# tool prefers fail-loud predictability over silent
|
||||
# overrides. Surface the override so the user knows their
|
||||
# plug-in is being ignored and can rename it.
|
||||
if Provider._load_ep_provider(arguments.provider) is not None:
|
||||
# Match by name only — never ep.load() a shadowing plug-in.
|
||||
if any(
|
||||
ep.name == arguments.provider
|
||||
for ep in importlib.metadata.entry_points(group="prowler.providers")
|
||||
):
|
||||
logger.warning(
|
||||
f"Plug-in provider '{arguments.provider}' registered "
|
||||
f"via entry points is being IGNORED — a built-in with "
|
||||
|
||||
+11
-6
@@ -659,22 +659,25 @@ class TestProviderInitialization:
|
||||
|
||||
@patch("prowler.providers.common.provider.logger")
|
||||
@patch("prowler.providers.common.provider.load_and_validate_config_file")
|
||||
@patch("prowler.providers.common.provider.Provider._load_ep_provider")
|
||||
@patch("prowler.providers.common.provider.importlib.metadata.entry_points")
|
||||
@patch("prowler.providers.common.provider.import_module")
|
||||
@patch("prowler.providers.common.provider.Provider.is_builtin")
|
||||
def test_init_global_provider_warns_when_plugin_shadowed_by_builtin(
|
||||
self, mock_is_builtin, mock_import, mock_load_ep, mock_config, mock_logger
|
||||
self, mock_is_builtin, mock_import, mock_entry_points, mock_config, mock_logger
|
||||
):
|
||||
"""Regression guard: when a plug-in registers a provider name that
|
||||
collides with a built-in, the BUILT-IN wins and a warning is emitted
|
||||
naming the shadowed plug-in. Matches the precedence enforced by
|
||||
`_resolve_check_module` and `CheckMetadata.get_bulk` for checks. See
|
||||
PR #10700 review (HugoPBrito).
|
||||
naming the shadowed plug-in. Shadow detection matches by entry-point
|
||||
name only — the plug-in is never `ep.load()`-ed just to warn, so its
|
||||
module code cannot run during a built-in run. See PR #10700 review
|
||||
(HugoPBrito, Alan-TheGentleman).
|
||||
"""
|
||||
# Simulate a built-in `aws` that exists, AND a plug-in registered
|
||||
# under the same `aws` name via entry points.
|
||||
mock_is_builtin.return_value = True
|
||||
mock_load_ep.return_value = FakeExternalProvider # plug-in shadow
|
||||
shadow_ep = MagicMock()
|
||||
shadow_ep.name = "aws" # plug-in shadowing the built-in name
|
||||
mock_entry_points.return_value = [shadow_ep]
|
||||
mock_import.return_value = MagicMock(
|
||||
AwsProvider=MagicMock(side_effect=lambda **_kw: None)
|
||||
)
|
||||
@@ -719,6 +722,8 @@ class TestProviderInitialization:
|
||||
]
|
||||
assert warning_msgs, "expected a warning about the shadowed plug-in 'aws'"
|
||||
assert "IGNORED" in warning_msgs[0]
|
||||
# Shadow detected by name only — plug-in code never executed to warn
|
||||
shadow_ep.load.assert_not_called()
|
||||
|
||||
|
||||
# ===========================================================================
|
||||
|
||||
Reference in new issue
Block a user