mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
Merge branch 'master' of github.com:prowler-cloud/prowler into PRWLR-6129-review-check-report-init-for-region-resource-id-resource-arn
This commit is contained in:
+1
-1
@@ -124,7 +124,7 @@ extra:
|
||||
make our documentation better.
|
||||
analytics:
|
||||
provider: google
|
||||
property: G-H5TFH6WJRQ
|
||||
property: G-KBKV70W5Y2
|
||||
social:
|
||||
- icon: fontawesome/brands/github
|
||||
link: https://github.com/prowler-cloud
|
||||
|
||||
+9
-6
@@ -332,18 +332,21 @@ def prowler():
|
||||
# Outputs
|
||||
# TODO: this part is needed since the checks generates a Check_Report_XXX and the output uses Finding
|
||||
# This will be refactored for the outputs generate directly the Finding
|
||||
finding_outputs = [
|
||||
Finding.generate_output(global_provider, finding, output_options)
|
||||
for finding in findings
|
||||
]
|
||||
finding_outputs = []
|
||||
for finding in findings:
|
||||
try:
|
||||
finding_outputs.append(
|
||||
Finding.generate_output(global_provider, finding, output_options)
|
||||
)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
generated_outputs = {"regular": [], "compliance": []}
|
||||
|
||||
if args.output_formats:
|
||||
for mode in args.output_formats:
|
||||
filename = (
|
||||
f"{output_options.output_directory}/"
|
||||
f"{output_options.output_filename}"
|
||||
f"{output_options.output_directory}/{output_options.output_filename}"
|
||||
)
|
||||
if mode == "csv":
|
||||
csv_output = CSV(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from datetime import datetime
|
||||
from typing import Optional, Union
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import BaseModel, Field, ValidationError
|
||||
|
||||
from prowler.config.config import prowler_version
|
||||
from prowler.lib.check.models import Check_Report, CheckMetadata
|
||||
@@ -257,7 +257,13 @@ class Finding(BaseModel):
|
||||
)
|
||||
|
||||
return cls(**output_data)
|
||||
except ValidationError as validation_error:
|
||||
logger.error(
|
||||
f"{validation_error.__class__.__name__}[{validation_error.__traceback__.tb_lineno}]: {validation_error} - {output_data}"
|
||||
)
|
||||
raise validation_error
|
||||
except Exception as error:
|
||||
logger.error(
|
||||
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
raise error
|
||||
|
||||
@@ -296,12 +296,16 @@ class Scan:
|
||||
self.get_completed_checks(),
|
||||
)
|
||||
|
||||
findings = [
|
||||
Finding.generate_output(
|
||||
self._provider, finding, output_options=None
|
||||
)
|
||||
for finding in check_findings
|
||||
]
|
||||
findings = []
|
||||
for finding in check_findings:
|
||||
try:
|
||||
findings.append(
|
||||
Finding.generate_output(
|
||||
self._provider, finding, output_options=None
|
||||
)
|
||||
)
|
||||
except Exception:
|
||||
continue
|
||||
|
||||
yield self.progress, findings
|
||||
# If check does not exists in the provider or is from another provider
|
||||
|
||||
@@ -57,7 +57,7 @@ class ACM(AWSService):
|
||||
certificate_expiration_time = 0
|
||||
self.certificates[certificate["CertificateArn"]] = Certificate(
|
||||
arn=certificate["CertificateArn"],
|
||||
name=certificate["DomainName"],
|
||||
name=certificate.get("DomainName", ""),
|
||||
id=certificate["CertificateArn"].split("/")[-1],
|
||||
type=certificate["Type"],
|
||||
key_algorithm=certificate["KeyAlgorithm"],
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@ class iam_user_with_temporary_credentials(Check):
|
||||
|
||||
report = Check_Report_AWS(
|
||||
metadata=self.metadata(),
|
||||
resource=iam_client.user_temporary_credentials_usage,
|
||||
resource={"name": user_name, "arn": user_arn},
|
||||
)
|
||||
report.resource_id = user_name
|
||||
report.resource_arn = user_arn
|
||||
|
||||
@@ -97,6 +97,7 @@ class SNS(AWSService):
|
||||
owner=sub["Owner"],
|
||||
protocol=sub["Protocol"],
|
||||
endpoint=sub["Endpoint"],
|
||||
region=sub["SubscriptionArn"].split(":")[3],
|
||||
)
|
||||
for sub in response["Subscriptions"]
|
||||
]
|
||||
@@ -117,6 +118,7 @@ class Subscription(BaseModel):
|
||||
owner: str
|
||||
protocol: str
|
||||
endpoint: str
|
||||
region: str
|
||||
|
||||
|
||||
class Topic(BaseModel):
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
from datetime import datetime
|
||||
from unittest.mock import MagicMock, patch
|
||||
|
||||
import pytest
|
||||
from pydantic import ValidationError
|
||||
|
||||
from prowler.lib.check.models import (
|
||||
CheckMetadata,
|
||||
Code,
|
||||
@@ -417,3 +420,44 @@ class TestFinding:
|
||||
assert metadata is not None
|
||||
assert isinstance(metadata, dict)
|
||||
self.assert_keys_lowercase(metadata)
|
||||
|
||||
@patch(
|
||||
"prowler.lib.outputs.finding.get_check_compliance",
|
||||
new=mock_get_check_compliance,
|
||||
)
|
||||
def test_generate_output_validation_error(self):
|
||||
# Mock provider
|
||||
provider = MagicMock()
|
||||
provider.type = "aws"
|
||||
provider.identity.profile = "mock_auth"
|
||||
provider.identity.account = "mock_account_uid"
|
||||
provider.identity.partition = "aws"
|
||||
provider.organizations_metadata.account_name = "mock_account_name"
|
||||
provider.organizations_metadata.account_email = "mock_account_email"
|
||||
provider.organizations_metadata.organization_arn = "mock_account_org_uid"
|
||||
provider.organizations_metadata.organization_id = "mock_account_org_name"
|
||||
provider.organizations_metadata.account_tags = {"tag1": "value1"}
|
||||
|
||||
# Mock check result
|
||||
check_output = MagicMock()
|
||||
check_output.resource_id = "test_resource_id"
|
||||
check_output.resource_arn = "test_resource_arn"
|
||||
check_output.resource_details = "test_resource_details"
|
||||
check_output.resource_tags = {"tag1": "value1"}
|
||||
check_output.region = "us-west-1"
|
||||
check_output.partition = "aws"
|
||||
check_output.status_extended = "mock_status_extended"
|
||||
check_output.muted = False
|
||||
check_output.check_metadata = mock_check_metadata(provider="aws")
|
||||
check_output.resource = {}
|
||||
|
||||
# Mock output options
|
||||
output_options = MagicMock()
|
||||
output_options.unix_timestamp = False
|
||||
|
||||
# Bad Status Value
|
||||
check_output.status = "Invalid"
|
||||
|
||||
# Generate the finding
|
||||
with pytest.raises(ValidationError):
|
||||
Finding.generate_output(provider, check_output, output_options)
|
||||
|
||||
+9
@@ -65,6 +65,7 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
owner=AWS_ACCOUNT_NUMBER,
|
||||
protocol="https",
|
||||
endpoint="https://www.endpoint.com",
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
)
|
||||
)
|
||||
sns_client.topics = []
|
||||
@@ -100,6 +101,7 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
owner=AWS_ACCOUNT_NUMBER,
|
||||
protocol="https",
|
||||
endpoint="https://www.endpoint.com",
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
)
|
||||
)
|
||||
sns_client.topics = []
|
||||
@@ -131,6 +133,7 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
)
|
||||
assert result[0].resource_id == subscription_id_1
|
||||
assert result[0].resource_arn == subscription_arn_1
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
def test_subscriptions_with_http(self):
|
||||
sns_client = mock.MagicMock
|
||||
@@ -142,6 +145,7 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
owner=AWS_ACCOUNT_NUMBER,
|
||||
protocol="http",
|
||||
endpoint="http://www.endpoint.com",
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
)
|
||||
)
|
||||
sns_client.topics = []
|
||||
@@ -173,6 +177,7 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
)
|
||||
assert result[0].resource_id == subscription_id_2
|
||||
assert result[0].resource_arn == subscription_arn_2
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
def test_subscriptions_with_http_and_https(self):
|
||||
sns_client = mock.MagicMock
|
||||
@@ -184,6 +189,7 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
owner=AWS_ACCOUNT_NUMBER,
|
||||
protocol="https",
|
||||
endpoint="https://www.endpoint.com",
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
)
|
||||
)
|
||||
subscriptions.append(
|
||||
@@ -193,6 +199,7 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
owner=AWS_ACCOUNT_NUMBER,
|
||||
protocol="http",
|
||||
endpoint="http://www.endpoint.com",
|
||||
region=AWS_REGION_EU_WEST_1,
|
||||
)
|
||||
)
|
||||
sns_client.topics = []
|
||||
@@ -224,6 +231,7 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
)
|
||||
assert result[0].resource_id == subscription_id_1
|
||||
assert result[0].resource_arn == subscription_arn_1
|
||||
assert result[0].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
assert result[1].status == "FAIL"
|
||||
assert (
|
||||
@@ -232,3 +240,4 @@ class Test_sns_subscription_not_using_http_endpoints:
|
||||
)
|
||||
assert result[1].resource_id == subscription_id_2
|
||||
assert result[1].resource_arn == subscription_arn_2
|
||||
assert result[1].region == AWS_REGION_EU_WEST_1
|
||||
|
||||
Reference in New Issue
Block a user