prowler 5.17.1__py3-none-any.whl → 5.18.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dashboard/compliance/hipaa_azure.py +25 -0
- dashboard/pages/overview.py +20 -11
- prowler/AGENTS.md +1 -1
- prowler/CHANGELOG.md +43 -0
- prowler/__main__.py +5 -0
- prowler/compliance/azure/hipaa_azure.json +820 -0
- prowler/compliance/m365/cis_4.0_m365.json +6 -2
- prowler/compliance/m365/cis_6.0_m365.json +6 -2
- prowler/compliance/m365/iso27001_2022_m365.json +13 -11
- prowler/compliance/openstack/__init__.py +0 -0
- prowler/config/config.py +2 -1
- prowler/config/config.yaml +4 -1
- prowler/config/openstack_mutelist_example.yaml +60 -0
- prowler/lib/check/check.py +4 -0
- prowler/lib/check/models.py +27 -2
- prowler/lib/cli/parser.py +3 -2
- prowler/lib/outputs/finding.py +14 -0
- prowler/lib/outputs/html/html.py +72 -0
- prowler/lib/outputs/jira/jira.py +3 -3
- prowler/lib/outputs/outputs.py +2 -0
- prowler/lib/outputs/summary_table.py +7 -0
- prowler/lib/timeline/__init__.py +0 -0
- prowler/lib/timeline/models.py +27 -0
- prowler/lib/timeline/timeline.py +36 -0
- prowler/providers/aws/lib/cloudtrail_timeline/__init__.py +0 -0
- prowler/providers/aws/lib/cloudtrail_timeline/cloudtrail_timeline.py +218 -0
- prowler/providers/aws/services/codebuild/codebuild_project_webhook_filters_use_anchored_patterns/__init__.py +0 -0
- prowler/providers/aws/services/codebuild/codebuild_project_webhook_filters_use_anchored_patterns/codebuild_project_webhook_filters_use_anchored_patterns.metadata.json +40 -0
- prowler/providers/aws/services/codebuild/codebuild_project_webhook_filters_use_anchored_patterns/codebuild_project_webhook_filters_use_anchored_patterns.py +58 -0
- prowler/providers/aws/services/codebuild/codebuild_service.py +45 -0
- prowler/providers/aws/services/dynamodb/dynamodb_table_cross_account_access/dynamodb_table_cross_account_access.metadata.json +1 -1
- prowler/providers/aws/services/dynamodb/dynamodb_table_cross_account_access/dynamodb_table_cross_account_access.py +4 -0
- prowler/providers/aws/services/eventbridge/eventbridge_bus_cross_account_access/eventbridge_bus_cross_account_access.metadata.json +1 -1
- prowler/providers/aws/services/eventbridge/eventbridge_bus_cross_account_access/eventbridge_bus_cross_account_access.py +4 -0
- prowler/providers/aws/services/eventbridge/eventbridge_schema_registry_cross_account_access/eventbridge_schema_registry_cross_account_access.metadata.json +1 -1
- prowler/providers/aws/services/eventbridge/eventbridge_schema_registry_cross_account_access/eventbridge_schema_registry_cross_account_access.py +2 -0
- prowler/providers/aws/services/iam/lib/policy.py +19 -3
- prowler/providers/aws/services/rds/rds_instance_extended_support/__init__.py +0 -0
- prowler/providers/aws/services/rds/rds_instance_extended_support/rds_instance_extended_support.metadata.json +41 -0
- prowler/providers/aws/services/rds/rds_instance_extended_support/rds_instance_extended_support.py +37 -0
- prowler/providers/aws/services/rds/rds_service.py +4 -0
- prowler/providers/aws/services/s3/s3_bucket_cross_account_access/s3_bucket_cross_account_access.metadata.json +1 -1
- prowler/providers/aws/services/s3/s3_bucket_cross_account_access/s3_bucket_cross_account_access.py +5 -1
- prowler/providers/azure/lib/service/service.py +23 -0
- prowler/providers/azure/services/app/app_client_certificates_on/app_client_certificates_on.metadata.json +18 -12
- prowler/providers/azure/services/app/app_ensure_auth_is_set_up/app_ensure_auth_is_set_up.metadata.json +18 -11
- prowler/providers/azure/services/app/app_ensure_http_is_redirected_to_https/app_ensure_http_is_redirected_to_https.metadata.json +19 -12
- prowler/providers/azure/services/app/app_ensure_java_version_is_latest/app_ensure_java_version_is_latest.metadata.json +19 -12
- prowler/providers/azure/services/app/app_ensure_php_version_is_latest/app_ensure_php_version_is_latest.metadata.json +19 -12
- prowler/providers/azure/services/app/app_ensure_python_version_is_latest/app_ensure_python_version_is_latest.metadata.json +19 -12
- prowler/providers/azure/services/app/app_ensure_using_http20/app_ensure_using_http20.metadata.json +18 -11
- prowler/providers/azure/services/app/app_ftp_deployment_disabled/app_ftp_deployment_disabled.metadata.json +21 -13
- prowler/providers/azure/services/app/app_function_access_keys_configured/app_function_access_keys_configured.metadata.json +19 -11
- prowler/providers/azure/services/app/app_function_application_insights_enabled/app_function_application_insights_enabled.metadata.json +21 -14
- prowler/providers/azure/services/app/app_function_ftps_deployment_disabled/app_function_ftps_deployment_disabled.metadata.json +18 -13
- prowler/providers/azure/services/app/app_function_identity_is_configured/app_function_identity_is_configured.metadata.json +20 -13
- prowler/providers/azure/services/app/app_function_identity_without_admin_privileges/app_function_identity_without_admin_privileges.metadata.json +18 -11
- prowler/providers/azure/services/app/app_function_latest_runtime_version/app_function_latest_runtime_version.metadata.json +20 -13
- prowler/providers/azure/services/app/app_function_not_publicly_accessible/app_function_not_publicly_accessible.metadata.json +20 -13
- prowler/providers/azure/services/app/app_function_vnet_integration_enabled/app_function_vnet_integration_enabled.metadata.json +21 -14
- prowler/providers/azure/services/app/app_http_logs_enabled/app_http_logs_enabled.metadata.json +18 -12
- prowler/providers/azure/services/app/app_minimum_tls_version_12/app_minimum_tls_version_12.metadata.json +20 -12
- prowler/providers/azure/services/app/app_register_with_identity/app_register_with_identity.metadata.json +18 -11
- prowler/providers/azure/services/appinsights/appinsights_ensure_is_configured/appinsights_ensure_is_configured.metadata.json +18 -12
- prowler/providers/azure/services/containerregistry/containerregistry_admin_user_disabled/containerregistry_admin_user_disabled.metadata.json +17 -11
- prowler/providers/azure/services/containerregistry/containerregistry_not_publicly_accessible/containerregistry_not_publicly_accessible.metadata.json +18 -12
- prowler/providers/azure/services/containerregistry/containerregistry_uses_private_link/containerregistry_uses_private_link.metadata.json +21 -13
- prowler/providers/azure/services/cosmosdb/cosmosdb_account_firewall_use_selected_networks/cosmosdb_account_firewall_use_selected_networks.metadata.json +20 -12
- prowler/providers/azure/services/cosmosdb/cosmosdb_account_use_aad_and_rbac/cosmosdb_account_use_aad_and_rbac.metadata.json +19 -13
- prowler/providers/azure/services/cosmosdb/cosmosdb_account_use_private_endpoints/cosmosdb_account_use_private_endpoints.metadata.json +20 -13
- prowler/providers/azure/services/databricks/databricks_workspace_cmk_encryption_enabled/databricks_workspace_cmk_encryption_enabled.metadata.json +20 -14
- prowler/providers/azure/services/databricks/databricks_workspace_vnet_injection_enabled/databricks_workspace_vnet_injection_enabled.metadata.json +20 -14
- prowler/providers/azure/services/defender/defender_additional_email_configured_with_a_security_contact/defender_additional_email_configured_with_a_security_contact.metadata.json +20 -13
- prowler/providers/azure/services/defender/defender_assessments_vm_endpoint_protection_installed/defender_assessments_vm_endpoint_protection_installed.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_attack_path_notifications_properly_configured/defender_attack_path_notifications_properly_configured.metadata.json +19 -13
- prowler/providers/azure/services/defender/defender_auto_provisioning_log_analytics_agent_vms_on/defender_auto_provisioning_log_analytics_agent_vms_on.metadata.json +20 -13
- prowler/providers/azure/services/defender/defender_auto_provisioning_vulnerabilty_assessments_machines_on/defender_auto_provisioning_vulnerabilty_assessments_machines_on.metadata.json +19 -12
- prowler/providers/azure/services/defender/defender_container_images_resolved_vulnerabilities/defender_container_images_resolved_vulnerabilities.metadata.json +20 -12
- prowler/providers/azure/services/defender/defender_container_images_scan_enabled/defender_container_images_scan_enabled.metadata.json +22 -13
- prowler/providers/azure/services/defender/defender_ensure_defender_for_app_services_is_on/defender_ensure_defender_for_app_services_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_arm_is_on/defender_ensure_defender_for_arm_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_azure_sql_databases_is_on/defender_ensure_defender_for_azure_sql_databases_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_containers_is_on/defender_ensure_defender_for_containers_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_cosmosdb_is_on/defender_ensure_defender_for_cosmosdb_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_databases_is_on/defender_ensure_defender_for_databases_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_dns_is_on/defender_ensure_defender_for_dns_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_keyvault_is_on/defender_ensure_defender_for_keyvault_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_os_relational_databases_is_on/defender_ensure_defender_for_os_relational_databases_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_server_is_on/defender_ensure_defender_for_server_is_on.metadata.json +19 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_sql_servers_is_on/defender_ensure_defender_for_sql_servers_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_defender_for_storage_is_on/defender_ensure_defender_for_storage_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_iot_hub_defender_is_on/defender_ensure_iot_hub_defender_is_on.metadata.json +17 -11
- prowler/providers/azure/services/defender/defender_ensure_mcas_is_enabled/defender_ensure_mcas_is_enabled.metadata.json +20 -12
- prowler/providers/azure/services/defender/defender_ensure_notify_alerts_severity_is_high/defender_ensure_notify_alerts_severity_is_high.metadata.json +19 -12
- prowler/providers/azure/services/defender/defender_ensure_notify_emails_to_owners/defender_ensure_notify_emails_to_owners.metadata.json +19 -12
- prowler/providers/azure/services/defender/defender_ensure_system_updates_are_applied/defender_ensure_system_updates_are_applied.metadata.json +17 -9
- prowler/providers/azure/services/defender/defender_ensure_wdatp_is_enabled/defender_ensure_wdatp_is_enabled.metadata.json +21 -13
- prowler/providers/azure/services/entra/entra_service.py +3 -11
- prowler/providers/azure/services/entra/entra_user_with_vm_access_has_mfa/entra_user_with_vm_access_has_mfa.py +6 -0
- prowler/providers/azure/services/iam/iam_custom_role_has_permissions_to_administer_resource_locks/iam_custom_role_has_permissions_to_administer_resource_locks.metadata.json +19 -13
- prowler/providers/azure/services/iam/iam_role_user_access_admin_restricted/iam_role_user_access_admin_restricted.metadata.json +16 -10
- prowler/providers/azure/services/iam/iam_subscription_roles_owner_custom_not_created/iam_subscription_roles_owner_custom_not_created.metadata.json +18 -12
- prowler/providers/azure/services/keyvault/keyvault_rbac_secret_expiration_set/keyvault_rbac_secret_expiration_set.py +10 -11
- prowler/providers/azure/services/keyvault/keyvault_service.py +164 -81
- prowler/providers/azure/services/mysql/mysql_flexible_server_audit_log_connection_activated/mysql_flexible_server_audit_log_connection_activated.metadata.json +18 -12
- prowler/providers/azure/services/mysql/mysql_flexible_server_audit_log_enabled/mysql_flexible_server_audit_log_enabled.metadata.json +19 -12
- prowler/providers/azure/services/mysql/mysql_flexible_server_minimum_tls_version_12/mysql_flexible_server_minimum_tls_version_12.metadata.json +18 -12
- prowler/providers/azure/services/mysql/mysql_flexible_server_ssl_connection_enabled/mysql_flexible_server_ssl_connection_enabled.metadata.json +19 -12
- prowler/providers/azure/services/network/network_bastion_host_exists/network_bastion_host_exists.metadata.json +21 -12
- prowler/providers/azure/services/network/network_flow_log_captured_sent/network_flow_log_captured_sent.metadata.json +19 -12
- prowler/providers/azure/services/network/network_flow_log_more_than_90_days/network_flow_log_more_than_90_days.metadata.json +21 -12
- prowler/providers/azure/services/network/network_http_internet_access_restricted/network_http_internet_access_restricted.metadata.json +18 -12
- prowler/providers/azure/services/network/network_public_ip_shodan/network_public_ip_shodan.metadata.json +15 -10
- prowler/providers/azure/services/network/network_rdp_internet_access_restricted/network_rdp_internet_access_restricted.metadata.json +20 -12
- prowler/providers/azure/services/network/network_ssh_internet_access_restricted/network_ssh_internet_access_restricted.metadata.json +19 -12
- prowler/providers/azure/services/network/network_udp_internet_access_restricted/network_udp_internet_access_restricted.metadata.json +19 -12
- prowler/providers/azure/services/network/network_watcher_enabled/network_watcher_enabled.metadata.json +21 -13
- prowler/providers/azure/services/policy/policy_ensure_asc_enforcement_enabled/policy_ensure_asc_enforcement_enabled.metadata.json +16 -11
- prowler/providers/azure/services/postgresql/postgresql_flexible_server_allow_access_services_disabled/postgresql_flexible_server_allow_access_services_disabled.metadata.json +20 -13
- prowler/providers/azure/services/postgresql/postgresql_flexible_server_connection_throttling_on/postgresql_flexible_server_connection_throttling_on.metadata.json +18 -12
- prowler/providers/azure/services/postgresql/postgresql_flexible_server_enforce_ssl_enabled/postgresql_flexible_server_enforce_ssl_enabled.metadata.json +19 -13
- prowler/providers/azure/services/postgresql/postgresql_flexible_server_entra_id_authentication_enabled/postgresql_flexible_server_entra_id_authentication_enabled.metadata.json +4 -4
- prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_checkpoints_on/postgresql_flexible_server_log_checkpoints_on.metadata.json +19 -13
- prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_connections_on/postgresql_flexible_server_log_connections_on.metadata.json +18 -11
- prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_disconnections_on/postgresql_flexible_server_log_disconnections_on.metadata.json +18 -12
- prowler/providers/azure/services/postgresql/postgresql_flexible_server_log_retention_days_greater_3/postgresql_flexible_server_log_retention_days_greater_3.metadata.json +18 -12
- prowler/providers/azure/services/sqlserver/sqlserver_auditing_enabled/sqlserver_auditing_enabled.metadata.json +20 -13
- prowler/providers/azure/services/sqlserver/sqlserver_auditing_retention_90_days/sqlserver_auditing_retention_90_days.metadata.json +20 -12
- prowler/providers/azure/services/sqlserver/sqlserver_azuread_administrator_enabled/sqlserver_azuread_administrator_enabled.metadata.json +18 -12
- prowler/providers/azure/services/sqlserver/sqlserver_microsoft_defender_enabled/sqlserver_microsoft_defender_enabled.metadata.json +23 -13
- prowler/providers/azure/services/sqlserver/sqlserver_recommended_minimal_tls_version/sqlserver_recommended_minimal_tls_version.metadata.json +19 -12
- prowler/providers/azure/services/sqlserver/sqlserver_tde_encrypted_with_cmk/sqlserver_tde_encrypted_with_cmk.metadata.json +20 -13
- prowler/providers/azure/services/sqlserver/sqlserver_tde_encryption_enabled/sqlserver_tde_encryption_enabled.metadata.json +20 -13
- prowler/providers/azure/services/sqlserver/sqlserver_unrestricted_inbound_access/sqlserver_unrestricted_inbound_access.metadata.json +18 -12
- prowler/providers/azure/services/sqlserver/sqlserver_va_emails_notifications_admins_enabled/sqlserver_va_emails_notifications_admins_enabled.metadata.json +19 -12
- prowler/providers/azure/services/sqlserver/sqlserver_va_periodic_recurring_scans_enabled/sqlserver_va_periodic_recurring_scans_enabled.metadata.json +19 -12
- prowler/providers/azure/services/sqlserver/sqlserver_va_scan_reports_configured/sqlserver_va_scan_reports_configured.metadata.json +18 -12
- prowler/providers/azure/services/sqlserver/sqlserver_vulnerability_assessment_enabled/sqlserver_vulnerability_assessment_enabled.metadata.json +19 -12
- prowler/providers/azure/services/storage/storage_account_key_access_disabled/storage_account_key_access_disabled.metadata.json +17 -12
- prowler/providers/azure/services/storage/storage_blob_public_access_level_is_disabled/storage_blob_public_access_level_is_disabled.metadata.json +18 -12
- prowler/providers/azure/services/storage/storage_blob_versioning_is_enabled/storage_blob_versioning_is_enabled.metadata.json +19 -11
- prowler/providers/azure/services/storage/storage_cross_tenant_replication_disabled/storage_cross_tenant_replication_disabled.metadata.json +19 -13
- prowler/providers/azure/services/storage/storage_default_network_access_rule_is_denied/storage_default_network_access_rule_is_denied.metadata.json +19 -12
- prowler/providers/azure/services/storage/storage_default_to_entra_authorization_enabled/storage_default_to_entra_authorization_enabled.metadata.json +20 -13
- prowler/providers/azure/services/storage/storage_ensure_azure_services_are_trusted_to_access_is_enabled/storage_ensure_azure_services_are_trusted_to_access_is_enabled.metadata.json +17 -10
- prowler/providers/azure/services/storage/storage_ensure_encryption_with_customer_managed_keys/storage_ensure_encryption_with_customer_managed_keys.metadata.json +15 -10
- prowler/providers/azure/services/storage/storage_ensure_file_shares_soft_delete_is_enabled/storage_ensure_file_shares_soft_delete_is_enabled.metadata.json +18 -12
- prowler/providers/azure/services/storage/storage_ensure_minimum_tls_version_12/storage_ensure_minimum_tls_version_12.metadata.json +14 -10
- prowler/providers/azure/services/storage/storage_ensure_private_endpoints_in_storage_accounts/storage_ensure_private_endpoints_in_storage_accounts.metadata.json +19 -11
- prowler/providers/azure/services/storage/storage_ensure_soft_delete_is_enabled/storage_ensure_soft_delete_is_enabled.metadata.json +17 -12
- prowler/providers/azure/services/storage/storage_geo_redundant_enabled/storage_geo_redundant_enabled.metadata.json +19 -12
- prowler/providers/azure/services/storage/storage_infrastructure_encryption_is_enabled/storage_infrastructure_encryption_is_enabled.metadata.json +13 -9
- prowler/providers/azure/services/storage/storage_key_rotation_90_days/storage_key_rotation_90_days.metadata.json +17 -12
- prowler/providers/azure/services/storage/storage_secure_transfer_required_is_enabled/storage_secure_transfer_required_is_enabled.metadata.json +15 -11
- prowler/providers/azure/services/storage/storage_smb_channel_encryption_with_secure_algorithm/storage_smb_channel_encryption_with_secure_algorithm.metadata.json +19 -12
- prowler/providers/azure/services/storage/storage_smb_protocol_version_is_latest/storage_smb_protocol_version_is_latest.metadata.json +19 -13
- prowler/providers/cloudflare/cloudflare_provider.py +95 -12
- prowler/providers/cloudflare/lib/arguments/arguments.py +7 -0
- prowler/providers/cloudflare/services/dns/dns_record_cname_target_valid/__init__.py +0 -0
- prowler/providers/cloudflare/services/dns/dns_record_cname_target_valid/dns_record_cname_target_valid.metadata.json +36 -0
- prowler/providers/cloudflare/services/dns/dns_record_cname_target_valid/dns_record_cname_target_valid.py +109 -0
- prowler/providers/cloudflare/services/dns/dns_record_no_internal_ip/__init__.py +0 -0
- prowler/providers/cloudflare/services/dns/dns_record_no_internal_ip/dns_record_no_internal_ip.metadata.json +36 -0
- prowler/providers/cloudflare/services/dns/dns_record_no_internal_ip/dns_record_no_internal_ip.py +73 -0
- prowler/providers/cloudflare/services/dns/dns_record_no_wildcard/__init__.py +0 -0
- prowler/providers/cloudflare/services/dns/dns_record_no_wildcard/dns_record_no_wildcard.metadata.json +36 -0
- prowler/providers/cloudflare/services/dns/dns_record_no_wildcard/dns_record_no_wildcard.py +60 -0
- prowler/providers/cloudflare/services/dns/dns_record_proxied/__init__.py +0 -0
- prowler/providers/cloudflare/services/dns/dns_record_proxied/dns_record_proxied.metadata.json +36 -0
- prowler/providers/cloudflare/services/dns/dns_record_proxied/dns_record_proxied.py +49 -0
- prowler/providers/cloudflare/services/dns/dns_service.py +52 -6
- prowler/providers/cloudflare/services/firewall/__init__.py +0 -0
- prowler/providers/cloudflare/services/firewall/firewall_client.py +4 -0
- prowler/providers/cloudflare/services/firewall/firewall_service.py +123 -0
- prowler/providers/cloudflare/services/zone/zone_firewall_blocking_rules_configured/__init__.py +0 -0
- prowler/providers/cloudflare/services/zone/zone_firewall_blocking_rules_configured/zone_firewall_blocking_rules_configured.metadata.json +36 -0
- prowler/providers/cloudflare/services/zone/zone_firewall_blocking_rules_configured/zone_firewall_blocking_rules_configured.py +53 -0
- prowler/providers/cloudflare/services/zone/zone_service.py +133 -1
- prowler/providers/cloudflare/services/zone/zone_waf_owasp_ruleset_enabled/__init__.py +0 -0
- prowler/providers/cloudflare/services/zone/zone_waf_owasp_ruleset_enabled/zone_waf_owasp_ruleset_enabled.metadata.json +36 -0
- prowler/providers/cloudflare/services/zone/zone_waf_owasp_ruleset_enabled/zone_waf_owasp_ruleset_enabled.py +58 -0
- prowler/providers/common/provider.py +23 -0
- prowler/providers/gcp/services/compute/compute_instance_suspended_without_persistent_disks/__init__.py +0 -0
- prowler/providers/gcp/services/compute/compute_instance_suspended_without_persistent_disks/compute_instance_suspended_without_persistent_disks.metadata.json +37 -0
- prowler/providers/gcp/services/compute/compute_instance_suspended_without_persistent_disks/compute_instance_suspended_without_persistent_disks.py +35 -0
- prowler/providers/gcp/services/compute/compute_service.py +2 -0
- prowler/providers/m365/lib/powershell/m365_powershell.py +47 -1
- prowler/providers/m365/services/defender/defender_service.py +52 -0
- prowler/providers/m365/services/defender/defender_zap_for_teams_enabled/__init__.py +0 -0
- prowler/providers/m365/services/defender/defender_zap_for_teams_enabled/defender_zap_for_teams_enabled.metadata.json +38 -0
- prowler/providers/m365/services/defender/defender_zap_for_teams_enabled/defender_zap_for_teams_enabled.py +53 -0
- prowler/providers/m365/services/exchange/exchange_service.py +78 -0
- prowler/providers/m365/services/exchange/exchange_shared_mailbox_sign_in_disabled/__init__.py +0 -0
- prowler/providers/m365/services/exchange/exchange_shared_mailbox_sign_in_disabled/exchange_shared_mailbox_sign_in_disabled.metadata.json +37 -0
- prowler/providers/m365/services/exchange/exchange_shared_mailbox_sign_in_disabled/exchange_shared_mailbox_sign_in_disabled.py +59 -0
- prowler/providers/openstack/__init__.py +0 -0
- prowler/providers/openstack/exceptions/__init__.py +0 -0
- prowler/providers/openstack/exceptions/exceptions.py +166 -0
- prowler/providers/openstack/lib/__init__.py +0 -0
- prowler/providers/openstack/lib/arguments/__init__.py +0 -0
- prowler/providers/openstack/lib/arguments/arguments.py +113 -0
- prowler/providers/openstack/lib/mutelist/__init__.py +0 -0
- prowler/providers/openstack/lib/mutelist/mutelist.py +31 -0
- prowler/providers/openstack/lib/service/__init__.py +0 -0
- prowler/providers/openstack/lib/service/service.py +21 -0
- prowler/providers/openstack/models.py +100 -0
- prowler/providers/openstack/openstack_provider.py +515 -0
- prowler/providers/openstack/services/__init__.py +0 -0
- prowler/providers/openstack/services/compute/__init__.py +0 -0
- prowler/providers/openstack/services/compute/compute_client.py +4 -0
- prowler/providers/openstack/services/compute/compute_instance_security_groups_attached/__init__.py +0 -0
- prowler/providers/openstack/services/compute/compute_instance_security_groups_attached/compute_instance_security_groups_attached.metadata.json +40 -0
- prowler/providers/openstack/services/compute/compute_instance_security_groups_attached/compute_instance_security_groups_attached.py +35 -0
- prowler/providers/openstack/services/compute/compute_service.py +63 -0
- {prowler-5.17.1.dist-info → prowler-5.18.0.dist-info}/METADATA +11 -9
- {prowler-5.17.1.dist-info → prowler-5.18.0.dist-info}/RECORD +219 -155
- {prowler-5.17.1.dist-info → prowler-5.18.0.dist-info}/LICENSE +0 -0
- {prowler-5.17.1.dist-info → prowler-5.18.0.dist-info}/WHEEL +0 -0
- {prowler-5.17.1.dist-info → prowler-5.18.0.dist-info}/entry_points.txt +0 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
from prowler.exceptions.exceptions import ProwlerException
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
# Exceptions codes from 10000 to 10999 are reserved for OpenStack exceptions
|
|
5
|
+
class OpenStackBaseException(ProwlerException):
|
|
6
|
+
"""Base class for OpenStack Errors."""
|
|
7
|
+
|
|
8
|
+
OPENSTACK_ERROR_CODES = {
|
|
9
|
+
(10000, "OpenStackCredentialsError"): {
|
|
10
|
+
"message": "OpenStack credentials not found or invalid",
|
|
11
|
+
"remediation": "Check the OpenStack API credentials and ensure they are properly set.",
|
|
12
|
+
},
|
|
13
|
+
(10001, "OpenStackAuthenticationError"): {
|
|
14
|
+
"message": "OpenStack authentication failed",
|
|
15
|
+
"remediation": "Check the OpenStack API credentials and ensure they are valid.",
|
|
16
|
+
},
|
|
17
|
+
(10002, "OpenStackSessionError"): {
|
|
18
|
+
"message": "OpenStack session setup failed",
|
|
19
|
+
"remediation": "Check the session setup and ensure it is properly configured.",
|
|
20
|
+
},
|
|
21
|
+
(10003, "OpenStackIdentityError"): {
|
|
22
|
+
"message": "OpenStack identity setup failed",
|
|
23
|
+
"remediation": "Check credentials and ensure they are properly set up for OpenStack.",
|
|
24
|
+
},
|
|
25
|
+
(10004, "OpenStackAPIError"): {
|
|
26
|
+
"message": "OpenStack API call failed",
|
|
27
|
+
"remediation": "Check the API request and ensure it is properly formatted.",
|
|
28
|
+
},
|
|
29
|
+
(10005, "OpenStackRateLimitError"): {
|
|
30
|
+
"message": "OpenStack API rate limit exceeded",
|
|
31
|
+
"remediation": "Reduce the number of API requests or wait before making more requests.",
|
|
32
|
+
},
|
|
33
|
+
(10006, "OpenStackConfigFileNotFoundError"): {
|
|
34
|
+
"message": "OpenStack clouds.yaml configuration file not found",
|
|
35
|
+
"remediation": "Check that the clouds.yaml file exists at the specified path or in standard locations (~/.config/openstack/clouds.yaml, /etc/openstack/clouds.yaml, ./clouds.yaml).",
|
|
36
|
+
},
|
|
37
|
+
(10007, "OpenStackCloudNotFoundError"): {
|
|
38
|
+
"message": "Specified cloud not found in clouds.yaml configuration",
|
|
39
|
+
"remediation": "Check that the cloud name exists in your clouds.yaml file and is properly configured.",
|
|
40
|
+
},
|
|
41
|
+
(10008, "OpenStackInvalidConfigError"): {
|
|
42
|
+
"message": "Invalid or malformed clouds.yaml configuration file",
|
|
43
|
+
"remediation": "Check that the clouds.yaml file is valid YAML and follows the OpenStack configuration format.",
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
def __init__(self, code, file=None, original_exception=None, message=None):
|
|
48
|
+
provider = "OpenStack"
|
|
49
|
+
error_info = self.OPENSTACK_ERROR_CODES.get((code, self.__class__.__name__))
|
|
50
|
+
if message:
|
|
51
|
+
error_info["message"] = message
|
|
52
|
+
super().__init__(
|
|
53
|
+
code=code,
|
|
54
|
+
source=provider,
|
|
55
|
+
file=file,
|
|
56
|
+
original_exception=original_exception,
|
|
57
|
+
error_info=error_info,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class OpenStackCredentialsError(OpenStackBaseException):
|
|
62
|
+
"""Exception for OpenStack credentials errors"""
|
|
63
|
+
|
|
64
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
65
|
+
super().__init__(
|
|
66
|
+
code=10000,
|
|
67
|
+
file=file,
|
|
68
|
+
original_exception=original_exception,
|
|
69
|
+
message=message,
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
class OpenStackAuthenticationError(OpenStackBaseException):
|
|
74
|
+
"""Exception for OpenStack authentication errors"""
|
|
75
|
+
|
|
76
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
77
|
+
super().__init__(
|
|
78
|
+
code=10001,
|
|
79
|
+
file=file,
|
|
80
|
+
original_exception=original_exception,
|
|
81
|
+
message=message,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
class OpenStackSessionError(OpenStackBaseException):
|
|
86
|
+
"""Exception for OpenStack session setup errors"""
|
|
87
|
+
|
|
88
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
89
|
+
super().__init__(
|
|
90
|
+
code=10002,
|
|
91
|
+
file=file,
|
|
92
|
+
original_exception=original_exception,
|
|
93
|
+
message=message,
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
class OpenStackIdentityError(OpenStackBaseException):
|
|
98
|
+
"""Exception for OpenStack identity setup errors"""
|
|
99
|
+
|
|
100
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
101
|
+
super().__init__(
|
|
102
|
+
code=10003,
|
|
103
|
+
file=file,
|
|
104
|
+
original_exception=original_exception,
|
|
105
|
+
message=message,
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class OpenStackAPIError(OpenStackBaseException):
|
|
110
|
+
"""Exception for OpenStack API errors"""
|
|
111
|
+
|
|
112
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
113
|
+
super().__init__(
|
|
114
|
+
code=10004,
|
|
115
|
+
file=file,
|
|
116
|
+
original_exception=original_exception,
|
|
117
|
+
message=message,
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class OpenStackRateLimitError(OpenStackBaseException):
|
|
122
|
+
"""Exception for OpenStack rate limit errors"""
|
|
123
|
+
|
|
124
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
125
|
+
super().__init__(
|
|
126
|
+
code=10005,
|
|
127
|
+
file=file,
|
|
128
|
+
original_exception=original_exception,
|
|
129
|
+
message=message,
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
class OpenStackConfigFileNotFoundError(OpenStackBaseException):
|
|
134
|
+
"""Exception for clouds.yaml file not found errors"""
|
|
135
|
+
|
|
136
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
137
|
+
super().__init__(
|
|
138
|
+
code=10006,
|
|
139
|
+
file=file,
|
|
140
|
+
original_exception=original_exception,
|
|
141
|
+
message=message,
|
|
142
|
+
)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
class OpenStackCloudNotFoundError(OpenStackBaseException):
|
|
146
|
+
"""Exception for cloud not found in clouds.yaml errors"""
|
|
147
|
+
|
|
148
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
149
|
+
super().__init__(
|
|
150
|
+
code=10007,
|
|
151
|
+
file=file,
|
|
152
|
+
original_exception=original_exception,
|
|
153
|
+
message=message,
|
|
154
|
+
)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
class OpenStackInvalidConfigError(OpenStackBaseException):
|
|
158
|
+
"""Exception for invalid clouds.yaml configuration errors"""
|
|
159
|
+
|
|
160
|
+
def __init__(self, file=None, original_exception=None, message=None):
|
|
161
|
+
super().__init__(
|
|
162
|
+
code=10008,
|
|
163
|
+
file=file,
|
|
164
|
+
original_exception=original_exception,
|
|
165
|
+
message=message,
|
|
166
|
+
)
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
from argparse import Namespace
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
def init_parser(self):
|
|
5
|
+
"""Initialize the OpenStack provider CLI parser."""
|
|
6
|
+
openstack_parser = self.subparsers.add_parser(
|
|
7
|
+
"openstack", parents=[self.common_providers_parser], help="OpenStack Provider"
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
# clouds.yaml Configuration File Authentication
|
|
11
|
+
openstack_clouds_yaml_subparser = openstack_parser.add_argument_group(
|
|
12
|
+
"clouds.yaml Configuration File Authentication"
|
|
13
|
+
)
|
|
14
|
+
openstack_clouds_yaml_subparser.add_argument(
|
|
15
|
+
"--clouds-yaml-file",
|
|
16
|
+
nargs="?",
|
|
17
|
+
default=None,
|
|
18
|
+
help="Path to clouds.yaml configuration file. If not specified, standard locations will be searched (~/.config/openstack/clouds.yaml, /etc/openstack/clouds.yaml, ./clouds.yaml)",
|
|
19
|
+
)
|
|
20
|
+
openstack_clouds_yaml_subparser.add_argument(
|
|
21
|
+
"--clouds-yaml-cloud",
|
|
22
|
+
nargs="?",
|
|
23
|
+
default=None,
|
|
24
|
+
help="Cloud name from clouds.yaml to use for authentication. Required when using --clouds-yaml-file or when searching for clouds.yaml in standard locations",
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Explicit Credential Authentication
|
|
28
|
+
openstack_explicit_subparser = openstack_parser.add_argument_group(
|
|
29
|
+
"Explicit Credential Authentication"
|
|
30
|
+
)
|
|
31
|
+
openstack_explicit_subparser.add_argument(
|
|
32
|
+
"--os-auth-url",
|
|
33
|
+
nargs="?",
|
|
34
|
+
default=None,
|
|
35
|
+
help="OpenStack authentication URL (Keystone endpoint). Can also be set via OS_AUTH_URL environment variable",
|
|
36
|
+
)
|
|
37
|
+
openstack_explicit_subparser.add_argument(
|
|
38
|
+
"--os-username",
|
|
39
|
+
nargs="?",
|
|
40
|
+
default=None,
|
|
41
|
+
help="OpenStack username for authentication. Can also be set via OS_USERNAME environment variable",
|
|
42
|
+
)
|
|
43
|
+
openstack_explicit_subparser.add_argument(
|
|
44
|
+
"--os-password",
|
|
45
|
+
nargs="?",
|
|
46
|
+
default=None,
|
|
47
|
+
help="OpenStack password for authentication. Can also be set via OS_PASSWORD environment variable",
|
|
48
|
+
)
|
|
49
|
+
openstack_explicit_subparser.add_argument(
|
|
50
|
+
"--os-project-id",
|
|
51
|
+
nargs="?",
|
|
52
|
+
default=None,
|
|
53
|
+
help="OpenStack project ID (tenant ID). Can also be set via OS_PROJECT_ID environment variable",
|
|
54
|
+
)
|
|
55
|
+
openstack_explicit_subparser.add_argument(
|
|
56
|
+
"--os-region-name",
|
|
57
|
+
nargs="?",
|
|
58
|
+
default=None,
|
|
59
|
+
help="OpenStack region name. Can also be set via OS_REGION_NAME environment variable",
|
|
60
|
+
)
|
|
61
|
+
openstack_explicit_subparser.add_argument(
|
|
62
|
+
"--os-user-domain-name",
|
|
63
|
+
nargs="?",
|
|
64
|
+
default=None,
|
|
65
|
+
help="OpenStack user domain name. Can also be set via OS_USER_DOMAIN_NAME environment variable",
|
|
66
|
+
)
|
|
67
|
+
openstack_explicit_subparser.add_argument(
|
|
68
|
+
"--os-project-domain-name",
|
|
69
|
+
nargs="?",
|
|
70
|
+
default=None,
|
|
71
|
+
help="OpenStack project domain name. Can also be set via OS_PROJECT_DOMAIN_NAME environment variable",
|
|
72
|
+
)
|
|
73
|
+
openstack_explicit_subparser.add_argument(
|
|
74
|
+
"--os-identity-api-version",
|
|
75
|
+
nargs="?",
|
|
76
|
+
default=None,
|
|
77
|
+
help="OpenStack Identity API version (2 or 3). Can also be set via OS_IDENTITY_API_VERSION environment variable",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def validate_arguments(arguments: Namespace) -> tuple[bool, str]:
|
|
82
|
+
"""
|
|
83
|
+
Validate that provider arguments are valid and can be used together.
|
|
84
|
+
|
|
85
|
+
Enforces mutual exclusivity between clouds.yaml authentication and explicit credential parameters.
|
|
86
|
+
|
|
87
|
+
Args:
|
|
88
|
+
arguments (Namespace): The parsed arguments.
|
|
89
|
+
|
|
90
|
+
Returns:
|
|
91
|
+
tuple[bool, str]: A tuple containing a boolean indicating validity and an error message.
|
|
92
|
+
"""
|
|
93
|
+
# Check if clouds.yaml options are used with explicit credential parameters
|
|
94
|
+
clouds_yaml_in_use = arguments.clouds_yaml_file or arguments.clouds_yaml_cloud
|
|
95
|
+
|
|
96
|
+
explicit_params_in_use = any(
|
|
97
|
+
[
|
|
98
|
+
arguments.os_auth_url,
|
|
99
|
+
arguments.os_username,
|
|
100
|
+
arguments.os_password,
|
|
101
|
+
arguments.os_project_id,
|
|
102
|
+
arguments.os_user_domain_name,
|
|
103
|
+
arguments.os_project_domain_name,
|
|
104
|
+
]
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
if clouds_yaml_in_use and explicit_params_in_use:
|
|
108
|
+
return (
|
|
109
|
+
False,
|
|
110
|
+
"Cannot use clouds.yaml options (--clouds-yaml-file, --clouds-yaml-cloud) together with explicit credential parameters (--os-auth-url, --os-username, --os-password, --os-project-id, --os-user-domain-name, --os-project-domain-name). Please use one authentication method only.",
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
return (True, "")
|
|
File without changes
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
from prowler.lib.check.models import CheckReportOpenStack
|
|
2
|
+
from prowler.lib.mutelist.mutelist import Mutelist
|
|
3
|
+
from prowler.lib.outputs.utils import unroll_dict, unroll_tags
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class OpenStackMutelist(Mutelist):
|
|
7
|
+
"""Mutelist implementation for the OpenStack provider."""
|
|
8
|
+
|
|
9
|
+
def is_finding_muted(
|
|
10
|
+
self,
|
|
11
|
+
finding: CheckReportOpenStack,
|
|
12
|
+
project_id: str,
|
|
13
|
+
) -> bool:
|
|
14
|
+
"""Return True when the finding should be muted for the audited project."""
|
|
15
|
+
# Try matching with both resource_id and resource_name for better UX
|
|
16
|
+
# Users can specify either the UUID or the friendly name in the mutelist
|
|
17
|
+
muted_by_id = self.is_muted(
|
|
18
|
+
project_id,
|
|
19
|
+
finding.check_metadata.CheckID,
|
|
20
|
+
finding.region,
|
|
21
|
+
finding.resource_id,
|
|
22
|
+
unroll_dict(unroll_tags(finding.resource_tags)),
|
|
23
|
+
)
|
|
24
|
+
muted_by_name = self.is_muted(
|
|
25
|
+
project_id,
|
|
26
|
+
finding.check_metadata.CheckID,
|
|
27
|
+
finding.region,
|
|
28
|
+
finding.resource_name,
|
|
29
|
+
unroll_dict(unroll_tags(finding.resource_tags)),
|
|
30
|
+
)
|
|
31
|
+
return muted_by_id or muted_by_name
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from prowler.lib.logger import logger
|
|
2
|
+
from prowler.providers.openstack.openstack_provider import OpenstackProvider
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class OpenStackService:
|
|
6
|
+
"""Base class for all OpenStack services."""
|
|
7
|
+
|
|
8
|
+
def __init__(self, service_name: str, provider: OpenstackProvider) -> None:
|
|
9
|
+
self.service_name = service_name
|
|
10
|
+
self.provider = provider
|
|
11
|
+
self.connection = provider.connection
|
|
12
|
+
self.session = provider.session
|
|
13
|
+
self.region = provider.session.region_name
|
|
14
|
+
self.project_id = provider.session.project_id
|
|
15
|
+
self.identity = provider.identity
|
|
16
|
+
self.audit_config = provider.audit_config
|
|
17
|
+
self.fixer_config = provider.fixer_config
|
|
18
|
+
|
|
19
|
+
logger.debug(
|
|
20
|
+
f"{self.service_name} service initialized for project {self.project_id} in region {self.region}"
|
|
21
|
+
)
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import re
|
|
2
|
+
from typing import Optional
|
|
3
|
+
|
|
4
|
+
from pydantic.v1 import BaseModel, Field
|
|
5
|
+
|
|
6
|
+
from prowler.config.config import output_file_timestamp
|
|
7
|
+
from prowler.providers.common.models import ProviderOutputOptions
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def _is_uuid(value: str) -> bool:
|
|
11
|
+
"""Check if a string is a valid UUID.
|
|
12
|
+
|
|
13
|
+
Accepts both formats:
|
|
14
|
+
- Standard with dashes: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
|
|
15
|
+
- Compact without dashes: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
16
|
+
"""
|
|
17
|
+
# Standard UUID format with dashes
|
|
18
|
+
uuid_with_dashes = re.compile(
|
|
19
|
+
r"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$",
|
|
20
|
+
re.IGNORECASE,
|
|
21
|
+
)
|
|
22
|
+
# Compact UUID format without dashes (e.g., OVH)
|
|
23
|
+
uuid_without_dashes = re.compile(
|
|
24
|
+
r"^[0-9a-f]{32}$",
|
|
25
|
+
re.IGNORECASE,
|
|
26
|
+
)
|
|
27
|
+
return bool(uuid_with_dashes.match(value) or uuid_without_dashes.match(value))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class OpenStackSession(BaseModel):
|
|
31
|
+
"""Holds the authentication/session data used to talk with OpenStack."""
|
|
32
|
+
|
|
33
|
+
auth_url: str
|
|
34
|
+
identity_api_version: str = Field(default="3")
|
|
35
|
+
username: str
|
|
36
|
+
password: str
|
|
37
|
+
project_id: str
|
|
38
|
+
region_name: str
|
|
39
|
+
user_domain_name: str = Field(default="Default")
|
|
40
|
+
project_domain_name: str = Field(default="Default")
|
|
41
|
+
|
|
42
|
+
def as_sdk_config(self) -> dict:
|
|
43
|
+
"""Return a dict compatible with openstacksdk.connect().
|
|
44
|
+
|
|
45
|
+
Note: The OpenStack SDK distinguishes between project_id (must be UUID)
|
|
46
|
+
and project_name (any string identifier). We accept project_id from users
|
|
47
|
+
but internally pass it as project_name to the SDK if it's not a UUID.
|
|
48
|
+
This allows compatibility with providers like OVH that use numeric IDs.
|
|
49
|
+
"""
|
|
50
|
+
config = {
|
|
51
|
+
"auth_url": self.auth_url,
|
|
52
|
+
"username": self.username,
|
|
53
|
+
"password": self.password,
|
|
54
|
+
"region_name": self.region_name,
|
|
55
|
+
"project_domain_name": self.project_domain_name,
|
|
56
|
+
"user_domain_name": self.user_domain_name,
|
|
57
|
+
"identity_api_version": self.identity_api_version,
|
|
58
|
+
}
|
|
59
|
+
# If project_id is a UUID, pass it as project_id to SDK
|
|
60
|
+
# Otherwise, pass it as project_name (e.g., OVH numeric IDs)
|
|
61
|
+
if _is_uuid(self.project_id):
|
|
62
|
+
config["project_id"] = self.project_id
|
|
63
|
+
else:
|
|
64
|
+
config["project_name"] = self.project_id
|
|
65
|
+
return config
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class OpenStackIdentityInfo(BaseModel):
|
|
69
|
+
"""Represents the identity used during the audit run."""
|
|
70
|
+
|
|
71
|
+
user_id: Optional[str] = None
|
|
72
|
+
username: str
|
|
73
|
+
project_id: str
|
|
74
|
+
project_name: Optional[str] = None
|
|
75
|
+
region_name: str
|
|
76
|
+
user_domain_name: str
|
|
77
|
+
project_domain_name: str
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class OpenStackOutputOptions(ProviderOutputOptions):
|
|
81
|
+
"""OpenStack output options."""
|
|
82
|
+
|
|
83
|
+
def __init__(self, arguments, bulk_checks_metadata, identity):
|
|
84
|
+
# First call ProviderOutputOptions init
|
|
85
|
+
super().__init__(arguments, bulk_checks_metadata)
|
|
86
|
+
|
|
87
|
+
# Check if custom output filename was input, if not, set the default
|
|
88
|
+
if (
|
|
89
|
+
not hasattr(arguments, "output_filename")
|
|
90
|
+
or arguments.output_filename is None
|
|
91
|
+
):
|
|
92
|
+
# Use project_name if available, otherwise use project_id
|
|
93
|
+
project_identifier = (
|
|
94
|
+
identity.project_name if identity.project_name else identity.project_id
|
|
95
|
+
)
|
|
96
|
+
self.output_filename = (
|
|
97
|
+
f"prowler-output-{project_identifier}-{output_file_timestamp}"
|
|
98
|
+
)
|
|
99
|
+
else:
|
|
100
|
+
self.output_filename = arguments.output_filename
|