feat(sdk): discover external universal compliance frameworks via entry points#11490
Conversation
…very - Implemented dynamic loading of external providers via entry points, allowing for greater flexibility in provider integration. - Added functionality to discover compliance directories from entry points, enabling external compliance frameworks to be loaded seamlessly. - Refactored check module resolution to prioritize built-in checks while falling back to entry points if necessary. - Improved compliance framework loading to include both built-in and external sources, ensuring comprehensive compliance coverage. - Enhanced CLI argument parsing to support external providers, improving user experience and configurability. - Introduced extensive unit tests to validate dynamic loading, compliance discovery, and overall integration of external providers.
…iders and add tests
…ific compliance rendering
…iders load_and_validate_config_file only detected the namespaced format for 5 hardcoded providers (aws, gcp, azure, kubernetes, m365). For every other built-in (github, nhn, vercel, cloudflare, iac, llm, image, mongodbatlas, oraclecloud, openstack, alibabacloud, googleworkspace) and for any external plug-in, the full YAML was returned wrapped instead of the provider's own block. Replace the hardcoded list with a dynamic check: if the file has a top-level key matching the provider and its value is a dict, unwrap it. Keep the legacy flat format for AWS only (historical, pre-multicloud) and identify it by the absence of nested-dict top-level values, which prevents cross-provider config leakage when a namespaced file has no section for the requested provider.
…etadata validators
…r clearer import errors
…covery Conflict in prowler/config/config.py resolved by combining both branches: - HEAD: external compliance discovery via entry points (PROWLER-1391) - master: multi-provider framework JSONs scanned at top-level compliance/ (#10300) Order: built-in per-provider -> built-in multi-provider -> external entry points. Built-ins first so they win on name collisions against external registrations. Supporting external plug-ins to register multi-provider frameworks is tracked in PROWLER-1444.
…r names with hyphens are not misparsed
…er-contract-dynamic-discovery # Conflicts: # prowler/config/config.py
…very
Calling importlib.util.find_spec on prowler.providers.{provider}.services
for an external provider propagates ModuleNotFoundError when the parent
package prowler.providers.{provider} does not exist, instead of returning
None. This caused recover_checks_from_provider, _resolve_check_module and
Scan.scan to fail with "No module named 'prowler.providers.{external}'"
even though the plug-in registered its checks via entry points correctly.
Gate the built-in branch on Provider.is_builtin (which already wraps the
find_spec in try/except) and reuse _resolve_check_module from Scan.scan
so external providers fall through to the entry-point lookup.
…ints External plug-ins ship multi-provider (universal-schema) frameworks through a dedicated prowler.compliance.universal entry point group, separate from the per-provider prowler.compliance group. Both get_bulk_compliance_frameworks_universal (loading) and get_available_compliance_frameworks (listing / --compliance choices) scan the new group. Built-ins load first and win on a name collision; multiple packages under the same provider are merged. load_compliance_framework gains fatal=False so the legacy external path skips a non-legacy JSON with a warning instead of aborting the run.
841bb72 to
40da359
Compare
…provider-compliance-entry-points # Conflicts: # prowler/CHANGELOG.md # prowler/config/config.py # prowler/lib/check/compliance_models.py # tests/providers/external/test_dynamic_provider_loading.py
|
✅ Conflict Markers Resolved All conflict markers have been successfully resolved in this pull request. |
|
✅ All necessary |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #11490 +/- ##
===========================================
- Coverage 93.97% 74.30% -19.68%
===========================================
Files 241 110 -131
Lines 35441 8522 -26919
===========================================
- Hits 33305 6332 -26973
- Misses 2136 2190 +54
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
🔒 Container Security ScanImage: 📊 Vulnerability Summary
8 package(s) affected
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (5)
📝 WalkthroughWalkthroughThis PR extends Prowler's compliance framework system to support external universal (multi-provider) frameworks via entry points. The implementation adds graceful error handling for invalid external schemas, discovers frameworks through the ChangesUniversal Compliance Frameworks
🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Context
External plug-ins can register per-provider compliance via the
prowler.complianceentry point, but there was no way to ship multi-provider (universal-schema) frameworks. This adds that, building on the universal compliance support already in the SDK.Scope
prowler.compliance.universalentry-point group, built-in precedence on name collisions,fatalflag onload_compliance_frameworkAutonomy
Description
get_bulk_compliance_frameworks_universalnow scans a dedicatedprowler.compliance.universalentry point group, so external plug-ins can ship universal-schema frameworks. Kept separate from the per-providerprowler.compliancegroup, so the legacy per-provider loader never parses a universal JSON.load_compliance_frameworkgains afatalflag: an external JSON that fails the legacy schema is skipped with a warning instead of aborting the run (previously asys.exitthat the surroundingexcept Exceptioncould not catch).SDK-only change in
prowler/lib/check/compliance_models.pyplus tests.Steps to review
prowler.compliance.universalis returned byget_bulk_compliance_frameworks_universal.prowler.complianceis skipped with a warning andprowler aws --compliancedoes not crash.Checklist
CHANGELOG.md, if applicable.License
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Summary by CodeRabbit
New Features
Improvements