Merge branch 'PRWLR-7300-create-ia-c-provider' into PRWLR-7318-add-ia-c-provider-tests

This commit is contained in:
Andoni A.
2025-05-29 10:48:49 +02:00
29 changed files with 109 additions and 94 deletions
+15
View File
@@ -212,6 +212,21 @@ jobs:
run: |
poetry run pytest -n auto --cov=./prowler/providers/m365 --cov-report=xml:m365_coverage.xml tests/providers/m365
# Test IaC
- name: IaC - Check if any file has changed
id: iac-changed-files
uses: tj-actions/changed-files@ed68ef82c095e0d48ec87eccea555d944a631a4c # v46.0.5
with:
files: |
./prowler/providers/iac/**
./tests/providers/iac/**
.poetry.lock
- name: IaC - Test
if: steps.iac-changed-files.outputs.any_changed == 'true'
run: |
poetry run pytest -n auto --cov=./prowler/providers/iac --cov-report=xml:iac_coverage.xml tests/providers/iac
# Common Tests
- name: Lib - Test
if: steps.are-non-ignored-files-changed.outputs.any_changed == 'true'
+1 -1
View File
@@ -36,7 +36,7 @@ Available Cloud Providers:
kubernetes Kubernetes Provider
github GitHub Provider
m365 Microsoft 365 Provider
iac IaC Provider
iac IaC Provider (Preview)
nhn NHN Provider (Unofficial)
Available components:
+1 -1
View File
@@ -279,7 +279,7 @@ class Resource(BaseModel):
Id: str
Partition: str
Region: str
Tags: Optional[dict]
Tags: Optional[dict] = None
@validator("Tags", pre=True, always=True)
def tags_cannot_be_empty_dict(tags):
@@ -19,7 +19,7 @@ class AWSWellArchitectedModel(BaseModel):
Requirements_Attributes_WellArchitectedQuestionId: str
Requirements_Attributes_WellArchitectedPracticeId: str
Requirements_Attributes_Section: str
Requirements_Attributes_SubSection: Optional[str]
Requirements_Attributes_SubSection: Optional[str] = None
Requirements_Attributes_LevelOfRisk: str
Requirements_Attributes_AssessmentMethod: str
Requirements_Attributes_Description: str
+3 -3
View File
@@ -25,9 +25,9 @@ class AWSCISModel(BaseModel):
Requirements_Attributes_RemediationProcedure: str
Requirements_Attributes_AuditProcedure: str
Requirements_Attributes_AdditionalInformation: str
Requirements_Attributes_DefaultValue: Optional[
str
] # TODO Optional for now since it's not present in the CIS 1.5, 2.0 and 3.0 AWS benchmark
Requirements_Attributes_DefaultValue: Optional[str] = (
None # TODO Optional for now since it's not present in the CIS 1.5, 2.0 and 3.0 AWS benchmark
)
Requirements_Attributes_References: str
Status: str
StatusExtended: str
@@ -15,11 +15,11 @@ class GenericComplianceModel(BaseModel):
AssessmentDate: str
Requirements_Id: str
Requirements_Description: str
Requirements_Attributes_Section: Optional[str]
Requirements_Attributes_SubSection: Optional[str]
Requirements_Attributes_SubGroup: Optional[str]
Requirements_Attributes_Service: Optional[str]
Requirements_Attributes_Type: Optional[str]
Requirements_Attributes_Section: Optional[str] = None
Requirements_Attributes_SubSection: Optional[str] = None
Requirements_Attributes_SubGroup: Optional[str] = None
Requirements_Attributes_Service: Optional[str] = None
Requirements_Attributes_Type: Optional[str] = None
Status: str
StatusExtended: str
ResourceId: str
@@ -19,10 +19,10 @@ class AWSKISAISMSPModel(BaseModel):
Requirements_Attributes_Domain: str
Requirements_Attributes_Subdomain: str
Requirements_Attributes_Section: str
Requirements_Attributes_AuditChecklist: Optional[list[str]]
Requirements_Attributes_RelatedRegulations: Optional[list[str]]
Requirements_Attributes_AuditEvidence: Optional[list[str]]
Requirements_Attributes_NonComplianceCases: Optional[list[str]]
Requirements_Attributes_AuditChecklist: Optional[list[str]] = None
Requirements_Attributes_RelatedRegulations: Optional[list[str]] = None
Requirements_Attributes_AuditEvidence: Optional[list[str]] = None
Requirements_Attributes_NonComplianceCases: Optional[list[str]] = None
Status: str
StatusExtended: str
ResourceId: str
@@ -17,7 +17,7 @@ class ProwlerThreatScoreAWSModel(BaseModel):
Requirements_Description: str
Requirements_Attributes_Title: str
Requirements_Attributes_Section: str
Requirements_Attributes_SubSection: Optional[str]
Requirements_Attributes_SubSection: Optional[str] = None
Requirements_Attributes_AttributeDescription: str
Requirements_Attributes_AdditionalInformation: str
Requirements_Attributes_LevelOfRisk: int
@@ -44,7 +44,7 @@ class ProwlerThreatScoreAzureModel(BaseModel):
Requirements_Description: str
Requirements_Attributes_Title: str
Requirements_Attributes_Section: str
Requirements_Attributes_SubSection: Optional[str]
Requirements_Attributes_SubSection: Optional[str] = None
Requirements_Attributes_AttributeDescription: str
Requirements_Attributes_AdditionalInformation: str
Requirements_Attributes_LevelOfRisk: int
@@ -71,7 +71,7 @@ class ProwlerThreatScoreGCPModel(BaseModel):
Requirements_Description: str
Requirements_Attributes_Title: str
Requirements_Attributes_Section: str
Requirements_Attributes_SubSection: Optional[str]
Requirements_Attributes_SubSection: Optional[str] = None
Requirements_Attributes_AttributeDescription: str
Requirements_Attributes_AdditionalInformation: str
Requirements_Attributes_LevelOfRisk: int
@@ -98,7 +98,7 @@ class ProwlerThreatScoreM365Model(BaseModel):
Requirements_Description: str
Requirements_Attributes_Title: str
Requirements_Attributes_Section: str
Requirements_Attributes_SubSection: Optional[str]
Requirements_Attributes_SubSection: Optional[str] = None
Requirements_Attributes_AttributeDescription: str
Requirements_Attributes_AdditionalInformation: str
Requirements_Attributes_LevelOfRisk: int
+1 -1
View File
@@ -10,7 +10,7 @@ class ARN(BaseModel):
arn: str
partition: str
service: str
region: Optional[str] # In IAM ARN's do not have region
region: Optional[str] = None # In IAM ARN's do not have region
account_id: str
resource: str
resource_type: str
@@ -101,6 +101,6 @@ class Account(AWSService):
class Contact(BaseModel):
type: str
email: Optional[str]
name: Optional[str]
phone_number: Optional[str]
email: Optional[str] = None
name: Optional[str] = None
phone_number: Optional[str] = None
@@ -111,5 +111,5 @@ class Certificate(BaseModel):
tags: Optional[list] = []
expiration_days: int
in_use: bool
transparency_logging: Optional[bool]
transparency_logging: Optional[bool] = None
region: str
@@ -224,11 +224,11 @@ class Stage(BaseModel):
arn: str
logging: bool
client_certificate: bool
waf: Optional[str]
waf: Optional[str] = None
tags: Optional[list] = []
tracing_enabled: Optional[bool]
cache_enabled: Optional[bool]
cache_data_encrypted: Optional[bool]
tracing_enabled: Optional[bool] = None
cache_enabled: Optional[bool] = None
cache_data_encrypted: Optional[bool] = None
class PathResourceMethods(BaseModel):
@@ -196,12 +196,12 @@ class Function(BaseModel):
name: str
arn: str
security_groups: list
runtime: Optional[str]
runtime: Optional[str] = None
environment: dict = None
region: str
policy: dict = None
policy: dict = {}
code: LambdaCode = None
url_config: URLConfig = None
vpc_id: Optional[str]
subnet_ids: Optional[set]
vpc_id: Optional[str] = None
subnet_ids: Optional[set] = None
tags: Optional[list] = []
@@ -227,7 +227,7 @@ class BackupVault(BaseModel):
locked: bool
min_retention_days: int = None
max_retention_days: int = None
tags: Optional[list]
tags: Optional[list] = None
class BackupPlan(BaseModel):
@@ -236,17 +236,17 @@ class BackupPlan(BaseModel):
region: str
name: str
version_id: str
last_execution_date: Optional[datetime]
last_execution_date: Optional[datetime] = None
advanced_settings: list
tags: Optional[list]
tags: Optional[list] = None
class BackupReportPlan(BaseModel):
arn: str
region: str
name: str
last_attempted_execution_date: Optional[datetime]
last_successful_execution_date: Optional[datetime]
last_attempted_execution_date: Optional[datetime] = None
last_successful_execution_date: Optional[datetime] = None
class RecoveryPoint(BaseModel):
@@ -256,4 +256,4 @@ class RecoveryPoint(BaseModel):
backup_vault_name: str
encrypted: bool
backup_vault_region: str
tags: Optional[list]
tags: Optional[list] = None
@@ -116,7 +116,7 @@ class Guardrail(BaseModel):
region: str
tags: Optional[list] = []
sensitive_information_filter: bool = False
prompt_attack_filter_strength: Optional[str]
prompt_attack_filter_strength: Optional[str] = None
class BedrockAgent(AWSService):
@@ -169,6 +169,6 @@ class Agent(BaseModel):
id: str
name: str
arn: str
guardrail_id: Optional[str]
guardrail_id: Optional[str] = None
region: str
tags: Optional[list] = []
@@ -186,7 +186,7 @@ class SSLSupportMethod(Enum):
class DefaultCacheConfigBehaviour(BaseModel):
realtime_log_config_arn: Optional[str]
realtime_log_config_arn: Optional[str] = None
viewer_protocol_policy: ViewerProtocolPolicy
field_level_encryption_id: str
@@ -196,8 +196,8 @@ class Origin(BaseModel):
domain_name: str
origin_protocol_policy: str
origin_ssl_protocols: list[str]
origin_access_control: Optional[str]
s3_origin_config: Optional[dict]
origin_access_control: Optional[str] = None
s3_origin_config: Optional[dict] = None
class Distribution(BaseModel):
@@ -207,14 +207,14 @@ class Distribution(BaseModel):
id: str
region: str
logging_enabled: bool = False
default_cache_config: Optional[DefaultCacheConfigBehaviour]
geo_restriction_type: Optional[GeoRestrictionType]
default_cache_config: Optional[DefaultCacheConfigBehaviour] = None
geo_restriction_type: Optional[GeoRestrictionType] = None
origins: list[Origin]
web_acl_id: str = ""
default_certificate: Optional[bool]
default_root_object: Optional[str]
viewer_protocol_policy: Optional[str]
default_certificate: Optional[bool] = None
default_root_object: Optional[str] = None
viewer_protocol_policy: Optional[str] = None
tags: Optional[list] = []
origin_failover: Optional[bool]
ssl_support_method: Optional[SSLSupportMethod]
certificate: Optional[str]
origin_failover: Optional[bool] = None
ssl_support_method: Optional[SSLSupportMethod] = None
certificate: Optional[str] = None
@@ -278,8 +278,8 @@ class Logs(AWSService):
class MetricAlarm(BaseModel):
arn: str
name: str
metric: Optional[str]
name_space: Optional[str]
metric: Optional[str] = None
name_space: Optional[str] = None
region: str
tags: Optional[list] = []
alarm_actions: list
@@ -310,7 +310,7 @@ class MetricFilter(BaseModel):
name: str
metric: str
pattern: str
log_group: Optional[LogGroup]
log_group: Optional[LogGroup] = None
region: str
@@ -246,7 +246,7 @@ class Package(BaseModel):
"""Details of a package"""
name: str
namespace: Optional[str]
namespace: Optional[str] = None
format: str
origin_configuration: OriginConfiguration
latest_version: LatestPackageVersion
@@ -211,15 +211,15 @@ class Project(BaseModel):
name: str
arn: str
region: str
last_build: Optional[Build]
last_invoked_time: Optional[datetime.datetime]
buildspec: Optional[str]
source: Optional[Source]
last_build: Optional[Build] = None
last_invoked_time: Optional[datetime.datetime] = None
buildspec: Optional[str] = None
source: Optional[Source] = None
secondary_sources: Optional[list[Source]] = []
environment_variables: Optional[List[EnvironmentVariable]]
s3_logs: Optional[s3Logs]
cloudwatch_logs: Optional[CloudWatchLogs]
tags: Optional[list]
environment_variables: Optional[List[EnvironmentVariable]] = []
s3_logs: Optional[s3Logs] = None
cloudwatch_logs: Optional[CloudWatchLogs] = None
tags: Optional[list] = []
class ExportConfig(BaseModel):
@@ -233,6 +233,6 @@ class ReportGroup(BaseModel):
arn: str
name: str
region: str
status: Optional[str]
export_config: Optional[ExportConfig]
tags: Optional[list]
status: Optional[str] = None
export_config: Optional[ExportConfig] = None
tags: Optional[list] = []
@@ -367,12 +367,12 @@ class User(BaseModel):
class DefaultUserRolePermissions(BaseModel):
allowed_to_create_apps: Optional[bool]
allowed_to_create_security_groups: Optional[bool]
allowed_to_create_tenants: Optional[bool]
allowed_to_read_bitlocker_keys_for_owned_device: Optional[bool]
allowed_to_read_other_users: Optional[bool]
odata_type: Optional[str]
allowed_to_create_apps: Optional[bool] = None
allowed_to_create_security_groups: Optional[bool] = None
allowed_to_create_tenants: Optional[bool] = None
allowed_to_read_bitlocker_keys_for_owned_device: Optional[bool] = None
allowed_to_read_other_users: Optional[bool] = None
odata_type: Optional[str] = None
permission_grant_policies_assigned: Optional[List[str]] = None
@@ -380,20 +380,20 @@ class AuthorizationPolicy(BaseModel):
id: str
name: str
description: str
default_user_role_permissions: Optional[DefaultUserRolePermissions]
default_user_role_permissions: Optional[DefaultUserRolePermissions] = None
guest_invite_settings: str
guest_user_role_id: UUID
class SettingValue(BaseModel):
name: Optional[str]
odata_type: Optional[str]
value: Optional[str]
name: Optional[str] = None
odata_type: Optional[str] = None
value: Optional[str] = None
class GroupSetting(BaseModel):
name: Optional[str]
template_id: Optional[str]
name: Optional[str] = None
template_id: Optional[str] = None
settings: List[SettingValue]
+1 -1
View File
@@ -18,7 +18,7 @@ class GCPOrganization(BaseModel):
class GCPProject(BaseModel):
number: str
number: int
id: str
name: str
organization: Optional[GCPOrganization] = None
@@ -60,4 +60,4 @@ class Bucket(BaseModel):
uniform_bucket_level_access: bool
public: bool
project_id: str
retention_policy: Optional[dict]
retention_policy: Optional[dict] = None
@@ -143,8 +143,8 @@ class CriptoKey(BaseModel):
id: str
name: str
location: str
rotation_period: Optional[str]
next_rotation_time: Optional[str]
rotation_period: Optional[str] = None
next_rotation_time: Optional[str] = None
key_ring: str
members: list = []
project_id: str
@@ -162,9 +162,9 @@ class RoleBinding(BaseModel):
class Rule(BaseModel):
apiGroups: Optional[List[str]]
resources: Optional[List[str]]
verbs: Optional[List[str]]
apiGroups: Optional[List[str]] = None
resources: Optional[List[str]] = None
verbs: Optional[List[str]] = None
class Role(BaseModel):
@@ -63,7 +63,7 @@ class TestAzureMutelist:
finding.location = "West Europe"
finding.status = "FAIL"
finding.resource_name = "test_resource"
finding.resource_tags = []
finding.resource_tags = {}
finding.subscription = "subscription_1"
assert mutelist.is_finding_muted(finding)
@@ -91,7 +91,7 @@ class TestAzureMutelist:
account_uid="subscription_1",
region="subscription_1",
resource_uid="test_resource",
resource_tags=[],
resource_tags={},
muted=False,
)
@@ -89,7 +89,7 @@ class TestGCPMutelist:
account_uid="project_1",
region="test-region",
resource_uid="test_resource",
resource_tags=[],
resource_tags={},
muted=False,
)
@@ -96,7 +96,7 @@ class Test_iam_service_account_unused:
assert result[0].resource_id == iam_client.service_accounts[0].email
assert result[0].project_id == GCP_PROJECT_ID
assert result[0].location == GCP_US_CENTER1_LOCATION
assert result[0].resource == iam_client.service_accounts[0]
assert result[0].resource == iam_client.service_accounts[0].model_dump()
def test_iam_service_account_unused_mix(self):
iam_client = mock.MagicMock()
@@ -168,7 +168,7 @@ class Test_iam_service_account_unused:
assert result[0].resource_id == iam_client.service_accounts[0].email
assert result[0].project_id == GCP_PROJECT_ID
assert result[0].location == GCP_US_CENTER1_LOCATION
assert result[0].resource == iam_client.service_accounts[0]
assert result[0].resource == iam_client.service_accounts[0].model_dump()
assert result[1].status == "FAIL"
assert (
@@ -178,4 +178,4 @@ class Test_iam_service_account_unused:
assert result[1].resource_id == iam_client.service_accounts[1].email
assert result[1].project_id == GCP_PROJECT_ID
assert result[1].location == GCP_US_CENTER1_LOCATION
assert result[1].resource == iam_client.service_accounts[1]
assert result[1].resource == iam_client.service_accounts[1].model_dump()
@@ -153,7 +153,7 @@ class TestKubernetesMutelist:
account_uid="cluster_1",
region="test-region",
resource_uid="test_resource",
resource_tags=[],
resource_tags={},
muted=False,
)
@@ -62,7 +62,7 @@ class TestNHNMutelist:
finding.status = "FAIL"
finding.resource_name = "test_resource"
finding.location = "test_region"
finding.resource_tags = []
finding.resource_tags = {}
assert mutelist.is_finding_muted(finding)
@@ -89,7 +89,7 @@ class TestNHNMutelist:
account_uid="resource_1",
region="test_region",
resource_uid="test_resource",
resource_tags=[],
resource_tags={},
muted=False,
)