docs(aws): improve docstrings (#5714)

Co-authored-by: Pepe Fagoaga <pepe@prowler.com>
This commit is contained in:
Pedro Martín
2024-11-18 12:17:05 +01:00
committed by GitHub
parent 0d01790b22
commit 5d7c8d9cd2
+183 -6
View File
@@ -70,6 +70,25 @@ from prowler.providers.common.provider import Provider
class AwsProvider(Provider):
"""
AwsProvider class is the main class for the AWS provider.
This class is responsible for initializing the AWS provider, setting up the AWS session, validating the AWS
credentials, assuming an IAM role, getting the AWS Organizations metadata, and setting the AWS identity.
Attributes:
_type (str): The provider type.
_identity (AWSIdentityInfo): The AWS provider identity information.
_session (AWSSession): The AWS provider session.
_organizations_metadata (AWSOrganizationsInfo): The AWS Organizations metadata.
_audit_resources (list): The list of resources to audit.
_audit_config (dict): The audit configuration.
_scan_unused_services (bool): A boolean indicating whether to scan unused services.
_enabled_regions (set): The set of enabled regions.
_mutelist (AWSMutelist): The AWS provider mutelist.
audit_metadata (Audit_Metadata): The audit metadata.
"""
_type: str = "aws"
_identity: AWSIdentityInfo
_session: AWSSession
@@ -111,7 +130,7 @@ class AwsProvider(Provider):
Args:
- retries_max_attempts: The maximum number of retries for the AWS client.
- role_arn: The ARN of the IAM role to assume.
- session_duration: The duration of the session in seconds.
- session_duration: The duration of the session in seconds, between 900 and 43200.
- external_id: The external ID to use when assuming the IAM role.
- role_session_name: The name of the session when assuming the IAM role.
- mfa: A boolean indicating whether MFA is enabled.
@@ -136,6 +155,37 @@ class AwsProvider(Provider):
- ArgumentTypeError: If the input external ID is invalid.
- ArgumentTypeError: If the input role session name is invalid.
Usage:
- Boto3 is used so we follow their credential setup process:
- Authentication: Make sure you have properly configured your AWS CLI with a valid Access Key and Region or declare the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment variables.
- aws configure
or
- export AWS_ACCESS_KEY_ID="ASXXXXXXX"
export AWS_SECRET_ACCESS_KEY="XXXXXXXXX"
export AWS_SESSION_TOKEN="XXXXXXXXX"
- To create a new aws object you can use:
- aws = AwsProvider()
- aws = AwsProvider(aws_access_key_id="ASXXXXXXX", aws_secret_access_key="XXXXXXXXX", aws_session_token="XXXXXXXXX")
- Profile: If you have multiple profiles in your AWS CLI configuration, you can specify the profile to use:
- aws = AwsProvider(profile="profile_name")
- MFA: If you have MFA enabled you can specify it:
- aws = AwsProvider(mfa=True)
* Note: If you have MFA enabled you will be prompted to enter the MFA ARN and the MFA TOTP code.
* Note: Take into account that you can use static credentials or a profile, with the combination of MFA.
- Assume Role: *Requires authentication.* Prowler can be used against multiple accounts using IAM Assume Role features depending on each use case:
- Set up a custom profile inside your AWS CLI configuration file:
- [profile profile_name]
role_arn = arn:aws:iam::123456789012:role/role_name
- aws = AwsProvider(profile="profile_name")
- Use role_arn directly:
- aws = AwsProvider(role_arn="arn:aws:iam::123456789012:role/role_name")
- Use role_arn with session duration(in seconds, by default 3600) and external ID:
- aws = AwsProvider(role_arn="arn:aws:iam::123456789012:role/role_name", session_duration=3600, external_id="external_id")
- Use custom role session name:
- aws = AwsProvider(role_arn="arn:aws:iam::123456789012:role/role_name", role_session_name="custom_session_name")
* Note: You can use the combination of MFA with Assume Role.
- aws = AwsProvider(role_arn="arn:aws:iam::123456789012:role/role_name", mfa=True)
"""
logger.info("Initializing AWS provider ...")
@@ -426,6 +476,21 @@ class AwsProvider(Provider):
regions: set,
profile_region: str,
) -> AWSIdentityInfo:
"""
set_identity sets the AWS provider identity information.
Args:
- caller_identity: The AWS caller identity information.
- profile: The AWS CLI profile name.
- regions: A set of regions to audit.
- profile_region: The AWS CLI profile region.
Returns:
- AWSIdentityInfo: The AWS provider identity information.
Raises:
- AWSInvalidProviderIdError: If the AWS provider ID is invalid.
"""
logger.info(f"Original AWS Caller Identity UserId: {caller_identity.user_id}")
logger.info(f"Original AWS Caller Identity ARN: {caller_identity.arn}")
@@ -449,6 +514,22 @@ class AwsProvider(Provider):
aws_secret_access_key: str = None,
aws_session_token: Optional[str] = None,
) -> Session:
"""
setup_session sets up an AWS session using the provided credentials.
Args:
- mfa: A boolean indicating whether MFA is enabled.
- profile: The name of the AWS CLI profile to use.
- aws_access_key_id: The AWS access key ID.
- aws_secret_access_key: The AWS secret access key.
- aws_session_token: The AWS session token, optional.
Returns:
- Session: The AWS session.
Raises:
- AWSSetUpSessionError: If an error occurs during the setup process.
"""
try:
logger.debug("Creating original session ...")
@@ -590,6 +671,21 @@ class AwsProvider(Provider):
return refreshed_credentials
def print_credentials(self):
"""
Print the AWS credentials.
This method prints the AWS credentials used by the provider.
Example output:
```
Using the AWS credentials below:
AWS-CLI Profile: default
AWS Regions: all
AWS Account: 123456789012
User Id: AIDAJDPLRKLG7EXAMPLE
Caller Identity ARN: arn:aws:iam::123456789012:user/prowler
```
"""
# Beautify audited regions, set "all" if there is no filter region
regions = (
", ".join(self._identity.audited_regions)
@@ -681,6 +777,12 @@ class AwsProvider(Provider):
def get_checks_from_input_arn(self) -> set:
"""
get_checks_from_input_arn gets the list of checks from the input arns
Returns:
- set: set of strings representing the checks from the input arns
Example:
checks = get_checks_from_input_arn()
"""
checks_from_arn = set()
is_subservice_in_checks = False
@@ -747,7 +849,18 @@ class AwsProvider(Provider):
# TODO: This can be moved to another class since it doesn't need self
def get_regions_from_audit_resources(self, audit_resources: list) -> set:
"""get_regions_from_audit_resources gets the regions from the audit resources arns"""
"""get_regions_from_audit_resources gets the regions from the audit resources arns
Args:
- audit_resources: list of ARNs of the resources to audit
Returns:
- set: set of strings representing the regions from the audit resources arns
Example:
audit_resources = ["arn:aws:ec2:us-east-1:123456789012:instance/i-1234567890abcdef0"]
regions = get_regions_from_audit_resources(audit_resources)
"""
audited_regions = set()
for resource in audit_resources:
region = resource.split(":")[3]
@@ -807,7 +920,18 @@ class AwsProvider(Provider):
raise error
def get_default_region(self, service: str) -> str:
"""get_default_region returns the default region based on the profile and audited service regions"""
"""get_default_region returns the default region based on the profile and audited service regions
Args:
- service: The AWS service name
Returns:
- str: The default region for the given service
Example:
service = "ec2"
default_region = get_default_region(service)
"""
try:
service_regions = AwsProvider.get_available_aws_service_regions(
service, self._identity.partition, self._identity.audited_regions
@@ -828,7 +952,14 @@ class AwsProvider(Provider):
raise error
def get_global_region(self) -> str:
"""get_global_region returns the global region based on the audited partition"""
"""get_global_region returns the global region based on the audited partition
Returns:
- str: The global region for the audited partition
Example:
global_region = get_global_region()a
"""
global_region = "us-east-1"
if self._identity.partition == "aws-cn":
global_region = "cn-north-1"
@@ -840,7 +971,14 @@ class AwsProvider(Provider):
@staticmethod
def input_role_mfa_token_and_code() -> AWSMFAInfo:
"""input_role_mfa_token_and_code ask for the AWS MFA ARN and TOTP and returns it."""
"""input_role_mfa_token_and_code ask for the AWS MFA ARN and TOTP and returns it.
Returns:
- AWSMFAInfo: An object containing the MFA ARN and TOTP code
Example:
mfa_info = input_role_mfa_token_and_code()
"""
mfa_ARN = input("Enter ARN of MFA: ")
mfa_TOTP = input("Enter MFA code: ")
return AWSMFAInfo(arn=mfa_ARN, totp=mfa_TOTP)
@@ -848,6 +986,12 @@ class AwsProvider(Provider):
def set_session_config(self, retries_max_attempts: int) -> Config:
"""
set_session_config returns a botocore Config object with the Prowler user agent and the default retrier configuration if nothing is passed as argument
Args:
- retries_max_attempts: The maximum number of retries for the standard retrier config
Returns:
- Config: The botocore Config object
"""
# Set the maximum retries for the standard retrier config
default_session_config = Config(
@@ -874,6 +1018,13 @@ class AwsProvider(Provider):
) -> AWSCredentials:
"""
assume_role assumes the IAM roles passed with the given session and returns AWSCredentials
Args:
- session: The AWS session object
- assumed_role_info: The AWSAssumeRoleInfo object
Returns:
- AWSCredentials: The AWS credentials for the assumed role
"""
try:
role_session_name = (
@@ -925,7 +1076,14 @@ class AwsProvider(Provider):
)
def get_aws_enabled_regions(self, current_session: Session) -> set:
"""get_aws_enabled_regions returns a set of enabled AWS regions"""
"""get_aws_enabled_regions returns a set of enabled AWS regions
Args:
- current_session: The AWS session object
Returns:
- set: set of strings representing the enabled AWS regions
"""
try:
# EC2 Client to check enabled regions
service = "ec2"
@@ -949,6 +1107,12 @@ class AwsProvider(Provider):
# TODO: review this function
# Maybe this should be done within the AwsProvider and not in __main__.py
def get_checks_to_execute_by_audit_resources(self) -> set[str]:
"""
get_checks_to_execute_by_audit_resources gets the checks to execute based on the audit resources
Returns:
- set: set of strings representing the checks to execute
"""
# Once the provider is set and we have the eventual checks from arn, it is time to exclude the others
try:
checks = set()
@@ -1370,6 +1534,19 @@ def read_aws_regions_file() -> dict:
# TODO: This can be moved to another class since it doesn't need self
def get_aws_region_for_sts(session_region: str, regions: set[str]) -> str:
"""
Get the AWS region for the STS Assume Role operation.
Args:
- session_region (str): The region configured in the AWS session.
- regions (set[str]): The regions passed with the -f/--region/--filter-region option.
Returns:
str: The AWS region for the STS Assume Role operation
Example:
aws_region = get_aws_region_for_sts(session_region, regions)
"""
# If there is no region passed with -f/--region/--filter-region
if regions is None or len(regions) == 0:
# If you have a region configured in your AWS config or credentials file