Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions prowler/CHANGELOG.md

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move this into a new section for 5.33.0

Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ All notable changes to the **Prowler SDK** are documented in this file.
- CIS Kubernetes Benchmark v2.0.1 compliance framework for the Kubernetes provider [(#11722)](https://github.com/prowler-cloud/prowler/pull/11722)
- CIS GitHub Benchmark v1.2.0 compliance framework for the GitHub provider [(#11719)](https://github.com/prowler-cloud/prowler/pull/11719)

### 🔄 Changed

- Oracle Cloud API key authentication now uses an internal bootstrap region when no explicit scan region filter is provided [(#11565)](https://github.com/prowler-cloud/prowler/pull/11565)

### 🐞 Fixed

- Compliance frameworks contributed by several external packages under the same provider are now merged instead of overwritten, so every entry-point directory a provider contributes is discovered [(#11578)](https://github.com/prowler-cloud/prowler/pull/11578)
Expand Down
62 changes: 43 additions & 19 deletions prowler/providers/oraclecloud/oraclecloud_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,13 @@ class OraclecloudProvider(Provider):
_mutelist: OCIMutelist
audit_metadata: Audit_Metadata
_home_region: str = "us-ashburn-1"
_bootstrap_region: str = "us-ashburn-1"

def __init__(
self,
oci_config_file: str = None,
profile: str = None,
region: set = set(),
region: set = None,
compartment_ids: list = None,
config_path: str = None,
config_content: dict = None,
Expand Down Expand Up @@ -131,8 +132,11 @@ def __init__(

# Check if the configuration is scanning a single region
single_region = None
if region:
single_region = list(region)[0] if len(region) == 1 else None
if isinstance(region, str):
single_region = region
elif region:
single_region = sorted(region)[0]
bootstrap_region = single_region or self._bootstrap_region

# Setup OCI Session
logger.info("Setting up OCI session ...")
Expand All @@ -145,7 +149,7 @@ def __init__(
key_file=key_file,
key_content=key_content,
tenancy=tenancy,
region=single_region,
region=bootstrap_region,
pass_phrase=pass_phrase,
)

Expand All @@ -155,7 +159,7 @@ def __init__(
logger.info("Validating OCI credentials ...")
self._identity = self.set_identity(
session=self._session,
region=single_region,
region=bootstrap_region,
compartment_ids=compartment_ids,
)
logger.info("OCI credentials validated")
Expand All @@ -165,7 +169,13 @@ def __init__(
# Determine the tenancy home region from the full subscription list, independent of
# the --region filter, so tenancy-level APIs (e.g. the Audit configuration) always
# target the home region instead of a filtered, non-home region.
all_subscribed_regions = self.get_regions_to_audit()
try:
all_subscribed_regions = self.get_regions_to_audit()
except OCISetUpSessionError:
if single_region and len(self._regions) == 1:
all_subscribed_regions = self._regions
else:
raise
self._home_region = next(
(region.key for region in all_subscribed_regions if region.is_home_region),
self._regions[0].key if self._regions else "us-ashburn-1",
Expand Down Expand Up @@ -284,7 +294,7 @@ def setup_session(
signer = None

# If API key credentials are provided directly, create config from them
if user and fingerprint and tenancy and region:
if user and fingerprint and tenancy:
import base64

logger.info("Using API key credentials from direct parameters")
Expand All @@ -294,7 +304,7 @@ def setup_session(
"user": user,
"fingerprint": fingerprint,
"tenancy": tenancy,
"region": region,
"region": region or OraclecloudProvider._bootstrap_region,
}

# Handle private key
Expand Down Expand Up @@ -565,6 +575,12 @@ def get_regions_to_audit(self, region_set: set = None) -> list:
"""
regions = []

explicit_regions = None
if isinstance(region_set, str):
explicit_regions = {region_set}
elif region_set:
explicit_regions = set(region_set)

# Audit all subscribed regions
try:
# Create identity client with proper authentication handling
Expand All @@ -581,11 +597,9 @@ def get_regions_to_audit(self, region_set: set = None) -> list:
).data

# Check if auditing specific region or all
regions_check = (
region_set
if region_set
else [sub.region_name for sub in region_subscriptions]
)
regions_check = explicit_regions or [
sub.region_name for sub in region_subscriptions
]

for region_sub in region_subscriptions:
if region_sub.region_name in regions_check:
Expand All @@ -600,11 +614,21 @@ def get_regions_to_audit(self, region_set: set = None) -> list:
)
logger.info(f"Found {len(regions)} subscribed regions")
except Exception as error:
if not explicit_regions or len(explicit_regions) != 1:
raise OCISetUpSessionError(
original_exception=error,
message=(
"Could not retrieve OCI subscribed regions. "
"Configure an explicit region to preserve legacy single-region scans, "
"or fix the credentials/permissions required to list region subscriptions."
),
) from error

config_region = next(iter(explicit_regions))
logger.warning(
f"Could not retrieve region subscriptions: {error}. Using configured region."
f"Could not retrieve region subscriptions: {error}. "
f"Using explicitly configured region {config_region}."
)
# Fallback to configured region
config_region = self._session.config.get("region", "us-ashburn-1")
regions.append(
OCIRegion(
key=config_region,
Expand Down Expand Up @@ -855,7 +879,7 @@ def test_connection(
session = None

# If API key credentials are provided directly, create config from them
if user and fingerprint and tenancy and region:
if user and fingerprint and tenancy:
import base64

logger.info("Using API key credentials from direct parameters")
Expand All @@ -865,7 +889,7 @@ def test_connection(
"user": user,
"fingerprint": fingerprint,
"tenancy": tenancy,
"region": region,
"region": region or OraclecloudProvider._bootstrap_region,
}

# Handle private key
Expand Down Expand Up @@ -914,7 +938,7 @@ def test_connection(

identity = OraclecloudProvider.set_identity(
session=session,
region=region,
region=region or OraclecloudProvider._bootstrap_region,
)

# Validate provider_id if provided
Expand Down
Loading