feat(AwsProvider): include new structure for AWS provider (#3252)

Co-authored-by: Sergio Garcia <38561120+sergargar@users.noreply.github.com>
Co-authored-by: Sergio Garcia <sergargar1@gmail.com>
This commit is contained in:
Nacho Rivera
2024-01-15 16:55:53 +01:00
committed by GitHub
parent 24efb34d91
commit 36fc575e40
214 changed files with 1092 additions and 486 deletions
+6 -3
View File
@@ -39,7 +39,6 @@ from prowler.lib.outputs.json import close_json
from prowler.lib.outputs.outputs import extract_findings_statistics
from prowler.lib.outputs.slack import send_slack_message
from prowler.lib.outputs.summary_table import display_summary_table
from prowler.providers.aws.aws_provider import get_available_aws_service_regions
from prowler.providers.aws.lib.s3.s3 import send_to_s3_bucket
from prowler.providers.aws.lib.security_hub.security_hub import (
batch_send_to_security_hub,
@@ -52,7 +51,10 @@ from prowler.providers.common.audit_info import (
set_provider_execution_parameters,
)
from prowler.providers.common.clean import clean_provider_local_output_directories
from prowler.providers.common.common import set_global_provider_object
from prowler.providers.common.common import (
get_global_provider,
set_global_provider_object,
)
from prowler.providers.common.mutelist import set_provider_mutelist
from prowler.providers.common.outputs import set_provider_output_options
from prowler.providers.common.quick_inventory import run_provider_quick_inventory
@@ -263,9 +265,10 @@ def prowler():
f"{Style.BRIGHT}\nSending findings to AWS Security Hub, please wait...{Style.RESET_ALL}"
)
# Verify where AWS Security Hub is enabled
global_provider = get_global_provider()
aws_security_enabled_regions = []
security_hub_regions = (
get_available_aws_service_regions("securityhub", audit_info)
global_provider.get_available_aws_service_regions("securityhub")
if not audit_info.audited_regions
else audit_info.audited_regions
)
+8 -4
View File
@@ -22,6 +22,7 @@ from prowler.lib.logger import logger
from prowler.lib.outputs.outputs import report
from prowler.lib.utils.utils import open_file, parse_json_file
from prowler.providers.aws.lib.mutelist.mutelist import mutelist_findings
from prowler.providers.common.common import get_global_provider
from prowler.providers.common.models import Audit_Metadata
from prowler.providers.common.outputs import Provider_Output_Options
@@ -425,8 +426,10 @@ def execute_checks(
services_executed = set()
checks_executed = set()
global_provider = get_global_provider()
# Initialize the Audit Metadata
audit_info.audit_metadata = Audit_Metadata(
global_provider.audit_metadata = Audit_Metadata(
services_scanned=0,
expected_checks=checks_to_execute,
completed_checks=0,
@@ -537,6 +540,7 @@ def execute(
checks_executed: set,
custom_checks_metadata: Any,
):
global_provider = get_global_provider()
# Import check module
check_module_path = (
f"prowler.providers.{provider}.services.{service}.{check_name}.{check_name}"
@@ -556,15 +560,15 @@ def execute(
# Update Audit Status
services_executed.add(service)
checks_executed.add(check_name)
audit_info.audit_metadata = update_audit_metadata(
audit_info.audit_metadata, services_executed, checks_executed
global_provider.audit_metadata = update_audit_metadata(
global_provider.audit_metadata, services_executed, checks_executed
)
# Mute List findings
if audit_output_options.mutelist_file:
check_findings = mutelist_findings(
audit_output_options.mutelist_file,
audit_info.audited_account,
global_provider.audited_account,
check_findings,
)
+20 -20
View File
@@ -172,9 +172,6 @@ def display_compliance_table(
and compliance.Provider == "AWS"
and compliance.Version == "RD2022"
):
compliance_version = compliance.Version
compliance_fm = compliance.Framework
compliance_provider = compliance.Provider
for requirement in compliance.Requirements:
for attribute in requirement.Attributes:
marco_categoria = (
@@ -222,13 +219,13 @@ def display_compliance_table(
ens_compliance_table["Bajo"].append(
f"{Fore.YELLOW}{marcos[marco]['Bajo']}{Style.RESET_ALL}"
)
if fail_count + pass_count < 0:
if fail_count + pass_count < 1:
print(
f"\n {Style.BRIGHT}There are no resources for {Fore.YELLOW}{compliance_fm}_{compliance_version}_{compliance_provider}{Style.RESET_ALL}.\n"
f"\nThere are no resources for {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL}.\n"
)
else:
print(
f"\nEstado de Cumplimiento de {Fore.YELLOW}{compliance_fm}_{compliance_version}_{compliance_provider}{Style.RESET_ALL}:"
f"\nEstado de Cumplimiento de {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL}:"
)
overview_table = [
[
@@ -239,7 +236,7 @@ def display_compliance_table(
print(tabulate(overview_table, tablefmt="rounded_grid"))
if not compliance_overview:
print(
f"\nResultados de {Fore.YELLOW}{compliance_fm}_{compliance_version}_{compliance_provider}{Style.RESET_ALL}:"
f"\nResultados de {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL}:"
)
print(
tabulate(
@@ -251,7 +248,9 @@ def display_compliance_table(
print(
f"{Style.BRIGHT}* Solo aparece el Marco/Categoria que contiene resultados.{Style.RESET_ALL}"
)
print(f"\nResultados detallados de {compliance_fm} en:")
print(
f"\nResultados detallados de {compliance_framework.upper()} en:"
)
print(
f" - CSV: {output_directory}/compliance/{output_filename}_{compliance_framework}.csv\n"
)
@@ -272,8 +271,6 @@ def display_compliance_table(
compliance.Framework == "CIS"
and compliance.Version in compliance_framework
):
compliance_version = compliance.Version
compliance_fm = compliance.Framework
for requirement in compliance.Requirements:
for attribute in requirement.Attributes:
section = attribute.Section
@@ -322,11 +319,11 @@ def display_compliance_table(
)
if fail_count + pass_count < 1:
print(
f"\n {Style.BRIGHT}There are no resources for {Fore.YELLOW}{compliance_fm}_{compliance_version}{Style.RESET_ALL}.\n"
f"\nThere are no resources for {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL}.\n"
)
else:
print(
f"\nCompliance Status of {Fore.YELLOW}{compliance_fm}_{compliance_version}{Style.RESET_ALL} Framework:"
f"\nCompliance Status of {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL} Framework:"
)
overview_table = [
[
@@ -337,7 +334,7 @@ def display_compliance_table(
print(tabulate(overview_table, tablefmt="rounded_grid"))
if not compliance_overview:
print(
f"\nFramework {Fore.YELLOW}{compliance_fm}_{compliance_version}{Style.RESET_ALL} Results:"
f"\nFramework {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL} Results:"
)
print(
tabulate(
@@ -349,7 +346,9 @@ def display_compliance_table(
print(
f"{Style.BRIGHT}* Only sections containing results appear.{Style.RESET_ALL}"
)
print(f"\nDetailed results of {compliance_fm} are in:")
print(
f"\nDetailed results of {compliance_framework.upper()} are in:"
)
print(
f" - CSV: {output_directory}/compliance/{output_filename}_{compliance_framework}.csv\n"
)
@@ -369,7 +368,6 @@ def display_compliance_table(
"MITRE-ATTACK" in compliance.Framework
and compliance.Version in compliance_framework
):
compliance_fm = compliance.Framework
for requirement in compliance.Requirements:
for tactic in requirement.Tactics:
if tactic not in tactics:
@@ -396,11 +394,11 @@ def display_compliance_table(
)
if fail_count + pass_count < 1:
print(
f"\n {Style.BRIGHT}There are no resources for {Fore.YELLOW}{compliance_fm}{Style.RESET_ALL}.\n"
f"\nThere are no resources for {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL}.\n"
)
else:
print(
f"\nCompliance Status of {Fore.YELLOW}{compliance_fm}{Style.RESET_ALL} Framework:"
f"\nCompliance Status of {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL} Framework:"
)
overview_table = [
[
@@ -411,7 +409,7 @@ def display_compliance_table(
print(tabulate(overview_table, tablefmt="rounded_grid"))
if not compliance_overview:
print(
f"\nFramework {Fore.YELLOW}{compliance_fm}{Style.RESET_ALL} Results:"
f"\nFramework {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL} Results:"
)
print(
tabulate(
@@ -423,7 +421,9 @@ def display_compliance_table(
print(
f"{Style.BRIGHT}* Only sections containing results appear.{Style.RESET_ALL}"
)
print(f"\nDetailed results of {compliance_fm} are in:")
print(
f"\nDetailed results of {compliance_framework.upper()} are in:"
)
print(
f" - CSV: {output_directory}/compliance/{output_filename}_{compliance_framework}.csv\n"
)
@@ -447,7 +447,7 @@ def display_compliance_table(
pass_count += 1
if fail_count + pass_count < 1:
print(
f"\n {Style.BRIGHT}There are no resources for {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL}.\n"
f"\nThere are no resources for {Fore.YELLOW}{compliance_framework.upper()}{Style.RESET_ALL}.\n"
)
else:
print(
+2 -2
View File
@@ -10,7 +10,7 @@ from prowler.config.config import prowler_version, timestamp
from prowler.lib.check.models import Remediation
from prowler.lib.logger import logger
from prowler.lib.utils.utils import outputs_unix_timestamp
from prowler.providers.aws.lib.audit_info.models import AWS_Organizations_Info
from prowler.providers.aws.lib.audit_info.models import AWSOrganizationsInfo
def get_check_compliance(finding, provider, output_options) -> dict:
@@ -483,7 +483,7 @@ class Aws_Check_Output_JSON(Check_Output_JSON):
Profile: str = ""
AccountId: str = ""
OrganizationsInfo: Optional[AWS_Organizations_Info]
OrganizationsInfo: Optional[AWSOrganizationsInfo]
Region: str = ""
ResourceId: str = ""
ResourceArn: str = ""
+2 -2
View File
@@ -11,7 +11,7 @@ from prowler.lib.check.check import list_modules, recover_checks_from_service
from prowler.lib.logger import logger
from prowler.lib.utils.utils import open_file, parse_json_file
from prowler.providers.aws.config import AWS_STS_GLOBAL_ENDPOINT_REGION
from prowler.providers.aws.lib.audit_info.models import AWS_Assume_Role, AWS_Audit_Info
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info, AWSAssumeRole
from prowler.providers.aws.lib.credentials.credentials import create_sts_session
@@ -109,7 +109,7 @@ class AWS_Provider:
def assume_role(
session: session.Session,
assumed_role_info: AWS_Assume_Role,
assumed_role_info: AWSAssumeRole,
sts_endpoint_region: str = None,
) -> dict:
try:
+621
View File
@@ -0,0 +1,621 @@
import os
import pathlib
import sys
from argparse import Namespace
from dataclasses import dataclass
from datetime import datetime
from typing import Any, Optional
from boto3 import client, session
from botocore.config import Config
from botocore.credentials import RefreshableCredentials
from botocore.session import get_session
from colorama import Fore, Style
from prowler.config.config import aws_services_json_file
from prowler.lib.check.check import list_modules, recover_checks_from_service
from prowler.lib.logger import logger
from prowler.lib.utils.utils import open_file, parse_json_file
from prowler.providers.aws.config import (
AWS_STS_GLOBAL_ENDPOINT_REGION,
BOTO3_USER_AGENT_EXTRA,
)
from prowler.providers.aws.lib.arn.arn import parse_iam_credentials_arn
from prowler.providers.aws.lib.credentials.credentials import (
create_sts_session,
validate_AWSCredentials,
)
from prowler.providers.aws.lib.organizations.organizations import (
get_organizations_metadata,
)
from prowler.providers.common.provider import Provider
@dataclass
class AWSOrganizationsInfo:
account_details_email: str
account_details_name: str
account_details_arn: str
account_details_org: str
account_details_tags: str
@dataclass
class AWSCredentials:
aws_access_key_id: str
aws_session_token: str
aws_secret_access_key: str
expiration: datetime
@dataclass
class AWSAssumeRole:
role_arn: str
session_duration: int
external_id: str
mfa_enabled: bool
@dataclass
class AWSAssumeRoleConfiguration:
assumed_role_info: AWSAssumeRole
assumed_role_credentials: AWSCredentials
@dataclass
class AWSIdentityInfo:
account: str
account_arn: str
user_id: str
partition: str
identity_arn: str
profile: str
profile_region: str
audited_regions: list
@dataclass
class AWSSession:
session: session.Session
session_config: Config
original_session: None
class AwsProvider(Provider):
session: AWSSession = AWSSession(
session=None, session_config=None, original_session=None
)
identity: AWSIdentityInfo = AWSIdentityInfo(
account=None,
account_arn=None,
user_id=None,
partition=None,
identity_arn=None,
profile=None,
profile_region=None,
audited_regions=[],
)
assumed_role: AWSAssumeRoleConfiguration = AWSAssumeRoleConfiguration(
assumed_role_info=AWSAssumeRole(
role_arn=None,
session_duration=None,
external_id=None,
mfa_enabled=False,
),
assumed_role_credentials=AWSCredentials(
aws_access_key_id=None,
aws_session_token=None,
aws_secret_access_key=None,
expiration=None,
),
)
organizations_metadata: AWSOrganizationsInfo = AWSOrganizationsInfo(
account_details_email=None,
account_details_name=None,
account_details_arn=None,
account_details_org=None,
account_details_tags=None,
)
audit_resources: Optional[Any]
audit_metadata: Optional[Any]
audit_config: dict = {}
mfa_enabled: bool = False
ignore_unused_services: bool = False
def __init__(self, arguments: Namespace):
logger.info("Setting AWS provider ...")
# Parse input arguments
# Assume Role Options
input_role = getattr(arguments, "role", None)
input_session_duration = getattr(arguments, "session_duration", None)
input_external_id = getattr(arguments, "external_id", None)
# STS Endpoint Region
sts_endpoint_region = getattr(arguments, "sts_endpoint_region", None)
# MFA Configuration (false by default)
input_mfa = getattr(arguments, "mfa", None)
input_profile = getattr(arguments, "profile", None)
input_regions = getattr(arguments, "region", None)
organizations_role_arn = getattr(arguments, "organizations_role", None)
# Set the maximum retries for the standard retrier config
aws_retries_max_attempts = getattr(arguments, "aws_retries_max_attempts", None)
# Set if unused services must be ignored
ignore_unused_services = getattr(arguments, "ignore_unused_services", None)
# Set the maximum retries for the standard retrier config
self.session.session_config = self.__set_session_config__(
aws_retries_max_attempts
)
# Set ignore unused services
self.ignore_unused_services = ignore_unused_services
# Start populating AWS identity object
self.identity.profile = input_profile
self.identity.audited_regions = input_regions
# We need to create an original sessions using regular auth path (creds, profile, etc)
logger.info("Generating original session ...")
self.session.session = self.setup_session(input_mfa)
# After the session is created, validate it
logger.info("Validating credentials ...")
caller_identity = validate_AWSCredentials(
self.session.session, input_regions, sts_endpoint_region
)
logger.info("Credentials validated")
logger.info(f"Original caller identity UserId: {caller_identity['UserId']}")
logger.info(f"Original caller identity ARN: {caller_identity['Arn']}")
# Set values of AWS identity object
self.identity.account = caller_identity["Account"]
self.identity.identity_arn = caller_identity["Arn"]
self.identity.user_id = caller_identity["UserId"]
self.identity.partition = parse_iam_credentials_arn(
caller_identity["Arn"]
).partition
self.identity.account_arn = (
f"arn:{self.identity.partition}:iam::{self.identity.account}:root"
)
# save original session
self.session.original_session = self.session.session
# time for checking role assumption
if input_role:
# session will be the assumed one
self.session.session = self.setup_assumed_session(
input_role,
input_external_id,
input_mfa,
input_session_duration,
sts_endpoint_region,
)
logger.info("Audit session is the new session created assuming role")
# check if organizations info is gonna be retrieved
if organizations_role_arn:
logger.info(
f"Getting organizations metadata for account {organizations_role_arn}"
)
# session will be the assumed one with organizations permissions
self.session.session = self.setup_assumed_session(
organizations_role_arn,
input_external_id,
input_mfa,
input_session_duration,
sts_endpoint_region,
)
self.organizations_metadata = get_organizations_metadata(
self.identity.account, self.assumed_role.assumed_role_credentials
)
logger.info("Organizations metadata retrieved")
if self.session.session.region_name:
self.identity.profile_region = self.session.session.region_name
else:
self.identity.profile_region = "us-east-1"
if not getattr(arguments, "only_logs", None):
self.print_credentials()
# Parse Scan Tags
if getattr(arguments, "resource_tags", None):
input_resource_tags = arguments.resource_tags
self.audit_resources = self.get_tagged_resources(input_resource_tags)
# Parse Input Resource ARNs
self.audit_resources = getattr(arguments, "resource_arn", None)
def setup_session(self, input_mfa: bool):
logger.info("Creating regular session ...")
# Input MFA only if a role is not going to be assumed
if input_mfa and not self.assumed_role.assumed_role_info.role_arn:
mfa_ARN, mfa_TOTP = self.__input_role_mfa_token_and_code__()
get_session_token_arguments = {
"SerialNumber": mfa_ARN,
"TokenCode": mfa_TOTP,
}
sts_client = client("sts")
session_credentials = sts_client.get_session_token(
**get_session_token_arguments
)
return session.Session(
aws_access_key_id=session_credentials["Credentials"]["AccessKeyId"],
aws_secret_access_key=session_credentials["Credentials"][
"SecretAccessKey"
],
aws_session_token=session_credentials["Credentials"]["SessionToken"],
profile_name=self.identity.profile,
)
else:
return session.Session(
profile_name=self.identity.profile,
)
def setup_assumed_session(
self,
input_role: str,
input_external_id: str,
input_mfa: str,
session_duration: int,
sts_endpoint_region: str,
):
logger.info("Creating assumed session ...")
# store information about the role is gonna be assumed
self.assumed_role.assumed_role_info.role_arn = input_role
self.assumed_role.assumed_role_info.session_duration = session_duration
self.assumed_role.assumed_role_info.external_id = input_external_id
self.assumed_role.assumed_role_info.mfa_enabled = input_mfa
# Check if role arn is valid
try:
# this returns the arn already parsed into a dict to be used when it is needed to access its fields
role_arn_parsed = parse_iam_credentials_arn(
self.assumed_role.assumed_role_info.role_arn
)
except Exception as error:
logger.critical(f"{error.__class__.__name__} -- {error}")
sys.exit(1)
else:
logger.info(f"Assuming role {self.assumed_role.assumed_role_info.role_arn}")
# Assume the role
assumed_role_response = self.__assume_role__(
self.session.session,
sts_endpoint_region,
)
logger.info("Role assumed")
# Set the info needed to create a session with an assumed role
self.assumed_role.assumed_role_credentials = AWSCredentials(
aws_access_key_id=assumed_role_response["Credentials"]["AccessKeyId"],
aws_session_token=assumed_role_response["Credentials"]["SessionToken"],
aws_secret_access_key=assumed_role_response["Credentials"][
"SecretAccessKey"
],
expiration=assumed_role_response["Credentials"]["Expiration"],
)
# Set identity parameters
self.identity.account = role_arn_parsed.account_id
self.identity.partition = role_arn_parsed.partition
self.identity.account_arn = (
f"arn:{self.identity.partition}:iam::{self.identity.account}:root"
)
# From botocore we can use RefreshableCredentials class, which has an attribute (refresh_using)
# that needs to be a method without arguments that retrieves a new set of fresh credentials
# asuming the role again. -> https://github.com/boto/botocore/blob/098cc255f81a25b852e1ecdeb7adebd94c7b1b73/botocore/credentials.py#L395
assumed_refreshable_credentials = RefreshableCredentials(
access_key=self.assumed_role.assumed_role_credentials.aws_access_key_id,
secret_key=self.assumed_role.assumed_role_credentials.aws_secret_access_key,
token=self.assumed_role.assumed_role_credentials.aws_session_token,
expiry_time=self.assumed_role.assumed_role_credentials.expiration,
refresh_using=self.refresh_credentials,
method="sts-assume-role",
)
# Here we need the botocore session since it needs to use refreshable credentials
assumed_botocore_session = get_session()
assumed_botocore_session._credentials = assumed_refreshable_credentials
assumed_botocore_session.set_config_variable(
"region", self.identity.profile_region
)
return session.Session(
profile_name=self.identity.profile,
botocore_session=assumed_botocore_session,
)
# Refresh credentials method using assume role
# This method is called "adding ()" to the name, so it cannot accept arguments
# https://github.com/boto/botocore/blob/098cc255f81a25b852e1ecdeb7adebd94c7b1b73/botocore/credentials.py#L570
def refresh_credentials(self):
logger.info("Refreshing assumed credentials...")
response = self.__assume_role__(self.aws_session, self.role_info)
refreshed_credentials = dict(
# Keys of the dict has to be the same as those that are being searched in the parent class
# https://github.com/boto/botocore/blob/098cc255f81a25b852e1ecdeb7adebd94c7b1b73/botocore/credentials.py#L609
access_key=response["Credentials"]["AccessKeyId"],
secret_key=response["Credentials"]["SecretAccessKey"],
token=response["Credentials"]["SessionToken"],
expiry_time=response["Credentials"]["Expiration"].isoformat(),
)
logger.info("Refreshed Credentials:")
logger.info(refreshed_credentials)
return refreshed_credentials
def print_credentials(self):
# Beautify audited regions, set "all" if there is no filter region
regions = (
", ".join(self.identity.audited_regions)
if self.identity.audited_regions is not None
else "all"
)
# Beautify audited profile, set "default" if there is no profile set
profile = (
self.identity.profile if self.identity.profile is not None else "default"
)
report = f"""
This report is being generated using credentials below:
AWS-CLI Profile: {Fore.YELLOW}[{profile}]{Style.RESET_ALL} AWS Filter Region: {Fore.YELLOW}[{regions}]{Style.RESET_ALL}
AWS Account: {Fore.YELLOW}[{self.identity.account}]{Style.RESET_ALL} UserId: {Fore.YELLOW}[{self.identity.user_id}]{Style.RESET_ALL}
Caller Identity ARN: {Fore.YELLOW}[{ self.identity.identity_arn}]{Style.RESET_ALL}
"""
# If -A is set, print Assumed Role ARN
if self.assumed_role.assumed_role_info.role_arn is not None:
report += f"""Assumed Role ARN: {Fore.YELLOW}[{self.assumed_role.assumed_role_info.role_arn}]{Style.RESET_ALL}
"""
print(report)
def generate_regional_clients(
self, service: str, global_service: bool = False
) -> dict:
try:
regional_clients = {}
service_regions = self.get_available_aws_service_regions(service)
# Check if it is global service to gather only one region
if global_service:
if service_regions:
if self.identity.profile_region in service_regions:
service_regions = [self.identity.profile_region]
service_regions = service_regions[:1]
for region in service_regions:
regional_client = self.session.session.client(
service, region_name=region, config=self.session.session_config
)
regional_client.region = region
regional_clients[region] = regional_client
return regional_clients
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def get_available_aws_service_regions(self, service: str) -> list:
# Get json locally
actual_directory = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))
with open_file(f"{actual_directory}/{aws_services_json_file}") as f:
data = parse_json_file(f)
# Check if it is a subservice
json_regions = data["services"][service]["regions"][self.identity.partition]
if (
self.identity.audited_regions
): # Check for input aws audit_info.audited_regions
regions = list(
set(json_regions).intersection(self.identity.audited_regions)
) # Get common regions between input and json
else: # Get all regions from json of the service and partition
regions = json_regions
return regions
def get_aws_available_regions():
try:
actual_directory = pathlib.Path(os.path.dirname(os.path.realpath(__file__)))
with open_file(f"{actual_directory}/{aws_services_json_file}") as f:
data = parse_json_file(f)
regions = set()
for service in data["services"].values():
for partition in service["regions"]:
for item in service["regions"][partition]:
regions.add(item)
return list(regions)
except Exception as error:
logger.error(f"{error.__class__.__name__}: {error}")
return []
def get_checks_from_input_arn(audit_resources: list, provider: str) -> set:
"""get_checks_from_input_arn gets the list of checks from the input arns"""
checks_from_arn = set()
is_subservice_in_checks = False
# Handle if there are audit resources so only their services are executed
if audit_resources:
services_without_subservices = ["guardduty", "kms", "s3", "elb", "efs"]
service_list = set()
sub_service_list = set()
for resource in audit_resources:
service = resource.split(":")[2]
sub_service = resource.split(":")[5].split("/")[0].replace("-", "_")
# WAF Services does not have checks
if service != "wafv2" and service != "waf":
# Parse services when they are different in the ARNs
if service == "lambda":
service = "awslambda"
elif service == "elasticloadbalancing":
service = "elb"
elif service == "elasticfilesystem":
service = "efs"
elif service == "logs":
service = "cloudwatch"
# Check if Prowler has checks in service
try:
list_modules(provider, service)
except ModuleNotFoundError:
# Service is not supported
pass
else:
service_list.add(service)
# Get subservices to execute only applicable checks
if service not in services_without_subservices:
# Parse some specific subservices
if service == "ec2":
if sub_service == "security_group":
sub_service = "securitygroup"
if sub_service == "network_acl":
sub_service = "networkacl"
if sub_service == "image":
sub_service = "ami"
if service == "rds":
if sub_service == "cluster_snapshot":
sub_service = "snapshot"
sub_service_list.add(sub_service)
else:
sub_service_list.add(service)
checks = recover_checks_from_service(service_list, provider)
# Filter only checks with audited subservices
for check in checks:
if any(sub_service in check for sub_service in sub_service_list):
if not (sub_service == "policy" and "password_policy" in check):
checks_from_arn.add(check)
is_subservice_in_checks = True
if not is_subservice_in_checks:
checks_from_arn = checks
# Return final checks list
return sorted(checks_from_arn)
def get_regions_from_audit_resources(audit_resources: list) -> set:
"""get_regions_from_audit_resources gets the regions from the audit resources arns"""
audited_regions = set()
for resource in audit_resources:
region = resource.split(":")[3]
if region:
audited_regions.add(region)
return audited_regions
def get_tagged_resources(self, input_resource_tags: list):
"""
get_tagged_resources returns a list of the resources that are going to be scanned based on the given input tags
"""
try:
resource_tags = []
tagged_resources = []
for tag in input_resource_tags:
key = tag.split("=")[0]
value = tag.split("=")[1]
resource_tags.append({"Key": key, "Values": [value]})
# Get Resources with resource_tags for all regions
for regional_client in self.generate_regional_clients(
"resourcegroupstaggingapi"
).values():
try:
get_resources_paginator = regional_client.get_paginator(
"get_resources"
)
for page in get_resources_paginator.paginate(
TagFilters=resource_tags
):
for resource in page["ResourceTagMappingList"]:
tagged_resources.append(resource["ResourceARN"])
except Exception as error:
logger.error(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
logger.critical(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
sys.exit(1)
else:
return tagged_resources
def get_default_region(self, service: str) -> str:
"""get_default_region gets the default region based on the profile and audited service regions"""
service_regions = self.get_available_aws_service_regions(service)
default_region = (
self.get_global_region()
) # global region of the partition when all regions are audited and there is no profile region
if self.identity.profile_region in service_regions:
# return profile region only if it is audited
default_region = self.identity.profile_region
# return first audited region if specific regions are audited
elif self.identity.audited_regions:
default_region = self.identity.audited_regions[0]
return default_region
def get_global_region(self) -> str:
"""get_global_region gets the global region based on the audited partition"""
global_region = "us-east-1"
if self.identity.partition == "aws-cn":
global_region = "cn-north-1"
elif self.identity.partition == "aws-us-gov":
global_region = "us-gov-east-1"
elif "aws-iso" in self.identity.partition:
global_region = "aws-iso-global"
return global_region
def __input_role_mfa_token_and_code__() -> tuple[str]:
"""input_role_mfa_token_and_code ask for the AWS MFA ARN and TOTP and returns it."""
mfa_ARN = input("Enter ARN of MFA: ")
mfa_TOTP = input("Enter MFA code: ")
return (mfa_ARN.strip(), mfa_TOTP.strip())
def __set_session_config__(self, aws_retries_max_attempts: bool):
session_config = Config(
retries={"max_attempts": 3, "mode": "standard"},
user_agent_extra=BOTO3_USER_AGENT_EXTRA,
)
if aws_retries_max_attempts:
# Create the new config
config = Config(
retries={
"max_attempts": aws_retries_max_attempts,
"mode": "standard",
},
)
# Merge the new configuration
session_config = self.session.session_config.merge(config)
return session_config
def __assume_role__(
self,
session,
sts_endpoint_region: str,
) -> dict:
try:
assume_role_arguments = {
"RoleArn": self.assumed_role.assumed_role_info.role_arn,
"RoleSessionName": "ProwlerAsessmentSession",
"DurationSeconds": self.assumed_role.assumed_role_info.session_duration,
}
# Set the info to assume the role from the partition, account and role name
if self.assumed_role.assumed_role_info.external_id:
assume_role_arguments[
"ExternalId"
] = self.assumed_role.assumed_role_info.external_id
if self.assumed_role.assumed_role_info.mfa_enabled:
mfa_ARN, mfa_TOTP = self.__input_role_mfa_token_and_code__()
assume_role_arguments["SerialNumber"] = mfa_ARN
assume_role_arguments["TokenCode"] = mfa_TOTP
# Set the STS Endpoint Region
if sts_endpoint_region is None:
sts_endpoint_region = AWS_STS_GLOBAL_ENDPOINT_REGION
sts_client = create_sts_session(session, sts_endpoint_region)
assumed_credentials = sts_client.assume_role(**assume_role_arguments)
except Exception as error:
logger.critical(
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}] -- {error}"
)
sys.exit(1)
else:
return assumed_credentials
@@ -2,7 +2,7 @@ from boto3 import session
from botocore.config import Config
from prowler.providers.aws.config import BOTO3_USER_AGENT_EXTRA
from prowler.providers.aws.lib.audit_info.models import AWS_Assume_Role, AWS_Audit_Info
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info, AWSAssumeRole
# Default Current Audit Info
current_audit_info = AWS_Audit_Info(
@@ -25,7 +25,7 @@ current_audit_info = AWS_Audit_Info(
profile=None,
profile_region=None,
credentials=None,
assumed_role_info=AWS_Assume_Role(
assumed_role_info=AWSAssumeRole(
role_arn=None,
session_duration=None,
external_id=None,
@@ -7,7 +7,7 @@ from botocore.config import Config
@dataclass
class AWS_Credentials:
class AWSCredentials:
aws_access_key_id: str
aws_session_token: str
aws_secret_access_key: str
@@ -15,7 +15,7 @@ class AWS_Credentials:
@dataclass
class AWS_Assume_Role:
class AWSAssumeRole:
role_arn: str
session_duration: int
external_id: str
@@ -23,7 +23,7 @@ class AWS_Assume_Role:
@dataclass
class AWS_Organizations_Info:
class AWSOrganizationsInfo:
account_details_email: str
account_details_name: str
account_details_arn: str
@@ -44,12 +44,12 @@ class AWS_Audit_Info:
audited_partition: str
profile: str
profile_region: str
credentials: AWS_Credentials
credentials: AWSCredentials
mfa_enabled: bool
assumed_role_info: AWS_Assume_Role
assumed_role_info: AWSAssumeRole
audited_regions: list
audit_resources: list
organizations_metadata: AWS_Organizations_Info
audit_metadata: Optional[Any] = None
organizations_metadata: AWSOrganizationsInfo
audit_metadata: Optional[Any]
audit_config: Optional[dict] = None
ignore_unused_services: bool = False
@@ -8,7 +8,7 @@ from prowler.providers.aws.config import AWS_STS_GLOBAL_ENDPOINT_REGION
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
def validate_aws_credentials(
def validate_AWSCredentials(
session: session, input_regions: list, sts_endpoint_region: str = None
) -> dict:
try:
@@ -38,7 +38,7 @@ def validate_aws_credentials(
return caller_identity
def print_aws_credentials(audit_info: AWS_Audit_Info):
def print_AWSCredentials(audit_info: AWS_Audit_Info):
# Beautify audited regions, set "all" if there is no filter region
regions = (
", ".join(audit_info.audited_regions)
@@ -3,12 +3,12 @@ import sys
from boto3 import client
from prowler.lib.logger import logger
from prowler.providers.aws.lib.audit_info.models import AWS_Organizations_Info
from prowler.providers.aws.lib.audit_info.models import AWSOrganizationsInfo
def get_organizations_metadata(
metadata_account: str, assumed_credentials: dict
) -> AWS_Organizations_Info:
) -> AWSOrganizationsInfo:
try:
organizations_client = client(
"organizations",
@@ -30,7 +30,7 @@ def get_organizations_metadata(
account_details_tags = ""
for tag in list_tags_for_resource["Tags"]:
account_details_tags += tag["Key"] + ":" + tag["Value"] + ","
organizations_info = AWS_Organizations_Info(
organizations_info = AWSOrganizationsInfo(
account_details_email=organizations_metadata["Account"]["Email"],
account_details_name=organizations_metadata["Account"]["Name"],
account_details_arn=organizations_metadata["Account"]["Arn"],
+13 -17
View File
@@ -1,10 +1,6 @@
import threading
from prowler.providers.aws.aws_provider import (
generate_regional_clients,
get_default_region,
)
from prowler.providers.aws.lib.audit_info.models import AWS_Audit_Info
from prowler.providers.aws.aws_provider_new import AwsProvider
class AWSService:
@@ -15,18 +11,18 @@ class AWSService:
- Also handles if the AWS Service is Global
"""
def __init__(self, service: str, audit_info: AWS_Audit_Info, global_service=False):
def __init__(self, service: str, provider: AwsProvider, global_service=False):
# Audit Information
self.audit_info = audit_info
self.audited_account = audit_info.audited_account
self.audited_account_arn = audit_info.audited_account_arn
self.audited_partition = audit_info.audited_partition
self.audit_resources = audit_info.audit_resources
self.audited_checks = audit_info.audit_metadata.expected_checks
self.audit_config = audit_info.audit_config
self.provider = provider
self.audited_account = provider.identity.account
self.audited_account_arn = provider.identity.account_arn
self.audited_partition = provider.identity.partition
self.audit_resources = provider.audit_resources
self.audited_checks = provider.audit_metadata.expected_checks
self.audit_config = provider.audit_config
# AWS Session
self.session = audit_info.audit_session
self.session = provider.session.session
# We receive the service using __class__.__name__ or the service name in lowercase
# e.g.: AccessAnalyzer --> we need a lowercase string, so service.lower()
@@ -34,14 +30,14 @@ class AWSService:
# Generate Regional Clients
if not global_service:
self.regional_clients = generate_regional_clients(
self.service, audit_info, global_service
self.regional_clients = provider.generate_regional_clients(
self.service, global_service
)
# Get a single region and client if the service needs it (e.g. AWS Global Service)
# We cannot include this within an else because some services needs both the regional_clients
# and a single client like S3
self.region = get_default_region(self.service, audit_info)
self.region = provider.get_default_region(self.service)
self.client = self.session.client(self.service, self.region)
def __get_session__(self):
@@ -1,6 +1,6 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.accessanalyzer.accessanalyzer_service import (
AccessAnalyzer,
)
from prowler.providers.common.common import get_global_provider
accessanalyzer_client = AccessAnalyzer(current_audit_info)
accessanalyzer_client = AccessAnalyzer(get_global_provider())
@@ -10,9 +10,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## AccessAnalyzer
class AccessAnalyzer(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.analyzers = []
self.__threading_call__(self.__list_analyzers__)
self.__list_findings__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.account.account_service import Account
from prowler.providers.common.common import get_global_provider
account_client = Account(current_audit_info)
account_client = Account(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
class Account(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.number_of_contacts = 4
self.contact_base = self.__get_contact_information__()
self.contacts_billing = self.__get_alternate_contact__("BILLING")
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.acm.acm_service import ACM
from prowler.providers.common.common import get_global_provider
acm_client = ACM(current_audit_info)
acm_client = ACM(get_global_provider())
@@ -10,9 +10,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## ACM
class ACM(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.certificates = []
self.__threading_call__(self.__list_certificates__)
self.__describe_certificates__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.apigateway.apigateway_service import APIGateway
from prowler.providers.common.common import get_global_provider
apigateway_client = APIGateway(current_audit_info)
apigateway_client = APIGateway(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## APIGateway
class APIGateway(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.rest_apis = []
self.__threading_call__(self.__get_rest_apis__)
self.__get_authorizers__()
@@ -1,6 +1,6 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.apigatewayv2.apigatewayv2_service import (
ApiGatewayV2,
)
from prowler.providers.common.common import get_global_provider
apigatewayv2_client = ApiGatewayV2(current_audit_info)
apigatewayv2_client = ApiGatewayV2(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## ApiGatewayV2
class ApiGatewayV2(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.apis = []
self.__threading_call__(self.__get_apis__)
self.__get_authorizers__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.appstream.appstream_service import AppStream
from prowler.providers.common.common import get_global_provider
appstream_client = AppStream(current_audit_info)
appstream_client = AppStream(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## AppStream
class AppStream(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.fleets = []
self.__threading_call__(self.__describe_fleets__)
self.__list_tags_for_resource__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.athena.athena_service import Athena
from prowler.providers.common.common import get_global_provider
athena_client = Athena(current_audit_info)
athena_client = Athena(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## Athena
class Athena(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.workgroups = {}
self.__threading_call__(self.__list_workgroups__)
self.__get_workgroups__()
@@ -12,7 +12,7 @@ class athena_workgroup_encryption(Check):
# Only check for enabled and used workgroups (has recent queries)
if (
workgroup.state == "ENABLED" and workgroup.queries
) or not athena_client.audit_info.ignore_unused_services:
) or not athena_client.provider.ignore_unused_services:
report = Check_Report_AWS(self.metadata())
report.region = workgroup.region
report.resource_id = workgroup.name
@@ -12,7 +12,7 @@ class athena_workgroup_enforce_configuration(Check):
# Only check for enabled and used workgroups (has recent queries)
if (
workgroup.state == "ENABLED" and workgroup.queries
) or not athena_client.audit_info.ignore_unused_services:
) or not athena_client.provider.ignore_unused_services:
report = Check_Report_AWS(self.metadata())
report.region = workgroup.region
report.resource_id = workgroup.name
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.autoscaling.autoscaling_service import AutoScaling
from prowler.providers.common.common import get_global_provider
autoscaling_client = AutoScaling(current_audit_info)
autoscaling_client = AutoScaling(get_global_provider())
@@ -7,9 +7,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## AutoScaling
class AutoScaling(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.launch_configurations = []
self.__threading_call__(self.__describe_launch_configurations__)
self.groups = []
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.awslambda.awslambda_service import Lambda
from prowler.providers.common.common import get_global_provider
awslambda_client = Lambda(current_audit_info)
awslambda_client = Lambda(get_global_provider())
@@ -15,9 +15,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## Lambda
class Lambda(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.functions = {}
self.__threading_call__(self.__list_functions__)
self.__list_tags_for_resource__()
@@ -26,7 +26,7 @@ class Lambda(AWSService):
# awslambda_function_no_secrets_in_code check is set
if (
"awslambda_function_no_secrets_in_code"
in audit_info.audit_metadata.expected_checks
in provider.audit_metadata.expected_checks
):
self.__threading_call__(self.__get_function__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.backup.backup_service import Backup
from prowler.providers.common.common import get_global_provider
backup_client = Backup(current_audit_info)
backup_client = Backup(get_global_provider())
@@ -10,9 +10,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## Backup
class Backup(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.backup_vaults = []
self.__threading_call__(self.__list_backup_vaults__)
self.backup_plans = []
@@ -1,6 +1,6 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.cloudformation.cloudformation_service import (
CloudFormation,
)
from prowler.providers.common.common import get_global_provider
cloudformation_client = CloudFormation(current_audit_info)
cloudformation_client = CloudFormation(get_global_provider())
@@ -10,9 +10,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## CloudFormation
class CloudFormation(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.stacks = []
self.__threading_call__(self.__describe_stacks__)
self.__describe_stack__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.cloudfront.cloudfront_service import CloudFront
from prowler.providers.common.common import get_global_provider
cloudfront_client = CloudFront(current_audit_info)
cloudfront_client = CloudFront(get_global_provider())
@@ -10,9 +10,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## CloudFront
class CloudFront(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info, global_service=True)
super().__init__(__class__.__name__, provider, global_service=True)
self.distributions = {}
self.__list_distributions__(self.client, self.region)
self.__get_distribution_config__(self.client, self.distributions, self.region)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.cloudtrail.cloudtrail_service import Cloudtrail
from prowler.providers.common.common import get_global_provider
cloudtrail_client = Cloudtrail(current_audit_info)
cloudtrail_client = Cloudtrail(get_global_provider())
@@ -50,7 +50,7 @@ class cloudtrail_s3_dataevents_read_enabled(Check):
report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has an advanced data event selector to record all S3 object-level API operations."
findings.append(report)
if not findings and (
s3_client.buckets or not cloudtrail_client.audit_info.ignore_unused_services
s3_client.buckets or not cloudtrail_client.provider.ignore_unused_services
):
report = Check_Report_AWS(self.metadata())
report.region = cloudtrail_client.region
@@ -50,7 +50,7 @@ class cloudtrail_s3_dataevents_write_enabled(Check):
report.status_extended = f"Trail {trail.name} from home region {trail.home_region} has an advanced data event selector to record all S3 object-level API operations."
findings.append(report)
if not findings and (
s3_client.buckets or not cloudtrail_client.audit_info.ignore_unused_services
s3_client.buckets or not cloudtrail_client.provider.ignore_unused_services
):
report = Check_Report_AWS(self.metadata())
report.region = cloudtrail_client.region
@@ -11,9 +11,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################### CLOUDTRAIL
class Cloudtrail(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.trails = []
self.__threading_call__(self.__get_trails__)
self.__get_trail_status__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import CloudWatch
from prowler.providers.common.common import get_global_provider
cloudwatch_client = CloudWatch(current_audit_info)
cloudwatch_client = CloudWatch(get_global_provider())
@@ -11,9 +11,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## CloudWatch
class CloudWatch(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.metric_alarms = []
self.__threading_call__(self.__describe_alarms__)
self.__list_tags_for_resource__()
@@ -64,16 +64,16 @@ class CloudWatch(AWSService):
################## CloudWatch Logs
class Logs(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.metric_filters = []
self.log_groups = []
self.__threading_call__(self.__describe_metric_filters__)
self.__threading_call__(self.__describe_log_groups__)
if (
"cloudwatch_log_group_no_secrets_in_logs"
in audit_info.audit_metadata.expected_checks
in provider.audit_metadata.expected_checks
):
self.events_per_log_group_threshold = (
1000 # The threshold for number of events to return per log group.
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.cloudwatch.cloudwatch_service import Logs
from prowler.providers.common.common import get_global_provider
logs_client = Logs(current_audit_info)
logs_client = Logs(get_global_provider())
@@ -1,6 +1,6 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.codeartifact.codeartifact_service import (
CodeArtifact,
)
from prowler.providers.common.common import get_global_provider
codeartifact_client = CodeArtifact(current_audit_info)
codeartifact_client = CodeArtifact(get_global_provider())
@@ -11,9 +11,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## CodeArtifact
class CodeArtifact(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
# repositories is a dictionary containing all the codeartifact service information
self.repositories = {}
self.__threading_call__(self.__list_repositories__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.codebuild.codebuild_service import Codebuild
from prowler.providers.common.common import get_global_provider
codebuild_client = Codebuild(current_audit_info)
codebuild_client = Codebuild(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################### Codebuild
class Codebuild(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.projects = []
self.__threading_call__(self.__list_projects__)
self.__list_builds_for_project__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.config.config_service import Config
from prowler.providers.common.common import get_global_provider
config_client = Config(current_audit_info)
config_client = Config(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## Config
class Config(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.recorders = []
self.__threading_call__(self.__describe_configuration_recorder_status__)
@@ -1,6 +1,6 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.directoryservice.directoryservice_service import (
DirectoryService,
)
from prowler.providers.common.common import get_global_provider
directoryservice_client = DirectoryService(current_audit_info)
directoryservice_client = DirectoryService(get_global_provider())
@@ -12,9 +12,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## DirectoryService
class DirectoryService(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__("ds", audit_info)
super().__init__("ds", provider)
self.directories = {}
self.__threading_call__(self.__describe_directories__)
self.__threading_call__(self.__list_log_subscriptions__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.dlm.dlm_service import DLM
from prowler.providers.common.common import get_global_provider
dlm_client = DLM(current_audit_info)
dlm_client = DLM(get_global_provider())
@@ -6,9 +6,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## Data Lifecycle Manager
class DLM(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.lifecycle_policies = {}
self.__threading_call__(self.__get_lifecycle_policies__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.documentdb.documentdb_service import DocumentDB
from prowler.providers.common.common import get_global_provider
documentdb_client = DocumentDB(current_audit_info)
documentdb_client = DocumentDB(get_global_provider())
@@ -9,10 +9,10 @@ from prowler.providers.aws.lib.service.service import AWSService
################## DocumentDB
class DocumentDB(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
self.service_name = "docdb"
super().__init__(self.service_name, audit_info)
super().__init__(self.service_name, provider)
self.db_instances = {}
self.__threading_call__(self.__describe_db_instances__)
self.__list_tags_for_resource__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.drs.drs_service import DRS
from prowler.providers.common.common import get_global_provider
drs_client = DRS(current_audit_info)
drs_client = DRS(get_global_provider())
@@ -8,9 +8,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## DRS (Elastic Disaster Recovery Service)
class DRS(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.drs_services = []
self.__threading_call__(self.__describe_jobs__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.dynamodb.dynamodb_service import DAX
from prowler.providers.common.common import get_global_provider
dax_client = DAX(current_audit_info)
dax_client = DAX(get_global_provider())
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.dynamodb.dynamodb_service import DynamoDB
from prowler.providers.common.common import get_global_provider
dynamodb_client = DynamoDB(current_audit_info)
dynamodb_client = DynamoDB(get_global_provider())
@@ -10,9 +10,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## DynamoDB
class DynamoDB(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.tables = []
self.__threading_call__(self.__list_tables__)
self.__describe_table__()
@@ -121,9 +121,9 @@ class DynamoDB(AWSService):
################## DynamoDB DAX
class DAX(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.clusters = []
self.__threading_call__(self.__describe_clusters__)
self.__list_tags_for_resource__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.ec2.ec2_service import EC2
from prowler.providers.common.common import get_global_provider
ec2_client = EC2(current_audit_info)
ec2_client = EC2(get_global_provider())
@@ -15,8 +15,7 @@ class ec2_ebs_default_encryption(Check):
report.status_extended = "EBS Default Encryption is activated."
findings.append(report)
elif (
not ec2_client.audit_info.ignore_unused_services
or ebs_encryption.volumes
not ec2_client.provider.ignore_unused_services or ebs_encryption.volumes
):
report.status = "FAIL"
report.status_extended = "EBS Default Encryption is not activated."
@@ -10,7 +10,7 @@ class ec2_networkacl_allow_ingress_any_port(Check):
check_port = 0
for network_acl in ec2_client.network_acls:
if (
not ec2_client.audit_info.ignore_unused_services
not ec2_client.provider.ignore_unused_services
or network_acl.region in ec2_client.regions_with_sgs
):
# If some entry allows it, that ACL is not securely configured
@@ -10,7 +10,7 @@ class ec2_networkacl_allow_ingress_tcp_port_22(Check):
check_port = 22
for network_acl in ec2_client.network_acls:
if (
not ec2_client.audit_info.ignore_unused_services
not ec2_client.provider.ignore_unused_services
or network_acl.region in ec2_client.regions_with_sgs
):
# If some entry allows it, that ACL is not securely configured
@@ -10,7 +10,7 @@ class ec2_networkacl_allow_ingress_tcp_port_3389(Check):
check_port = 3389
for network_acl in ec2_client.network_acls:
if (
not ec2_client.audit_info.ignore_unused_services
not ec2_client.provider.ignore_unused_services
or network_acl.region in ec2_client.regions_with_sgs
):
# If some entry allows it, that ACL is not securely configured
@@ -8,7 +8,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_any_port(Check):
findings = []
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_port_mongodb_27017_27018(
check_ports = [27017, 27018]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_ftp_port_20_21(Check)
check_ports = [20, 21]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_22(Check):
check_ports = [22]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_3389(Check):
check_ports = [3389]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -12,7 +12,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_cassandra_7199_9
check_ports = [7199, 9160, 8888]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -12,7 +12,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_elasticsearch_ki
check_ports = [9200, 9300, 5601]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_kafka_9092(Check
check_ports = [9092]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_memcached_11211(
check_ports = [11211]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_mysql_3306(Check
check_ports = [3306]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_oracle_1521_2483
check_ports = [1521, 2483]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_postgres_5432(Ch
check_ports = [5432]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_redis_6379(Check
check_ports = [6379]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -12,7 +12,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_sql_server_1433_
check_ports = [1433, 1434]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -10,7 +10,7 @@ class ec2_securitygroup_allow_ingress_from_internet_to_tcp_port_telnet_23(Check)
check_ports = [23]
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -11,7 +11,7 @@ class ec2_securitygroup_allow_wide_open_public_ipv4(Check):
cidr_treshold = 24
for security_group in ec2_client.security_groups:
# Check if ignoring flag is set and if the VPC and the SG is in use
if not ec2_client.audit_info.ignore_unused_services or (
if not ec2_client.provider.ignore_unused_services or (
security_group.vpc_id in vpc_client.vpcs
and vpc_client.vpcs[security_group.vpc_id].in_use
and len(security_group.network_interfaces) > 0
@@ -12,9 +12,9 @@ from prowler.providers.aws.services.ec2.lib.security_groups import check_securit
################## EC2
class EC2(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.instances = []
self.__threading_call__(self.__describe_instances__)
self.__get_instance_user_data__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.ecr.ecr_service import ECR
from prowler.providers.common.common import get_global_provider
ecr_client = ECR(current_audit_info)
ecr_client = ECR(get_global_provider())
@@ -12,10 +12,10 @@ from prowler.providers.aws.lib.service.service import AWSService
################################ ECR
class ECR(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
self.registry_id = audit_info.audited_account
super().__init__(__class__.__name__, provider)
self.registry_id = self.audited_account
self.registries = {}
self.__threading_call__(self.__describe_registries_and_repositories__)
self.__threading_call__(self.__describe_repository_policies__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.ecs.ecs_service import ECS
from prowler.providers.common.common import get_global_provider
ecs_client = ECS(current_audit_info)
ecs_client = ECS(get_global_provider())
@@ -10,9 +10,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################################ ECS
class ECS(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.task_definitions = []
self.__threading_call__(self.__list_task_definitions__)
self.__describe_task_definition__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.efs.efs_service import EFS
from prowler.providers.common.common import get_global_provider
efs_client = EFS(current_audit_info)
efs_client = EFS(get_global_provider())
@@ -11,9 +11,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################### EFS
class EFS(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.filesystems = []
self.__threading_call__(self.__describe_file_systems__)
self.__describe_file_system_policies__()
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.eks.eks_service import EKS
from prowler.providers.common.common import get_global_provider
eks_client = EKS(current_audit_info)
eks_client = EKS(get_global_provider())
@@ -4,16 +4,14 @@ from pydantic import BaseModel
from prowler.lib.logger import logger
from prowler.lib.scan_filters.scan_filters import is_resource_filtered
from prowler.providers.aws.aws_provider import generate_regional_clients
from prowler.providers.aws.lib.service.service import AWSService
################################ EKS
class EKS(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
self.regional_clients = generate_regional_clients(self.service, audit_info)
super().__init__(__class__.__name__, provider)
self.clusters = []
self.__threading_call__(self.__list_clusters__)
self.__describe_cluster__(self.regional_clients)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.elasticache.elasticache_service import ElastiCache
from prowler.providers.common.common import get_global_provider
elasticache_client = ElastiCache(current_audit_info)
elasticache_client = ElastiCache(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################################ Elasticache
class ElastiCache(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.clusters = {}
self.__threading_call__(self.__describe_cache_clusters__)
self.__threading_call__(self.__describe_cache_subnet_groups__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.elb.elb_service import ELB
from prowler.providers.common.common import get_global_provider
elb_client = ELB(current_audit_info)
elb_client = ELB(get_global_provider())
@@ -9,9 +9,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################### ELB
class ELB(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.loadbalancers = []
self.__threading_call__(self.__describe_load_balancers__)
self.__threading_call__(self.__describe_load_balancer_attributes__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.elbv2.elbv2_service import ELBv2
from prowler.providers.common.common import get_global_provider
elbv2_client = ELBv2(current_audit_info)
elbv2_client = ELBv2(get_global_provider())
@@ -10,9 +10,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################### ELBv2
class ELBv2(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.loadbalancersv2 = []
self.__threading_call__(self.__describe_load_balancers__)
self.listeners = []
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.emr.emr_service import EMR
from prowler.providers.common.common import get_global_provider
emr_client = EMR(current_audit_info)
emr_client = EMR(get_global_provider())
@@ -11,9 +11,9 @@ from prowler.providers.aws.lib.service.service import AWSService
################## EMR
class EMR(AWSService):
def __init__(self, audit_info):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, audit_info)
super().__init__(__class__.__name__, provider)
self.clusters = {}
self.block_public_access_configuration = {}
self.__threading_call__(self.__list_clusters__)
@@ -1,4 +1,4 @@
from prowler.providers.aws.lib.audit_info.audit_info import current_audit_info
from prowler.providers.aws.services.fms.fms_service import FMS
from prowler.providers.common.common import get_global_provider
fms_client = FMS(current_audit_info)
fms_client = FMS(get_global_provider())

Some files were not shown because too many files have changed in this diff Show More