mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 20:42:02 +00:00
feat(exceptions): modify custom exceptions (#5451)
This commit is contained in:
@@ -1,31 +1,32 @@
|
||||
from prowler.exceptions.exceptions import ProwlerException
|
||||
|
||||
|
||||
# Exceptions codes from 5000 to 5999 are reserved for Scan exceptions
|
||||
class ScanBaseException(ProwlerException):
|
||||
"""Base class for Scan errors."""
|
||||
|
||||
SCAN_ERROR_CODES = {
|
||||
(2000, "ScanInvalidSeverityError"): {
|
||||
(5000, "ScanInvalidSeverityError"): {
|
||||
"message": "Invalid severity level provided.",
|
||||
"remediation": "Please provide a valid severity level. Valid severities are: critical, high, medium, low, informational.",
|
||||
},
|
||||
(2001, "ScanInvalidCheckError"): {
|
||||
(5001, "ScanInvalidCheckError"): {
|
||||
"message": "Invalid check provided.",
|
||||
"remediation": "Please provide a valid check name.",
|
||||
},
|
||||
(2002, "ScanInvalidServiceError"): {
|
||||
(5002, "ScanInvalidServiceError"): {
|
||||
"message": "Invalid service provided.",
|
||||
"remediation": "Please provide a valid service name.",
|
||||
},
|
||||
(2003, "ScanInvalidComplianceFrameworkError"): {
|
||||
(5003, "ScanInvalidComplianceFrameworkError"): {
|
||||
"message": "Invalid compliance framework provided.",
|
||||
"remediation": "Please provide a valid compliance framework name for the chosen provider.",
|
||||
},
|
||||
(2004, "ScanInvalidCategoryError"): {
|
||||
(5004, "ScanInvalidCategoryError"): {
|
||||
"message": "Invalid category provided.",
|
||||
"remediation": "Please provide a valid category name.",
|
||||
},
|
||||
(2005, "ScanInvalidStatusError"): {
|
||||
(5005, "ScanInvalidStatusError"): {
|
||||
"message": "Invalid status provided.",
|
||||
"remediation": "Please provide a valid status: FAIL, PASS, MANUAL.",
|
||||
},
|
||||
@@ -48,40 +49,40 @@ class ScanBaseException(ProwlerException):
|
||||
class ScanInvalidSeverityError(ScanBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2000, file=file, original_exception=original_exception, message=message
|
||||
5000, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class ScanInvalidCheckError(ScanBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2001, file=file, original_exception=original_exception, message=message
|
||||
5001, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class ScanInvalidServiceError(ScanBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2002, file=file, original_exception=original_exception, message=message
|
||||
5002, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class ScanInvalidComplianceFrameworkError(ScanBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2003, file=file, original_exception=original_exception, message=message
|
||||
5003, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class ScanInvalidCategoryError(ScanBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2004, file=file, original_exception=original_exception, message=message
|
||||
5004, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class ScanInvalidStatusError(ScanBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
2005, file=file, original_exception=original_exception, message=message
|
||||
5005, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
@@ -24,21 +24,21 @@ from prowler.providers.aws.config import (
|
||||
ROLE_SESSION_NAME,
|
||||
)
|
||||
from prowler.providers.aws.exceptions.exceptions import (
|
||||
AWSAccessKeyIDInvalid,
|
||||
AWSAccessKeyIDInvalidError,
|
||||
AWSArgumentTypeValidationError,
|
||||
AWSAssumeRoleError,
|
||||
AWSClientError,
|
||||
AWSIAMRoleARNEmptyResource,
|
||||
AWSIAMRoleARNInvalidAccountID,
|
||||
AWSIAMRoleARNInvalidResourceType,
|
||||
AWSIAMRoleARNPartitionEmpty,
|
||||
AWSIAMRoleARNRegionNotEmtpy,
|
||||
AWSIAMRoleARNServiceNotIAMnorSTS,
|
||||
AWSInvalidAccountCredentials,
|
||||
AWSIAMRoleARNEmptyResourceError,
|
||||
AWSIAMRoleARNInvalidAccountIDError,
|
||||
AWSIAMRoleARNInvalidResourceTypeError,
|
||||
AWSIAMRoleARNPartitionEmptyError,
|
||||
AWSIAMRoleARNRegionNotEmtpyError,
|
||||
AWSIAMRoleARNServiceNotIAMnorSTSError,
|
||||
AWSInvalidProviderIdError,
|
||||
AWSNoCredentialsError,
|
||||
AWSProfileNotFoundError,
|
||||
AWSSecretAccessKeyInvalid,
|
||||
AWSSessionTokenExpired,
|
||||
AWSSecretAccessKeyInvalidError,
|
||||
AWSSessionTokenExpiredError,
|
||||
AWSSetUpSessionError,
|
||||
)
|
||||
from prowler.providers.aws.lib.arn.arn import parse_iam_credentials_arn
|
||||
@@ -974,17 +974,17 @@ class AwsProvider(Provider):
|
||||
f"{client_error.__class__.__name__}[{client_error.__traceback__.tb_lineno}]: {client_error}"
|
||||
)
|
||||
if client_error.response["Error"]["Code"] == "InvalidClientTokenId":
|
||||
raise AWSAccessKeyIDInvalid(
|
||||
raise AWSAccessKeyIDInvalidError(
|
||||
original_exception=client_error,
|
||||
file=pathlib.Path(__file__).name,
|
||||
)
|
||||
elif client_error.response["Error"]["Code"] == "SignatureDoesNotMatch":
|
||||
raise AWSSecretAccessKeyInvalid(
|
||||
raise AWSSecretAccessKeyInvalidError(
|
||||
original_exception=client_error,
|
||||
file=pathlib.Path(__file__).name,
|
||||
)
|
||||
elif client_error.response["Error"]["Code"] == "ExpiredToken":
|
||||
raise AWSSessionTokenExpired(
|
||||
raise AWSSessionTokenExpiredError(
|
||||
original_exception=client_error,
|
||||
file=pathlib.Path(__file__).name,
|
||||
)
|
||||
@@ -1097,62 +1097,80 @@ class AwsProvider(Provider):
|
||||
caller_identity = AwsProvider.validate_credentials(session, aws_region)
|
||||
# Do an extra validation if the AWS account ID is provided
|
||||
if provider_id and caller_identity.account != provider_id:
|
||||
raise AWSInvalidAccountCredentials(file=pathlib.Path(__file__).name)
|
||||
raise AWSInvalidProviderIdError(file=pathlib.Path(__file__).name)
|
||||
|
||||
return Connection(
|
||||
is_connected=True,
|
||||
)
|
||||
|
||||
except AWSSetUpSessionError as setup_session_error:
|
||||
logger.error(str(setup_session_error))
|
||||
logger.error(
|
||||
f"{setup_session_error.__class__.__name__}[{setup_session_error.__traceback__.tb_lineno}]: {setup_session_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise setup_session_error
|
||||
return Connection(error=setup_session_error)
|
||||
|
||||
except AWSArgumentTypeValidationError as validation_error:
|
||||
logger.error(str(validation_error))
|
||||
logger.error(
|
||||
f"{validation_error.__class__.__name__}[{validation_error.__traceback__.tb_lineno}]: {validation_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise validation_error
|
||||
return Connection(error=validation_error)
|
||||
|
||||
except AWSIAMRoleARNRegionNotEmtpy as arn_region_not_empty_error:
|
||||
logger.error(str(arn_region_not_empty_error))
|
||||
except AWSIAMRoleARNRegionNotEmtpyError as arn_region_not_empty_error:
|
||||
logger.error(
|
||||
f"{arn_region_not_empty_error.__class__.__name__}[{arn_region_not_empty_error.__traceback__.tb_lineno}]: {arn_region_not_empty_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise arn_region_not_empty_error
|
||||
return Connection(error=arn_region_not_empty_error)
|
||||
|
||||
except AWSIAMRoleARNPartitionEmpty as arn_partition_empty_error:
|
||||
logger.error(str(arn_partition_empty_error))
|
||||
except AWSIAMRoleARNPartitionEmptyError as arn_partition_empty_error:
|
||||
logger.error(
|
||||
f"{arn_partition_empty_error.__class__.__name__}[{arn_partition_empty_error.__traceback__.tb_lineno}]: {arn_partition_empty_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise arn_partition_empty_error
|
||||
return Connection(error=arn_partition_empty_error)
|
||||
|
||||
except AWSIAMRoleARNServiceNotIAMnorSTS as arn_service_not_iam_sts_error:
|
||||
logger.error(str(arn_service_not_iam_sts_error))
|
||||
except AWSIAMRoleARNServiceNotIAMnorSTSError as arn_service_not_iam_sts_error:
|
||||
logger.error(
|
||||
f"{arn_service_not_iam_sts_error.__class__.__name__}[{arn_service_not_iam_sts_error.__traceback__.tb_lineno}]: {arn_service_not_iam_sts_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise arn_service_not_iam_sts_error
|
||||
return Connection(error=arn_service_not_iam_sts_error)
|
||||
|
||||
except AWSIAMRoleARNInvalidAccountID as arn_invalid_account_id_error:
|
||||
logger.error(str(arn_invalid_account_id_error))
|
||||
except AWSIAMRoleARNInvalidAccountIDError as arn_invalid_account_id_error:
|
||||
logger.error(
|
||||
f"{arn_invalid_account_id_error.__class__.__name__}[{arn_invalid_account_id_error.__traceback__.tb_lineno}]: {arn_invalid_account_id_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise arn_invalid_account_id_error
|
||||
return Connection(error=arn_invalid_account_id_error)
|
||||
|
||||
except AWSIAMRoleARNInvalidResourceType as arn_invalid_resource_type_error:
|
||||
logger.error(str(arn_invalid_resource_type_error))
|
||||
except AWSIAMRoleARNInvalidResourceTypeError as arn_invalid_resource_type_error:
|
||||
logger.error(
|
||||
f"{arn_invalid_resource_type_error.__class__.__name__}[{arn_invalid_resource_type_error.__traceback__.tb_lineno}]: {arn_invalid_resource_type_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise arn_invalid_resource_type_error
|
||||
return Connection(error=arn_invalid_resource_type_error)
|
||||
|
||||
except AWSIAMRoleARNEmptyResource as arn_empty_resource_error:
|
||||
logger.error(str(arn_empty_resource_error))
|
||||
except AWSIAMRoleARNEmptyResourceError as arn_empty_resource_error:
|
||||
logger.error(
|
||||
f"{arn_empty_resource_error.__class__.__name__}[{arn_empty_resource_error.__traceback__.tb_lineno}]: {arn_empty_resource_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise arn_empty_resource_error
|
||||
return Connection(error=arn_empty_resource_error)
|
||||
|
||||
except AWSAssumeRoleError as assume_role_error:
|
||||
logger.error(str(assume_role_error))
|
||||
logger.error(
|
||||
f"{assume_role_error.__class__.__name__}[{assume_role_error.__traceback__.tb_lineno}]: {assume_role_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise assume_role_error
|
||||
return Connection(error=assume_role_error)
|
||||
@@ -1189,26 +1207,34 @@ class AwsProvider(Provider):
|
||||
) from no_credentials_error
|
||||
return Connection(error=no_credentials_error)
|
||||
|
||||
except AWSAccessKeyIDInvalid as access_key_id_invalid_error:
|
||||
logger.error(str(access_key_id_invalid_error))
|
||||
except AWSAccessKeyIDInvalidError as access_key_id_invalid_error:
|
||||
logger.error(
|
||||
f"{access_key_id_invalid_error.__class__.__name__}[{access_key_id_invalid_error.__traceback__.tb_lineno}]: {access_key_id_invalid_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise access_key_id_invalid_error
|
||||
return Connection(error=access_key_id_invalid_error)
|
||||
|
||||
except AWSSecretAccessKeyInvalid as secret_access_key_invalid_error:
|
||||
logger.error(str(secret_access_key_invalid_error))
|
||||
except AWSSecretAccessKeyInvalidError as secret_access_key_invalid_error:
|
||||
logger.error(
|
||||
f"{secret_access_key_invalid_error.__class__.__name__}[{secret_access_key_invalid_error.__traceback__.tb_lineno}]: {secret_access_key_invalid_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise secret_access_key_invalid_error
|
||||
return Connection(error=secret_access_key_invalid_error)
|
||||
|
||||
except AWSInvalidAccountCredentials as invalid_account_credentials_error:
|
||||
logger.error(str(invalid_account_credentials_error))
|
||||
except AWSInvalidProviderIdError as invalid_account_credentials_error:
|
||||
logger.error(
|
||||
f"{invalid_account_credentials_error.__class__.__name__}[{invalid_account_credentials_error.__traceback__.tb_lineno}]: {invalid_account_credentials_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise invalid_account_credentials_error
|
||||
return Connection(error=invalid_account_credentials_error)
|
||||
|
||||
except AWSSessionTokenExpired as session_token_expired:
|
||||
logger.error(str(session_token_expired))
|
||||
except AWSSessionTokenExpiredError as session_token_expired:
|
||||
logger.error(
|
||||
f"{session_token_expired.__class__.__name__}[{session_token_expired.__traceback__.tb_lineno}]: {session_token_expired}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise session_token_expired
|
||||
return Connection(error=session_token_expired)
|
||||
|
||||
@@ -1,75 +1,76 @@
|
||||
from prowler.exceptions.exceptions import ProwlerException
|
||||
|
||||
|
||||
# Exceptions codes from 1000 to 1999 are reserved for AWS exceptions
|
||||
class AWSBaseException(ProwlerException):
|
||||
"""Base class for AWS errors."""
|
||||
|
||||
AWS_ERROR_CODES = {
|
||||
(1902, "AWSClientError"): {
|
||||
(1000, "AWSClientError"): {
|
||||
"message": "AWS ClientError occurred",
|
||||
"remediation": "Check your AWS client configuration and permissions.",
|
||||
},
|
||||
(1903, "AWSProfileNotFoundError"): {
|
||||
(1001, "AWSProfileNotFoundError"): {
|
||||
"message": "AWS Profile not found",
|
||||
"remediation": "Ensure the AWS profile is correctly configured, please visit https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-files.html",
|
||||
},
|
||||
(1904, "AWSNoCredentialsError"): {
|
||||
(1002, "AWSNoCredentialsError"): {
|
||||
"message": "No AWS credentials found",
|
||||
"remediation": "Verify that AWS credentials are properly set up, please visit https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/aws/authentication/ and https://docs.aws.amazon.com/cli/v1/userguide/cli-chap-configure.html",
|
||||
},
|
||||
(1905, "AWSArgumentTypeValidationError"): {
|
||||
(1003, "AWSArgumentTypeValidationError"): {
|
||||
"message": "AWS argument type validation error",
|
||||
"remediation": "Check the provided argument types specific to AWS and ensure they meet the required format. For session duration check: https://docs.aws.amazon.com/singlesignon/latest/userguide/howtosessionduration.html and for role session name check: https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-session-name",
|
||||
},
|
||||
(1906, "AWSSetUpSessionError"): {
|
||||
(1004, "AWSSetUpSessionError"): {
|
||||
"message": "AWS session setup error",
|
||||
"remediation": "Check the AWS session setup and ensure it is properly configured, please visit https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html and check if the provided profile has the necessary permissions.",
|
||||
},
|
||||
(1907, "AWSIAMRoleARNRegionNotEmtpy"): {
|
||||
(1005, "AWSIAMRoleARNRegionNotEmtpyError"): {
|
||||
"message": "AWS IAM Role ARN region is not empty",
|
||||
"remediation": "Check the AWS IAM Role ARN region and ensure it is empty, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
},
|
||||
(1908, "AWSIAMRoleARNPartitionEmpty"): {
|
||||
(1006, "AWSIAMRoleARNPartitionEmptyError"): {
|
||||
"message": "AWS IAM Role ARN partition is empty",
|
||||
"remediation": "Check the AWS IAM Role ARN partition and ensure it is not empty, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
},
|
||||
(1909, "AWSIAMRoleARNMissingFields"): {
|
||||
(1007, "AWSIAMRoleARNMissingFieldsError"): {
|
||||
"message": "AWS IAM Role ARN missing fields",
|
||||
"remediation": "Check the AWS IAM Role ARN and ensure all required fields are present, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
},
|
||||
(1910, "AWSIAMRoleARNServiceNotIAMnorSTS"): {
|
||||
(1008, "AWSIAMRoleARNServiceNotIAMnorSTSError"): {
|
||||
"message": "AWS IAM Role ARN service is not IAM nor STS",
|
||||
"remediation": "Check the AWS IAM Role ARN service and ensure it is either IAM or STS, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
},
|
||||
(1911, "AWSIAMRoleARNInvalidAccountID"): {
|
||||
(1009, "AWSIAMRoleARNInvalidAccountIDError"): {
|
||||
"message": "AWS IAM Role ARN account ID is invalid",
|
||||
"remediation": "Check the AWS IAM Role ARN account ID and ensure it is a valid 12-digit number, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
},
|
||||
(1912, "AWSIAMRoleARNInvalidResourceType"): {
|
||||
(1010, "AWSIAMRoleARNInvalidResourceTypeError"): {
|
||||
"message": "AWS IAM Role ARN resource type is invalid",
|
||||
"remediation": "Check the AWS IAM Role ARN resource type and ensure it is valid, resources types are: role, user, assumed-role, root, federated-user, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
},
|
||||
(1913, "AWSIAMRoleARNEmptyResource"): {
|
||||
(1011, "AWSIAMRoleARNEmptyResourceError"): {
|
||||
"message": "AWS IAM Role ARN resource is empty",
|
||||
"remediation": "Check the AWS IAM Role ARN resource and ensure it is not empty, visit https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_identifiers.html#identifiers-arns for more information.",
|
||||
},
|
||||
(1914, "AWSAssumeRoleError"): {
|
||||
(1012, "AWSAssumeRoleError"): {
|
||||
"message": "AWS assume role error",
|
||||
"remediation": "Check the AWS assume role configuration and ensure it is properly set up, please visit https://docs.prowler.com/projects/prowler-open-source/en/latest/tutorials/aws/role-assumption/ and https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_terms-and-concepts.html#iam-term-role-session-name",
|
||||
},
|
||||
(1915, "AWSAccessKeyIDInvalid"): {
|
||||
(1013, "AWSAccessKeyIDInvalidError"): {
|
||||
"message": "AWS Access Key ID or Session Token is invalid",
|
||||
"remediation": "Check your AWS Access Key ID or Session Token and ensure it is valid.",
|
||||
},
|
||||
(1916, "AWSSecretAccessKeyInvalid"): {
|
||||
(1014, "AWSSecretAccessKeyInvalidError"): {
|
||||
"message": "AWS Secret Access Key is invalid",
|
||||
"remediation": "Check your AWS Secret Access Key and signing method and ensure it is valid.",
|
||||
},
|
||||
(1917, "AWSInvalidAccountCredentials"): {
|
||||
(1015, "AWSInvalidProviderIdError"): {
|
||||
"message": "The provided AWS credentials belong to a different account",
|
||||
"remediation": "Check the provided AWS credentials and review if belong to the account you want to use.",
|
||||
},
|
||||
(1918, "AWSSessionTokenExpired"): {
|
||||
(1016, "AWSSessionTokenExpiredError"): {
|
||||
"message": "The provided AWS Session Token is expired",
|
||||
"remediation": "Get a new AWS Session Token and configure it for the provider.",
|
||||
},
|
||||
@@ -98,35 +99,35 @@ class AWSCredentialsError(AWSBaseException):
|
||||
class AWSClientError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1902, file=file, original_exception=original_exception, message=message
|
||||
1000, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSProfileNotFoundError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1903, file=file, original_exception=original_exception, message=message
|
||||
1001, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSNoCredentialsError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1904, file=file, original_exception=original_exception, message=message
|
||||
1002, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSArgumentTypeValidationError(AWSBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1905, file=file, original_exception=original_exception, message=message
|
||||
1003, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSSetUpSessionError(AWSBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1906, file=file, original_exception=original_exception, message=message
|
||||
1004, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
@@ -137,85 +138,85 @@ class AWSRoleArnError(AWSBaseException):
|
||||
super().__init__(code, file, original_exception, message)
|
||||
|
||||
|
||||
class AWSIAMRoleARNRegionNotEmtpy(AWSRoleArnError):
|
||||
class AWSIAMRoleARNRegionNotEmtpyError(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1907, file=file, original_exception=original_exception, message=message
|
||||
1005, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNPartitionEmpty(AWSRoleArnError):
|
||||
class AWSIAMRoleARNPartitionEmptyError(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1908, file=file, original_exception=original_exception, message=message
|
||||
1006, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNMissingFields(AWSRoleArnError):
|
||||
class AWSIAMRoleARNMissingFieldsError(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1909, file=file, original_exception=original_exception, message=message
|
||||
1007, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNServiceNotIAMnorSTS(AWSRoleArnError):
|
||||
class AWSIAMRoleARNServiceNotIAMnorSTSError(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1910, file=file, original_exception=original_exception, message=message
|
||||
1008, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNInvalidAccountID(AWSRoleArnError):
|
||||
class AWSIAMRoleARNInvalidAccountIDError(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1911, file=file, original_exception=original_exception, message=message
|
||||
1009, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNInvalidResourceType(AWSRoleArnError):
|
||||
class AWSIAMRoleARNInvalidResourceTypeError(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1912, file=file, original_exception=original_exception, message=message
|
||||
1010, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSIAMRoleARNEmptyResource(AWSRoleArnError):
|
||||
class AWSIAMRoleARNEmptyResourceError(AWSRoleArnError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1913, file=file, original_exception=original_exception, message=message
|
||||
1011, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSAssumeRoleError(AWSBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1914, file=file, original_exception=original_exception, message=message
|
||||
1012, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSAccessKeyIDInvalid(AWSCredentialsError):
|
||||
class AWSAccessKeyIDInvalidError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1915, file=file, original_exception=original_exception, message=message
|
||||
1013, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSSecretAccessKeyInvalid(AWSCredentialsError):
|
||||
class AWSSecretAccessKeyInvalidError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1916, file=file, original_exception=original_exception, message=message
|
||||
1014, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSInvalidAccountCredentials(AWSCredentialsError):
|
||||
class AWSInvalidProviderIdError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1917, file=file, original_exception=original_exception, message=message
|
||||
1015, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AWSSessionTokenExpired(AWSCredentialsError):
|
||||
class AWSSessionTokenExpiredError(AWSCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1918, file=file, original_exception=original_exception, message=message
|
||||
1016, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
@@ -3,12 +3,12 @@ import re
|
||||
from argparse import ArgumentTypeError
|
||||
|
||||
from prowler.providers.aws.exceptions.exceptions import (
|
||||
AWSIAMRoleARNEmptyResource,
|
||||
AWSIAMRoleARNInvalidAccountID,
|
||||
AWSIAMRoleARNInvalidResourceType,
|
||||
AWSIAMRoleARNPartitionEmpty,
|
||||
AWSIAMRoleARNRegionNotEmtpy,
|
||||
AWSIAMRoleARNServiceNotIAMnorSTS,
|
||||
AWSIAMRoleARNEmptyResourceError,
|
||||
AWSIAMRoleARNInvalidAccountIDError,
|
||||
AWSIAMRoleARNInvalidResourceTypeError,
|
||||
AWSIAMRoleARNPartitionEmptyError,
|
||||
AWSIAMRoleARNRegionNotEmtpyError,
|
||||
AWSIAMRoleARNServiceNotIAMnorSTSError,
|
||||
)
|
||||
from prowler.providers.aws.lib.arn.models import ARN
|
||||
|
||||
@@ -25,7 +25,7 @@ def parse_iam_credentials_arn(arn: str) -> ARN:
|
||||
arn_parsed = ARN(arn)
|
||||
# First check if region is empty (in IAM ARN's region is always empty)
|
||||
if arn_parsed.region:
|
||||
raise AWSIAMRoleARNRegionNotEmtpy(file=os.path.basename(__file__))
|
||||
raise AWSIAMRoleARNRegionNotEmtpyError(file=os.path.basename(__file__))
|
||||
else:
|
||||
# check if needed fields are filled:
|
||||
# - partition
|
||||
@@ -34,15 +34,15 @@ def parse_iam_credentials_arn(arn: str) -> ARN:
|
||||
# - resource_type
|
||||
# - resource
|
||||
if arn_parsed.partition is None or arn_parsed.partition == "":
|
||||
raise AWSIAMRoleARNPartitionEmpty(file=os.path.basename(__file__))
|
||||
raise AWSIAMRoleARNPartitionEmptyError(file=os.path.basename(__file__))
|
||||
elif arn_parsed.service != "iam" and arn_parsed.service != "sts":
|
||||
raise AWSIAMRoleARNServiceNotIAMnorSTS(file=os.path.basename(__file__))
|
||||
raise AWSIAMRoleARNServiceNotIAMnorSTSError(file=os.path.basename(__file__))
|
||||
elif (
|
||||
arn_parsed.account_id is None
|
||||
or len(arn_parsed.account_id) != 12
|
||||
or not arn_parsed.account_id.isnumeric()
|
||||
):
|
||||
raise AWSIAMRoleARNInvalidAccountID(file=os.path.basename(__file__))
|
||||
raise AWSIAMRoleARNInvalidAccountIDError(file=os.path.basename(__file__))
|
||||
elif (
|
||||
arn_parsed.resource_type != "role"
|
||||
and arn_parsed.resource_type != "user"
|
||||
@@ -50,9 +50,9 @@ def parse_iam_credentials_arn(arn: str) -> ARN:
|
||||
and arn_parsed.resource_type != "root"
|
||||
and arn_parsed.resource_type != "federated-user"
|
||||
):
|
||||
raise AWSIAMRoleARNInvalidResourceType(file=os.path.basename(__file__))
|
||||
raise AWSIAMRoleARNInvalidResourceTypeError(file=os.path.basename(__file__))
|
||||
elif arn_parsed.resource == "":
|
||||
raise AWSIAMRoleARNEmptyResource(file=os.path.basename(__file__))
|
||||
raise AWSIAMRoleARNEmptyResourceError(file=os.path.basename(__file__))
|
||||
else:
|
||||
return arn_parsed
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from prowler.providers.aws.exceptions.exceptions import AWSIAMRoleARNMissingFields
|
||||
from prowler.providers.aws.exceptions.exceptions import AWSIAMRoleARNMissingFieldsError
|
||||
|
||||
|
||||
class ARN(BaseModel):
|
||||
@@ -19,7 +19,7 @@ class ARN(BaseModel):
|
||||
# Validate the ARN
|
||||
## Check that arn starts with arn
|
||||
if not arn.startswith("arn:"):
|
||||
raise AWSIAMRoleARNMissingFields(file=os.path.basename(__file__))
|
||||
raise AWSIAMRoleARNMissingFieldsError(file=os.path.basename(__file__))
|
||||
## Retrieve fields
|
||||
arn_elements = arn.split(":", 5)
|
||||
data = {
|
||||
|
||||
@@ -32,10 +32,10 @@ from prowler.providers.azure.exceptions.exceptions import (
|
||||
AzureGetTokenIdentityError,
|
||||
AzureHTTPResponseError,
|
||||
AzureInteractiveBrowserCredentialError,
|
||||
AzureInvalidAccountCredentialsError,
|
||||
AzureInvalidProviderIdError,
|
||||
AzureNoAuthenticationMethodError,
|
||||
AzureNoSubscriptionsError,
|
||||
AzureNotTenantIdButClientIdAndClienSecret,
|
||||
AzureNotTenantIdButClientIdAndClienSecretError,
|
||||
AzureNotValidClientIdError,
|
||||
AzureNotValidClientSecretError,
|
||||
AzureNotValidTenantIdError,
|
||||
@@ -320,7 +320,7 @@ class AzureProvider(Provider):
|
||||
)
|
||||
else:
|
||||
if not tenant_id:
|
||||
raise AzureNotTenantIdButClientIdAndClienSecret(
|
||||
raise AzureNotTenantIdButClientIdAndClienSecretError(
|
||||
file=os.path.basename(__file__),
|
||||
message="Tenant Id is required for Azure static credentials. Make sure you are using the correct credentials.",
|
||||
)
|
||||
@@ -621,7 +621,7 @@ class AzureProvider(Provider):
|
||||
if provider_id and provider_id not in [
|
||||
sub.subscription_id for sub in available_subscriptions
|
||||
]:
|
||||
raise AzureInvalidAccountCredentialsError(
|
||||
raise AzureInvalidProviderIdError(
|
||||
file=os.path.basename(__file__),
|
||||
message="The provided credentials are not valid for the specified Azure subscription.",
|
||||
)
|
||||
@@ -631,88 +631,120 @@ class AzureProvider(Provider):
|
||||
return Connection(is_connected=True)
|
||||
# Exceptions from validate_arguments
|
||||
except AzureNoAuthenticationMethodError as no_auth_method_error:
|
||||
logger.error(str(no_auth_method_error))
|
||||
logger.error(
|
||||
f"{no_auth_method_error.__class__.__name__}[{no_auth_method_error.__traceback__.tb_lineno}]: {no_auth_method_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise no_auth_method_error
|
||||
return Connection(error=no_auth_method_error)
|
||||
except AzureBrowserAuthNoTenantIDError as browser_no_tenant_error:
|
||||
logger.error(str(browser_no_tenant_error))
|
||||
logger.error(
|
||||
f"{browser_no_tenant_error.__class__.__name__}[{browser_no_tenant_error.__traceback__.tb_lineno}]: {browser_no_tenant_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise browser_no_tenant_error
|
||||
return Connection(error=browser_no_tenant_error)
|
||||
except AzureTenantIDNoBrowserAuthError as tenant_no_browser_error:
|
||||
logger.error(str(tenant_no_browser_error))
|
||||
logger.error(
|
||||
f"{tenant_no_browser_error.__class__.__name__}[{tenant_no_browser_error.__traceback__.tb_lineno}]: {tenant_no_browser_error}"
|
||||
)
|
||||
# Exceptions from setup_region_config
|
||||
except AzureArgumentTypeValidationError as type_validation_error:
|
||||
logger.error(str(type_validation_error))
|
||||
logger.error(
|
||||
f"{type_validation_error.__class__.__name__}[{type_validation_error.__traceback__.tb_lineno}]: {type_validation_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise type_validation_error
|
||||
return Connection(error=type_validation_error)
|
||||
except AzureSetUpRegionConfigError as region_config_error:
|
||||
logger.error(str(region_config_error))
|
||||
logger.error(
|
||||
f"{region_config_error.__class__.__name__}[{region_config_error.__traceback__.tb_lineno}]: {region_config_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise region_config_error
|
||||
return Connection(error=region_config_error)
|
||||
# Exceptions from setup_session
|
||||
except AzureEnvironmentVariableError as environment_credentials_error:
|
||||
logger.error(str(environment_credentials_error))
|
||||
logger.error(
|
||||
f"{environment_credentials_error.__class__.__name__}[{environment_credentials_error.__traceback__.tb_lineno}]: {environment_credentials_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise environment_credentials_error
|
||||
return Connection(error=environment_credentials_error)
|
||||
except AzureDefaultAzureCredentialError as default_credentials_error:
|
||||
logger.error(str(default_credentials_error))
|
||||
logger.error(
|
||||
f"{default_credentials_error.__class__.__name__}[{default_credentials_error.__traceback__.tb_lineno}]: {default_credentials_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise default_credentials_error
|
||||
return Connection(error=default_credentials_error)
|
||||
except AzureInteractiveBrowserCredentialError as interactive_browser_error:
|
||||
logger.error(str(interactive_browser_error))
|
||||
logger.error(
|
||||
f"{interactive_browser_error.__class__.__name__}[{interactive_browser_error.__traceback__.tb_lineno}]: {interactive_browser_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise interactive_browser_error
|
||||
return Connection(error=interactive_browser_error)
|
||||
except AzureConfigCredentialsError as config_credentials_error:
|
||||
logger.error(str(config_credentials_error))
|
||||
logger.error(
|
||||
f"{config_credentials_error.__class__.__name__}[{config_credentials_error.__traceback__.tb_lineno}]: {config_credentials_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise config_credentials_error
|
||||
return Connection(error=config_credentials_error)
|
||||
except AzureClientAuthenticationError as client_auth_error:
|
||||
logger.error(str(client_auth_error))
|
||||
logger.error(
|
||||
f"{client_auth_error.__class__.__name__}[{client_auth_error.__traceback__.tb_lineno}]: {client_auth_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise client_auth_error
|
||||
return Connection(error=client_auth_error)
|
||||
except AzureCredentialsUnavailableError as credential_unavailable_error:
|
||||
logger.error(str(credential_unavailable_error))
|
||||
logger.error(
|
||||
f"{credential_unavailable_error.__class__.__name__}[{credential_unavailable_error.__traceback__.tb_lineno}]: {credential_unavailable_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise credential_unavailable_error
|
||||
return Connection(error=credential_unavailable_error)
|
||||
except AzureDefaultAzureCredentialError as default_credentials_error:
|
||||
logger.error(str(default_credentials_error))
|
||||
logger.error(
|
||||
f"{default_credentials_error.__class__.__name__}[{default_credentials_error.__traceback__.tb_lineno}]: {default_credentials_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise default_credentials_error
|
||||
return Connection(error=default_credentials_error)
|
||||
except (
|
||||
AzureClientIdAndClientSecretNotBelongingToTenantIdError
|
||||
) as tenant_id_error:
|
||||
logger.error(str(tenant_id_error))
|
||||
logger.error(
|
||||
f"{tenant_id_error.__class__.__name__}[{tenant_id_error.__traceback__.tb_lineno}]: {tenant_id_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise tenant_id_error
|
||||
return Connection(error=tenant_id_error)
|
||||
except (
|
||||
AzureTenantIdAndClientSecretNotBelongingToClientIdError
|
||||
) as client_id_error:
|
||||
logger.error(str(client_id_error))
|
||||
logger.error(
|
||||
f"{client_id_error.__class__.__name__}[{client_id_error.__traceback__.tb_lineno}]: {client_id_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise client_id_error
|
||||
return Connection(error=client_id_error)
|
||||
except (
|
||||
AzureTenantIdAndClientIdNotBelongingToClientSecretError
|
||||
) as client_secret_error:
|
||||
logger.error(str(client_secret_error))
|
||||
logger.error(
|
||||
f"{client_secret_error.__class__.__name__}[{client_secret_error.__traceback__.tb_lineno}]: {client_secret_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise client_secret_error
|
||||
return Connection(error=client_secret_error)
|
||||
# Exceptions from provider_id validation
|
||||
except AzureInvalidAccountCredentialsError as invalid_credentials_error:
|
||||
logger.error(str(invalid_credentials_error))
|
||||
except AzureInvalidProviderIdError as invalid_credentials_error:
|
||||
logger.error(
|
||||
f"{invalid_credentials_error.__class__.__name__}[{invalid_credentials_error.__traceback__.tb_lineno}]: {invalid_credentials_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise invalid_credentials_error
|
||||
return Connection(error=invalid_credentials_error)
|
||||
@@ -998,19 +1030,25 @@ class AzureProvider(Provider):
|
||||
"client_secret": client_secret,
|
||||
}
|
||||
except AzureNotValidTenantIdError as tenant_id_error:
|
||||
logger.error(str(tenant_id_error))
|
||||
logger.error(
|
||||
f"{tenant_id_error.__class__.__name__}[{tenant_id_error.__traceback__.tb_lineno}]: {tenant_id_error}"
|
||||
)
|
||||
raise AzureClientIdAndClientSecretNotBelongingToTenantIdError(
|
||||
file=os.path.basename(__file__),
|
||||
message="The provided Azure Client ID and Client Secret do not belong to the specified Tenant ID.",
|
||||
)
|
||||
except AzureNotValidClientIdError as client_id_error:
|
||||
logger.error(str(client_id_error))
|
||||
logger.error(
|
||||
f"{client_id_error.__class__.__name__}[{client_id_error.__traceback__.tb_lineno}]: {client_id_error}"
|
||||
)
|
||||
raise AzureTenantIdAndClientSecretNotBelongingToClientIdError(
|
||||
file=os.path.basename(__file__),
|
||||
message="The provided Azure Tenant ID and Client Secret do not belong to the specified Client ID.",
|
||||
)
|
||||
except AzureNotValidClientSecretError as client_secret_error:
|
||||
logger.error(str(client_secret_error))
|
||||
logger.error(
|
||||
f"{client_secret_error.__class__.__name__}[{client_secret_error.__traceback__.tb_lineno}]: {client_secret_error}"
|
||||
)
|
||||
raise AzureTenantIdAndClientIdNotBelongingToClientSecretError(
|
||||
file=os.path.basename(__file__),
|
||||
message="The provided Azure Tenant ID and Client ID do not belong to the specified Client Secret.",
|
||||
|
||||
@@ -1,103 +1,104 @@
|
||||
from prowler.exceptions.exceptions import ProwlerException
|
||||
|
||||
|
||||
# Exceptions codes from 2000 to 2999 are reserved for Azure exceptions
|
||||
class AzureBaseException(ProwlerException):
|
||||
"""Base class for Azure Errors."""
|
||||
|
||||
AZURE_ERROR_CODES = {
|
||||
(1914, "AzureEnvironmentVariableError"): {
|
||||
(2000, "AzureEnvironmentVariableError"): {
|
||||
"message": "Azure environment variable error",
|
||||
"remediation": "Check the Azure environment variables and ensure they are properly set.",
|
||||
},
|
||||
(1915, "AzureNoSubscriptionsError"): {
|
||||
(2001, "AzureNoSubscriptionsError"): {
|
||||
"message": "No Azure subscriptions found",
|
||||
"remediation": "Check the Azure subscriptions and ensure they are properly set up.",
|
||||
},
|
||||
(1916, "AzureSetUpIdentityError"): {
|
||||
(2002, "AzureSetUpIdentityError"): {
|
||||
"message": "Azure identity setup error related with credentials",
|
||||
"remediation": "Check credentials and ensure they are properly set up for Azure and the identity provider.",
|
||||
},
|
||||
(1917, "AzureNoAuthenticationMethodError"): {
|
||||
(2003, "AzureNoAuthenticationMethodError"): {
|
||||
"message": "No Azure authentication method found",
|
||||
"remediation": "Check that any authentication method is properly set up for Azure.",
|
||||
},
|
||||
(1918, "AzureBrowserAuthNoTenantIDError"): {
|
||||
(2004, "AzureBrowserAuthNoTenantIDError"): {
|
||||
"message": "Azure browser authentication error: no tenant ID found",
|
||||
"remediation": "To use browser authentication, ensure the tenant ID is properly set.",
|
||||
},
|
||||
(1919, "AzureTenantIDNoBrowserAuthError"): {
|
||||
(2005, "AzureTenantIDNoBrowserAuthError"): {
|
||||
"message": "Azure tenant ID error: browser authentication not found",
|
||||
"remediation": "To use browser authentication, both the tenant ID and browser authentication must be properly set.",
|
||||
},
|
||||
(1920, "AzureArgumentTypeValidationError"): {
|
||||
(2006, "AzureArgumentTypeValidationError"): {
|
||||
"message": "Azure argument type validation error",
|
||||
"remediation": "Check the provided argument types specific to Azure and ensure they meet the required format.",
|
||||
},
|
||||
(1921, "AzureSetUpRegionConfigError"): {
|
||||
(2007, "AzureSetUpRegionConfigError"): {
|
||||
"message": "Azure region configuration setup error",
|
||||
"remediation": "Check the Azure region configuration and ensure it is properly set up.",
|
||||
},
|
||||
(1922, "AzureDefaultAzureCredentialError"): {
|
||||
(2008, "AzureDefaultAzureCredentialError"): {
|
||||
"message": "Error in DefaultAzureCredential",
|
||||
"remediation": "Check that all the attributes are properly set up for the DefaultAzureCredential.",
|
||||
},
|
||||
(1923, "AzureInteractiveBrowserCredentialError"): {
|
||||
(2009, "AzureInteractiveBrowserCredentialError"): {
|
||||
"message": "Error retrieving InteractiveBrowserCredential",
|
||||
"remediation": "Check your browser and ensure that the tenant ID and browser authentication are properly set.",
|
||||
},
|
||||
(1924, "AzureHTTPResponseError"): {
|
||||
(2010, "AzureHTTPResponseError"): {
|
||||
"message": "Error in HTTP response from Azure",
|
||||
"remediation": "",
|
||||
},
|
||||
(1925, "AzureCredentialsUnavailableError"): {
|
||||
(2011, "AzureCredentialsUnavailableError"): {
|
||||
"message": "Error trying to configure Azure credentials because they are unavailable",
|
||||
"remediation": "Check the dictionary and ensure it is properly set up for Azure credentials. TENANT_ID, CLIENT_ID and CLIENT_SECRET are required.",
|
||||
},
|
||||
(1926, "AzureGetTokenIdentityError"): {
|
||||
(2012, "AzureGetTokenIdentityError"): {
|
||||
"message": "Error trying to get token from Azure Identity",
|
||||
"remediation": "Check the Azure Identity and ensure it is properly set up.",
|
||||
},
|
||||
(1927, "AzureNotTenantIdButClientIdAndClienSecret"): {
|
||||
(2013, "AzureNotTenantIdButClientIdAndClienSecretError"): {
|
||||
"message": "The provided credentials are not a tenant ID but a client ID and client secret",
|
||||
"remediation": "Tenant Id, Client Id and Client Secret are required for Azure credentials. Make sure you are using the correct credentials.",
|
||||
},
|
||||
(1928, "AzureClientAuthenticationError"): {
|
||||
(2014, "AzureClientAuthenticationError"): {
|
||||
"message": "Error in client authentication",
|
||||
"remediation": "Check the client authentication and ensure it is properly set up.",
|
||||
},
|
||||
(1929, "AzureSetUpSessionError"): {
|
||||
(2015, "AzureSetUpSessionError"): {
|
||||
"message": "Error setting up session",
|
||||
"remediation": "Check the session setup and ensure it is properly set up.",
|
||||
},
|
||||
(1930, "AzureNotValidTenantIdError"): {
|
||||
(2016, "AzureNotValidTenantIdError"): {
|
||||
"message": "The provided tenant ID is not valid",
|
||||
"remediation": "Check the tenant ID and ensure it is a valid ID.",
|
||||
},
|
||||
(1931, "AzureNotValidClientIdError"): {
|
||||
(2017, "AzureNotValidClientIdError"): {
|
||||
"message": "The provided client ID is not valid",
|
||||
"remediation": "Check the client ID and ensure it is a valid ID.",
|
||||
},
|
||||
(1932, "AzureNotValidClientSecretError"): {
|
||||
(2018, "AzureNotValidClientSecretError"): {
|
||||
"message": "The provided client secret is not valid",
|
||||
"remediation": "Check the client secret and ensure it is a valid secret.",
|
||||
},
|
||||
(1933, "AzureConfigCredentialsError"): {
|
||||
(2019, "AzureConfigCredentialsError"): {
|
||||
"message": "Error in configuration of Azure credentials",
|
||||
"remediation": "Check the configuration of Azure credentials and ensure it is properly set up.",
|
||||
},
|
||||
(1934, "AzureClientIdAndClientSecretNotBelongingToTenantIdError"): {
|
||||
(2020, "AzureClientIdAndClientSecretNotBelongingToTenantIdError"): {
|
||||
"message": "The provided client ID and client secret do not belong to the provided tenant ID",
|
||||
"remediation": "Check the client ID and client secret and ensure they belong to the provided tenant ID.",
|
||||
},
|
||||
(1935, "AzureTenantIdAndClientSecretNotBelongingToClientIdError"): {
|
||||
(2021, "AzureTenantIdAndClientSecretNotBelongingToClientIdError"): {
|
||||
"message": "The provided tenant ID and client secret do not belong to the provided client ID",
|
||||
"remediation": "Check the tenant ID and client secret and ensure they belong to the provided client ID.",
|
||||
},
|
||||
(1936, "AzureTenantIdAndClientIdNotBelongingToClientSecretError"): {
|
||||
(2022, "AzureTenantIdAndClientIdNotBelongingToClientSecretError"): {
|
||||
"message": "The provided tenant ID and client ID do not belong to the provided client secret",
|
||||
"remediation": "Check the tenant ID and client ID and ensure they belong to the provided client secret.",
|
||||
},
|
||||
(1937, "AzureInvalidAccountCredentialsError"): {
|
||||
(2023, "AzureInvalidProviderIdError"): {
|
||||
"message": "The provided provider_id does not match with the available subscriptions",
|
||||
"remediation": "Check the provider_id and ensure it is a valid subscription for the given credentials.",
|
||||
},
|
||||
@@ -127,166 +128,166 @@ class AzureCredentialsError(AzureBaseException):
|
||||
class AzureEnvironmentVariableError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1914, file=file, original_exception=original_exception, message=message
|
||||
2000, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureNoSubscriptionsError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1915, file=file, original_exception=original_exception, message=message
|
||||
2001, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureSetUpIdentityError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1916, file=file, original_exception=original_exception, message=message
|
||||
2002, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureNoAuthenticationMethodError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1917, file=file, original_exception=original_exception, message=message
|
||||
2003, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureBrowserAuthNoTenantIDError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1918, file=file, original_exception=original_exception, message=message
|
||||
2004, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureTenantIDNoBrowserAuthError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1919, file=file, original_exception=original_exception, message=message
|
||||
2005, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureArgumentTypeValidationError(AzureBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1920, file=file, original_exception=original_exception, message=message
|
||||
2006, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureSetUpRegionConfigError(AzureBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1921, file=file, original_exception=original_exception, message=message
|
||||
2007, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureDefaultAzureCredentialError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1922, file=file, original_exception=original_exception, message=message
|
||||
2008, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureInteractiveBrowserCredentialError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1923, file=file, original_exception=original_exception, message=message
|
||||
2009, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureHTTPResponseError(AzureBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1924, file=file, original_exception=original_exception, message=message
|
||||
2010, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureCredentialsUnavailableError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1925, file=file, original_exception=original_exception, message=message
|
||||
2011, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureGetTokenIdentityError(AzureBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1926, file=file, original_exception=original_exception, message=message
|
||||
2012, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureNotTenantIdButClientIdAndClienSecret(AzureCredentialsError):
|
||||
class AzureNotTenantIdButClientIdAndClienSecretError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1927, file=file, original_exception=original_exception, message=message
|
||||
2013, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureClientAuthenticationError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1928, file=file, original_exception=original_exception, message=message
|
||||
2014, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureSetUpSessionError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1929, file=file, original_exception=original_exception, message=message
|
||||
2015, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureNotValidTenantIdError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1930, file=file, original_exception=original_exception, message=message
|
||||
2016, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureNotValidClientIdError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1931, file=file, original_exception=original_exception, message=message
|
||||
2017, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureNotValidClientSecretError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1932, file=file, original_exception=original_exception, message=message
|
||||
2018, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureConfigCredentialsError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1933, file=file, original_exception=original_exception, message=message
|
||||
2019, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureClientIdAndClientSecretNotBelongingToTenantIdError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1934, file=file, original_exception=original_exception, message=message
|
||||
2020, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureTenantIdAndClientSecretNotBelongingToClientIdError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1935, file=file, original_exception=original_exception, message=message
|
||||
2021, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureTenantIdAndClientIdNotBelongingToClientSecretError(AzureCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1936, file=file, original_exception=original_exception, message=message
|
||||
2022, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class AzureInvalidAccountCredentialsError(AzureBaseException):
|
||||
class AzureInvalidProviderIdError(AzureBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1937, file=file, original_exception=original_exception, message=message
|
||||
2023, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
@@ -1,43 +1,44 @@
|
||||
from prowler.exceptions.exceptions import ProwlerException
|
||||
|
||||
|
||||
# Exceptions codes from 3000 to 3999 are reserved for GCP exceptions
|
||||
class GCPBaseException(ProwlerException):
|
||||
"""Base class for GCP Errors."""
|
||||
|
||||
GCP_ERROR_CODES = {
|
||||
(1925, "GCPCloudResourceManagerAPINotUsedError"): {
|
||||
(3000, "GCPCloudResourceManagerAPINotUsedError"): {
|
||||
"message": "Cloud Resource Manager API not used",
|
||||
"remediation": "Enable the Cloud Resource Manager API for the project.",
|
||||
},
|
||||
(1926, "GCPHTTPError"): {
|
||||
(3001, "GCPHTTPError"): {
|
||||
"message": "HTTP error",
|
||||
"remediation": "Check the HTTP error and ensure the request is properly formatted.",
|
||||
},
|
||||
(1927, "GCPNoAccesibleProjectsError"): {
|
||||
(3002, "GCPNoAccesibleProjectsError"): {
|
||||
"message": "No Project IDs can be accessed via Google Credentials",
|
||||
"remediation": "Ensure the project is accessible and properly set up.",
|
||||
},
|
||||
(1928, "GCPSetUpSessionError"): {
|
||||
(3003, "GCPSetUpSessionError"): {
|
||||
"message": "Error setting up session",
|
||||
"remediation": "Check the session setup and ensure it is properly set up.",
|
||||
},
|
||||
(1929, "GCPGetProjectError"): {
|
||||
(3004, "GCPGetProjectError"): {
|
||||
"message": "Error getting project",
|
||||
"remediation": "Check the project and ensure it is properly set up.",
|
||||
},
|
||||
(1930, "GCPTestConnectionError"): {
|
||||
(3005, "GCPTestConnectionError"): {
|
||||
"message": "Error testing connection to GCP",
|
||||
"remediation": "Check the connection and ensure it is properly set up.",
|
||||
},
|
||||
(1931, "GCPLoadCredentialsFromDictError"): {
|
||||
(3006, "GCPLoadCredentialsFromDictError"): {
|
||||
"message": "Error loading credentials from dictionary",
|
||||
"remediation": "Check the credentials and ensure they are properly set up. client_id, client_secret and refresh_token are required.",
|
||||
},
|
||||
(1932, "GCPStaticCredentialsError"): {
|
||||
(3007, "GCPStaticCredentialsError"): {
|
||||
"message": "Error loading static credentials",
|
||||
"remediation": "Check the credentials and ensure they are properly set up. client_id, client_secret and refresh_token are required.",
|
||||
},
|
||||
(1933, "GCPInvalidAccountCredentials"): {
|
||||
(3008, "GCPInvalidProviderIdError"): {
|
||||
"message": "Provider does not match with the expected project_id",
|
||||
"remediation": "Check the provider and ensure it matches the expected project_id.",
|
||||
},
|
||||
@@ -67,61 +68,61 @@ class GCPCredentialsError(GCPBaseException):
|
||||
class GCPCloudResourceManagerAPINotUsedError(GCPBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1925, file=file, original_exception=original_exception, message=message
|
||||
3000, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GCPHTTPError(GCPBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1926, file=file, original_exception=original_exception, message=message
|
||||
3001, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GCPNoAccesibleProjectsError(GCPCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1927, file=file, original_exception=original_exception, message=message
|
||||
3002, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GCPSetUpSessionError(GCPCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1928, file=file, original_exception=original_exception, message=message
|
||||
3003, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GCPGetProjectError(GCPCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1929, file=file, original_exception=original_exception, message=message
|
||||
3004, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GCPTestConnectionError(GCPBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1930, file=file, original_exception=original_exception, message=message
|
||||
3005, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GCPLoadCredentialsFromDictError(GCPCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1931, file=file, original_exception=original_exception, message=message
|
||||
3006, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GCPStaticCredentialsError(GCPCredentialsError):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1932, file=file, original_exception=original_exception, message=message
|
||||
3007, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
|
||||
class GCPInvalidAccountCredentials(GCPBaseException):
|
||||
class GCPInvalidProviderIdError(GCPBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(
|
||||
1933, file=file, original_exception=original_exception, message=message
|
||||
3008, file=file, original_exception=original_exception, message=message
|
||||
)
|
||||
|
||||
@@ -19,7 +19,7 @@ from prowler.providers.gcp.exceptions.exceptions import (
|
||||
GCPCloudResourceManagerAPINotUsedError,
|
||||
GCPGetProjectError,
|
||||
GCPHTTPError,
|
||||
GCPInvalidAccountCredentials,
|
||||
GCPInvalidProviderIdError,
|
||||
GCPLoadCredentialsFromDictError,
|
||||
GCPNoAccesibleProjectsError,
|
||||
GCPSetUpSessionError,
|
||||
@@ -340,12 +340,16 @@ class GcpProvider(Provider):
|
||||
|
||||
# Errors from setup_session
|
||||
except GCPLoadCredentialsFromDictError as load_credentials_error:
|
||||
logger.critical(str(load_credentials_error))
|
||||
logger.critical(
|
||||
f"{load_credentials_error.__class__.__name__}[{load_credentials_error.__traceback__.tb_lineno}]: {load_credentials_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise load_credentials_error
|
||||
return Connection(error=load_credentials_error)
|
||||
except GCPSetUpSessionError as setup_session_error:
|
||||
logger.critical(str(setup_session_error))
|
||||
logger.critical(
|
||||
f"{setup_session_error.__class__.__name__}[{setup_session_error.__traceback__.tb_lineno}]: {setup_session_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise setup_session_error
|
||||
return Connection(error=setup_session_error)
|
||||
@@ -366,8 +370,10 @@ class GcpProvider(Provider):
|
||||
raise http_error
|
||||
return Connection(error=http_error)
|
||||
# Exceptions from validating Provider ID
|
||||
except GCPInvalidAccountCredentials as not_valid_provider_id_error:
|
||||
logger.critical(str(not_valid_provider_id_error))
|
||||
except GCPInvalidProviderIdError as not_valid_provider_id_error:
|
||||
logger.critical(
|
||||
f"{not_valid_provider_id_error.__class__.__name__}[{not_valid_provider_id_error.__traceback__.tb_lineno}]: {not_valid_provider_id_error}"
|
||||
)
|
||||
if raise_on_exception:
|
||||
raise not_valid_provider_id_error
|
||||
return Connection(error=not_valid_provider_id_error)
|
||||
@@ -563,7 +569,7 @@ class GcpProvider(Provider):
|
||||
None
|
||||
|
||||
Raises:
|
||||
GCPInvalidAccountCredentials if the provider ID does not match with the expected project_id
|
||||
GCPInvalidProviderIdError if the provider ID does not match with the expected project_id
|
||||
"""
|
||||
|
||||
available_projects = list(
|
||||
@@ -576,7 +582,7 @@ class GcpProvider(Provider):
|
||||
message="No Project IDs can be accessed via Google Credentials.",
|
||||
)
|
||||
elif provider_id not in available_projects:
|
||||
raise GCPInvalidAccountCredentials(
|
||||
raise GCPInvalidProviderIdError(
|
||||
file=__file__,
|
||||
message="The provider ID does not match with the expected project_id.",
|
||||
)
|
||||
|
||||
@@ -1,35 +1,36 @@
|
||||
from prowler.exceptions.exceptions import ProwlerException
|
||||
|
||||
|
||||
# Exceptions codes from 4000 to 4999 are reserved for Kubernetes exceptions
|
||||
class KubernetesBaseException(ProwlerException):
|
||||
"""Base class for Kubernetes errors."""
|
||||
|
||||
KUBERNETES_ERROR_CODES = {
|
||||
(1931, "KubernetesCloudResourceManagerAPINotUsedError"): {
|
||||
(4000, "KubernetesCloudResourceManagerAPINotUsedError"): {
|
||||
"message": "Cloud Resource Manager API is not enabled, blocking access to necessary resources.",
|
||||
"remediation": "Refer to the Kubernetes documentation to enable the Cloud Resource Manager API: https://kubernetes.io/docs/reference/access-authn-authz/rbac/",
|
||||
},
|
||||
(1932, "KubernetesSetUpSessionError"): {
|
||||
(4001, "KubernetesSetUpSessionError"): {
|
||||
"message": "Failed to establish a Kubernetes session, preventing further actions.",
|
||||
"remediation": "Verify your session setup, including credentials and Kubernetes cluster configuration. Refer to this guide for proper setup: https://kubernetes.io/docs/tasks/access-application-cluster/configure-access-multiple-clusters/",
|
||||
},
|
||||
(1933, "KubernetesAPIError"): {
|
||||
(4002, "KubernetesAPIError"): {
|
||||
"message": "An error occurred while interacting with the Kubernetes API.",
|
||||
"remediation": "Check the API request and ensure it is properly formatted. Refer to the Kubernetes API documentation for guidance: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/",
|
||||
},
|
||||
(1934, "KubernetesTimeoutError"): {
|
||||
(4003, "KubernetesTimeoutError"): {
|
||||
"message": "The request to the Kubernetes API timed out.",
|
||||
"remediation": "Check the network connection and the Kubernetes API server status. For information on troubleshooting timeouts, refer to the Kubernetes documentation: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#-strong-timeout-strong-",
|
||||
},
|
||||
(1935, "KubernetesError"): {
|
||||
(4004, "KubernetesError"): {
|
||||
"message": "An error occurred in the Kubernetes provider.",
|
||||
"remediation": "Check the provider code and configuration to identify the issue. For more information on troubleshooting Kubernetes providers, refer to the Kubernetes documentation: https://kubernetes.io/docs/reference/",
|
||||
},
|
||||
(1936, "KubernetesInvalidProviderIdError"): {
|
||||
(4005, "KubernetesInvalidProviderIdError"): {
|
||||
"message": "The provider ID is invalid.",
|
||||
"remediation": "Check the provider ID and ensure it is correctly formatted. Refer to the Kubernetes documentation for guidance on provider IDs: https://kubernetes.io/docs/reference/access-authn-authz/rbac/",
|
||||
},
|
||||
(1937, "KubernetesInvalidKubeConfigFileError"): {
|
||||
(4006, "KubernetesInvalidKubeConfigFileError"): {
|
||||
"message": "The provided kube-config is invalid.",
|
||||
"remediation": "Review the kube-config and the attached error to get more details. Please, refer to the Kubernetes config documentation: https://kubernetes.io/docs/reference/config-api/kubeconfig.v1/#Config",
|
||||
},
|
||||
@@ -57,34 +58,34 @@ class KubernetesBaseException(ProwlerException):
|
||||
|
||||
class KubernetesError(KubernetesBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(1935, file, original_exception, message)
|
||||
super().__init__(4004, file, original_exception, message)
|
||||
|
||||
|
||||
class KubernetesCloudResourceManagerAPINotUsedError(KubernetesBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(1931, file, original_exception, message)
|
||||
super().__init__(4000, file, original_exception, message)
|
||||
|
||||
|
||||
class KubernetesSetUpSessionError(KubernetesBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(1932, file, original_exception, message)
|
||||
super().__init__(4001, file, original_exception, message)
|
||||
|
||||
|
||||
class KubernetesAPIError(KubernetesBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(1933, file, original_exception, message)
|
||||
super().__init__(4002, file, original_exception, message)
|
||||
|
||||
|
||||
class KubernetesTimeoutError(KubernetesBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(1934, file, original_exception, message)
|
||||
super().__init__(4003, file, original_exception, message)
|
||||
|
||||
|
||||
class KubernetesInvalidProviderIdError(KubernetesBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(1936, file, original_exception, message)
|
||||
super().__init__(4005, file, original_exception, message)
|
||||
|
||||
|
||||
class KubernetesInvalidKubeConfigFileError(KubernetesBaseException):
|
||||
def __init__(self, file=None, original_exception=None, message=None):
|
||||
super().__init__(1937, file, original_exception, message)
|
||||
super().__init__(4006, file, original_exception, message)
|
||||
|
||||
@@ -28,8 +28,8 @@ from prowler.providers.aws.config import (
|
||||
)
|
||||
from prowler.providers.aws.exceptions.exceptions import (
|
||||
AWSArgumentTypeValidationError,
|
||||
AWSIAMRoleARNInvalidResourceType,
|
||||
AWSInvalidAccountCredentials,
|
||||
AWSIAMRoleARNInvalidResourceTypeError,
|
||||
AWSInvalidProviderIdError,
|
||||
AWSNoCredentialsError,
|
||||
)
|
||||
from prowler.providers.aws.lib.arn.models import ARN
|
||||
@@ -1265,7 +1265,7 @@ aws:
|
||||
) # No profile to avoid ProfileNotFound error
|
||||
|
||||
assert exception.type == AWSNoCredentialsError
|
||||
assert "AWSNoCredentialsError[1904]: No AWS credentials found" in str(
|
||||
assert "AWSNoCredentialsError[1002]: No AWS credentials found" in str(
|
||||
exception.value
|
||||
)
|
||||
|
||||
@@ -1307,7 +1307,7 @@ aws:
|
||||
assert exception.type == AWSArgumentTypeValidationError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1905] Session Duration must be between 900 and 43200 seconds."
|
||||
== "[1003] Session Duration must be between 900 and 43200 seconds."
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
@@ -1327,7 +1327,7 @@ aws:
|
||||
assert isinstance(connection.error, AWSArgumentTypeValidationError)
|
||||
assert (
|
||||
connection.error.args[0]
|
||||
== "[1905] Session Duration must be between 900 and 43200 seconds."
|
||||
== "[1003] Session Duration must be between 900 and 43200 seconds."
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
@@ -1343,7 +1343,7 @@ aws:
|
||||
assert exception.type == AWSArgumentTypeValidationError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1905] Role Session Name must be between 2 and 64 characters and may contain alphanumeric characters, periods, hyphens, and underscores."
|
||||
== "[1003] Role Session Name must be between 2 and 64 characters and may contain alphanumeric characters, periods, hyphens, and underscores."
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
@@ -1351,13 +1351,13 @@ aws:
|
||||
role_name = "test-role"
|
||||
role_arn = f"arn:{AWS_COMMERCIAL_PARTITION}:iam::{AWS_ACCOUNT_NUMBER}:not-role/{role_name}"
|
||||
|
||||
with raises(AWSIAMRoleARNInvalidResourceType) as exception:
|
||||
with raises(AWSIAMRoleARNInvalidResourceTypeError) as exception:
|
||||
AwsProvider.test_connection(role_arn=role_arn)
|
||||
|
||||
assert exception.type == AWSIAMRoleARNInvalidResourceType
|
||||
assert exception.type == AWSIAMRoleARNInvalidResourceTypeError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1912] AWS IAM Role ARN resource type is invalid"
|
||||
== "[1010] AWS IAM Role ARN resource type is invalid"
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
@@ -1429,13 +1429,13 @@ aws:
|
||||
"provider_id": "111122223333",
|
||||
}
|
||||
|
||||
with raises(AWSInvalidAccountCredentials) as exception:
|
||||
with raises(AWSInvalidProviderIdError) as exception:
|
||||
AwsProvider.test_connection(**session_credentials)
|
||||
|
||||
assert exception.type == AWSInvalidAccountCredentials
|
||||
assert exception.type == AWSInvalidProviderIdError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1917] The provided AWS credentials belong to a different account"
|
||||
== "[1015] The provided AWS credentials belong to a different account"
|
||||
)
|
||||
|
||||
@mock_aws
|
||||
@@ -1456,12 +1456,12 @@ aws:
|
||||
|
||||
assert isinstance(connection, Connection)
|
||||
assert not connection.is_connected
|
||||
assert isinstance(connection.error, AWSInvalidAccountCredentials)
|
||||
assert isinstance(connection.error, AWSInvalidProviderIdError)
|
||||
assert (
|
||||
connection.error.message
|
||||
== "The provided AWS credentials belong to a different account"
|
||||
)
|
||||
assert connection.error.code == 1917
|
||||
assert connection.error.code == 1015
|
||||
|
||||
@mock_aws
|
||||
def test_create_sts_session(self):
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
from pytest import raises
|
||||
|
||||
from prowler.providers.aws.exceptions.exceptions import (
|
||||
AWSIAMRoleARNEmptyResource,
|
||||
AWSIAMRoleARNInvalidAccountID,
|
||||
AWSIAMRoleARNInvalidResourceType,
|
||||
AWSIAMRoleARNMissingFields,
|
||||
AWSIAMRoleARNPartitionEmpty,
|
||||
AWSIAMRoleARNRegionNotEmtpy,
|
||||
AWSIAMRoleARNServiceNotIAMnorSTS,
|
||||
AWSIAMRoleARNEmptyResourceError,
|
||||
AWSIAMRoleARNInvalidAccountIDError,
|
||||
AWSIAMRoleARNInvalidResourceTypeError,
|
||||
AWSIAMRoleARNMissingFieldsError,
|
||||
AWSIAMRoleARNPartitionEmptyError,
|
||||
AWSIAMRoleARNRegionNotEmtpyError,
|
||||
AWSIAMRoleARNServiceNotIAMnorSTSError,
|
||||
)
|
||||
from prowler.providers.aws.lib.arn.arn import is_valid_arn, parse_iam_credentials_arn
|
||||
from prowler.providers.aws.lib.arn.models import ARN
|
||||
@@ -327,54 +327,54 @@ class Test_ARN_Parsing:
|
||||
self,
|
||||
):
|
||||
input_arn = ""
|
||||
with raises(AWSIAMRoleARNMissingFields) as error:
|
||||
with raises(AWSIAMRoleARNMissingFieldsError) as error:
|
||||
parse_iam_credentials_arn(input_arn)
|
||||
|
||||
assert error._excinfo[0] == AWSIAMRoleARNMissingFields
|
||||
assert error._excinfo[0] == AWSIAMRoleARNMissingFieldsError
|
||||
|
||||
def test_iam_credentials_arn_parsing_raising_AWSIAMRoleARNRegionNotEmtpy(self):
|
||||
input_arn = "arn:aws:iam:eu-west-1:111111111111:user/prowler"
|
||||
with raises(AWSIAMRoleARNRegionNotEmtpy) as error:
|
||||
with raises(AWSIAMRoleARNRegionNotEmtpyError) as error:
|
||||
parse_iam_credentials_arn(input_arn)
|
||||
|
||||
assert error._excinfo[0] == AWSIAMRoleARNRegionNotEmtpy
|
||||
assert error._excinfo[0] == AWSIAMRoleARNRegionNotEmtpyError
|
||||
|
||||
def test_iam_credentials_arn_parsing_raising_AWSIAMRoleARNPartitionEmpty(self):
|
||||
input_arn = "arn::iam::111111111111:user/prowler"
|
||||
with raises(AWSIAMRoleARNPartitionEmpty) as error:
|
||||
with raises(AWSIAMRoleARNPartitionEmptyError) as error:
|
||||
parse_iam_credentials_arn(input_arn)
|
||||
|
||||
assert error._excinfo[0] == AWSIAMRoleARNPartitionEmpty
|
||||
assert error._excinfo[0] == AWSIAMRoleARNPartitionEmptyError
|
||||
|
||||
def test_iam_credentials_arn_parsing_raising_AWSIAMRoleARNServiceNotIAMnorSTS(self):
|
||||
input_arn = "arn:aws:s3::111111111111:user/prowler"
|
||||
with raises(AWSIAMRoleARNServiceNotIAMnorSTS) as error:
|
||||
with raises(AWSIAMRoleARNServiceNotIAMnorSTSError) as error:
|
||||
parse_iam_credentials_arn(input_arn)
|
||||
|
||||
assert error._excinfo[0] == AWSIAMRoleARNServiceNotIAMnorSTS
|
||||
assert error._excinfo[0] == AWSIAMRoleARNServiceNotIAMnorSTSError
|
||||
|
||||
def test_iam_credentials_arn_parsing_raising_AWSIAMRoleARNInvalidAccountID(self):
|
||||
input_arn = "arn:aws:iam::AWS_ACCOUNT_ID:user/prowler"
|
||||
with raises(AWSIAMRoleARNInvalidAccountID) as error:
|
||||
with raises(AWSIAMRoleARNInvalidAccountIDError) as error:
|
||||
parse_iam_credentials_arn(input_arn)
|
||||
|
||||
assert error._excinfo[0] == AWSIAMRoleARNInvalidAccountID
|
||||
assert error._excinfo[0] == AWSIAMRoleARNInvalidAccountIDError
|
||||
|
||||
def test_iam_credentials_arn_parsing_raising_AWSIAMRoleARNInvalidResourceType(
|
||||
self,
|
||||
):
|
||||
input_arn = "arn:aws:iam::111111111111:account/prowler"
|
||||
with raises(AWSIAMRoleARNInvalidResourceType) as error:
|
||||
with raises(AWSIAMRoleARNInvalidResourceTypeError) as error:
|
||||
parse_iam_credentials_arn(input_arn)
|
||||
|
||||
assert error._excinfo[0] == AWSIAMRoleARNInvalidResourceType
|
||||
assert error._excinfo[0] == AWSIAMRoleARNInvalidResourceTypeError
|
||||
|
||||
def test_iam_credentials_arn_parsing_raising_AWSIAMRoleARNEmptyResource(self):
|
||||
input_arn = "arn:aws:iam::111111111111:role/"
|
||||
with raises(AWSIAMRoleARNEmptyResource) as error:
|
||||
with raises(AWSIAMRoleARNEmptyResourceError) as error:
|
||||
parse_iam_credentials_arn(input_arn)
|
||||
|
||||
assert error._excinfo[0] == AWSIAMRoleARNEmptyResource
|
||||
assert error._excinfo[0] == AWSIAMRoleARNEmptyResourceError
|
||||
|
||||
def test_is_valid_arn(self):
|
||||
assert is_valid_arn("arn:aws:iam::012345678910:user/test")
|
||||
|
||||
@@ -15,7 +15,7 @@ from prowler.providers.azure.azure_provider import AzureProvider
|
||||
from prowler.providers.azure.exceptions.exceptions import (
|
||||
AzureBrowserAuthNoTenantIDError,
|
||||
AzureHTTPResponseError,
|
||||
AzureInvalidAccountCredentialsError,
|
||||
AzureInvalidProviderIdError,
|
||||
AzureNoAuthenticationMethodError,
|
||||
AzureTenantIDNoBrowserAuthError,
|
||||
)
|
||||
@@ -158,7 +158,7 @@ class TestAzureProvider:
|
||||
assert exception.type == AzureBrowserAuthNoTenantIDError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1918] Azure Tenant ID (--tenant-id) is required for browser authentication mode"
|
||||
== "[2004] Azure Tenant ID (--tenant-id) is required for browser authentication mode"
|
||||
)
|
||||
|
||||
def test_azure_provider_not_browser_auth_but_tenant_id(self):
|
||||
@@ -197,7 +197,7 @@ class TestAzureProvider:
|
||||
assert exception.type == AzureTenantIDNoBrowserAuthError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1919] Azure Tenant ID (--tenant-id) is required for browser authentication mode"
|
||||
== "[2005] Azure Tenant ID (--tenant-id) is required for browser authentication mode"
|
||||
)
|
||||
|
||||
def test_test_connection_browser_auth(self):
|
||||
@@ -370,9 +370,7 @@ class TestAzureProvider:
|
||||
)
|
||||
|
||||
assert test_connection.error is not None
|
||||
assert isinstance(
|
||||
test_connection.error, AzureInvalidAccountCredentialsError
|
||||
)
|
||||
assert isinstance(test_connection.error, AzureInvalidProviderIdError)
|
||||
assert (
|
||||
"The provided credentials are not valid for the specified Azure subscription."
|
||||
in test_connection.error.args[0]
|
||||
@@ -390,7 +388,7 @@ class TestAzureProvider:
|
||||
assert exception.type == AzureHTTPResponseError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== f"[1924] Error in HTTP response from Azure - Authentication failed: Unable to get authority configuration for https://login.microsoftonline.com/{tenant_id}. Authority would typically be in a format of https://login.microsoftonline.com/your_tenant or https://tenant_name.ciamlogin.com or https://tenant_name.b2clogin.com/tenant.onmicrosoft.com/policy. Also please double check your tenant name or GUID is correct."
|
||||
== f"[2010] Error in HTTP response from Azure - Authentication failed: Unable to get authority configuration for https://login.microsoftonline.com/{tenant_id}. Authority would typically be in a format of https://login.microsoftonline.com/your_tenant or https://tenant_name.ciamlogin.com or https://tenant_name.b2clogin.com/tenant.onmicrosoft.com/policy. Also please double check your tenant name or GUID is correct."
|
||||
)
|
||||
|
||||
def test_test_connection_without_any_method(self):
|
||||
@@ -399,7 +397,7 @@ class TestAzureProvider:
|
||||
|
||||
assert exception.type == AzureNoAuthenticationMethodError
|
||||
assert (
|
||||
"[1917] Azure provider requires at least one authentication method set: [--az-cli-auth | --sp-env-auth | --browser-auth | --managed-identity-auth]"
|
||||
"[2003] Azure provider requires at least one authentication method set: [--az-cli-auth | --sp-env-auth | --browser-auth | --managed-identity-auth]"
|
||||
in exception.value.args[0]
|
||||
)
|
||||
|
||||
@@ -424,7 +422,7 @@ class TestAzureProvider:
|
||||
assert exception.type == AzureHTTPResponseError
|
||||
assert (
|
||||
exception.value.args[0]
|
||||
== "[1924] Error in HTTP response from Azure - Simulated HttpResponseError"
|
||||
== "[2010] Error in HTTP response from Azure - Simulated HttpResponseError"
|
||||
)
|
||||
|
||||
def test_test_connection_with_exception(self):
|
||||
|
||||
@@ -13,7 +13,7 @@ from prowler.config.config import (
|
||||
)
|
||||
from prowler.providers.common.models import Connection
|
||||
from prowler.providers.gcp.exceptions.exceptions import (
|
||||
GCPInvalidAccountCredentials,
|
||||
GCPInvalidProviderIdError,
|
||||
GCPTestConnectionError,
|
||||
)
|
||||
from prowler.providers.gcp.gcp_provider import GcpProvider
|
||||
@@ -593,7 +593,7 @@ class TestGCPProvider:
|
||||
"prowler.providers.gcp.gcp_provider.GcpProvider.validate_project_id"
|
||||
) as mock_validate_project_id:
|
||||
|
||||
mock_validate_project_id.side_effect = GCPInvalidAccountCredentials(
|
||||
mock_validate_project_id.side_effect = GCPInvalidProviderIdError(
|
||||
"Invalid project ID"
|
||||
)
|
||||
|
||||
@@ -605,4 +605,4 @@ class TestGCPProvider:
|
||||
provider_id="test-invalid-project",
|
||||
)
|
||||
|
||||
assert e.type == GCPInvalidAccountCredentials
|
||||
assert e.type == GCPInvalidProviderIdError
|
||||
|
||||
Reference in New Issue
Block a user