mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-07-23 12:31:54 +00:00
feat(dms): add tags to DMS checks (#5209)
This commit is contained in:
committed by
GitHub
parent
19acb873af
commit
05f7170add
+4
-5
@@ -9,16 +9,15 @@ class dms_endpoint_ssl_enabled(Check):
|
||||
report = Check_Report_AWS(self.metadata())
|
||||
report.resource_id = endpoint.id
|
||||
report.resource_arn = endpoint_arn
|
||||
report.region = dms_client.audited_region
|
||||
report.region = endpoint.region
|
||||
report.resource_tags = endpoint.tags
|
||||
|
||||
if endpoint.ssl_mode == "none":
|
||||
report.status = "FAIL"
|
||||
report.status_extended = (
|
||||
f"DMS Endpoint {endpoint_arn} is not using SSL."
|
||||
)
|
||||
report.status_extended = f"DMS Endpoint {endpoint.id} is not using SSL."
|
||||
else:
|
||||
report.status = "PASS"
|
||||
report.status_extended = f"DMS Endpoint {endpoint_arn} is using SSL with mode: {endpoint.ssl_mode}."
|
||||
report.status_extended = f"DMS Endpoint {endpoint.id} is using SSL with mode: {endpoint.ssl_mode}."
|
||||
|
||||
findings.append(report)
|
||||
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ class dms_instance_minor_version_upgrade_enabled(Check):
|
||||
report.region = instance.region
|
||||
report.resource_id = instance.id
|
||||
report.resource_arn = instance.arn
|
||||
report.resource_tags = instance.tags
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"DMS Replication Instance {instance.id} does not have auto minor version upgrade enabled."
|
||||
if instance.auto_minor_version_upgrade:
|
||||
|
||||
+1
@@ -10,6 +10,7 @@ class dms_instance_multi_az_enabled(Check):
|
||||
report.region = instance.region
|
||||
report.resource_id = instance.id
|
||||
report.resource_arn = instance.arn
|
||||
report.resource_tags = instance.tags
|
||||
report.status = "FAIL"
|
||||
report.status_extended = f"DMS Replication Instance {instance.id} does not have multi az enabled."
|
||||
if instance.multi_az:
|
||||
|
||||
+1
@@ -12,6 +12,7 @@ class dms_instance_no_public_access(Check):
|
||||
report.region = instance.region
|
||||
report.resource_id = instance.id
|
||||
report.resource_arn = instance.arn
|
||||
report.resource_tags = instance.tags
|
||||
report.status = "PASS"
|
||||
report.status_extended = (
|
||||
f"DMS Replication Instance {instance.id} is not publicly accessible."
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from typing import Optional
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from prowler.lib.logger import logger
|
||||
@@ -5,7 +7,6 @@ from prowler.lib.scan_filters.scan_filters import is_resource_filtered
|
||||
from prowler.providers.aws.lib.service.service import AWSService
|
||||
|
||||
|
||||
################## Database Migration Service
|
||||
class DMS(AWSService):
|
||||
def __init__(self, provider):
|
||||
# Call AWSService's __init__
|
||||
@@ -13,7 +14,9 @@ class DMS(AWSService):
|
||||
self.instances = []
|
||||
self.endpoints = {}
|
||||
self.__threading_call__(self._describe_replication_instances)
|
||||
self.__threading_call__(self._list_tags, self.instances)
|
||||
self.__threading_call__(self._describe_endpoints)
|
||||
self.__threading_call__(self._list_tags, self.endpoints.values())
|
||||
|
||||
def _describe_replication_instances(self, regional_client):
|
||||
logger.info("DMS - Describing DMS Replication Instances...")
|
||||
@@ -64,7 +67,9 @@ class DMS(AWSService):
|
||||
is_resource_filtered(arn, self.audit_resources)
|
||||
):
|
||||
self.endpoints[arn] = Endpoint(
|
||||
arn=arn,
|
||||
id=endpoint["EndpointIdentifier"],
|
||||
region=regional_client.region,
|
||||
ssl_mode=endpoint.get("SslMode", False),
|
||||
)
|
||||
except Exception as error:
|
||||
@@ -72,10 +77,23 @@ class DMS(AWSService):
|
||||
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
|
||||
def _list_tags(self, resource: any):
|
||||
try:
|
||||
resource.tags = self.regional_clients[
|
||||
resource.region
|
||||
].list_tags_for_resource(ResourceArn=resource.arn)["TagList"]
|
||||
except Exception as error:
|
||||
logger.error(
|
||||
f"{resource.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
|
||||
)
|
||||
|
||||
|
||||
class Endpoint(BaseModel):
|
||||
arn: str
|
||||
id: str
|
||||
region: str
|
||||
ssl_mode: str
|
||||
tags: Optional[list]
|
||||
|
||||
|
||||
class RepInstance(BaseModel):
|
||||
@@ -88,3 +106,4 @@ class RepInstance(BaseModel):
|
||||
security_groups: list[str] = []
|
||||
multi_az: bool
|
||||
region: str
|
||||
tags: Optional[list]
|
||||
|
||||
+48
-12
@@ -5,7 +5,6 @@ from tests.providers.aws.utils import AWS_ACCOUNT_NUMBER, AWS_REGION_US_EAST_1
|
||||
|
||||
|
||||
class Test_dms_endpoint_ssl_enabled:
|
||||
|
||||
def test_dms_no_endpoints(self):
|
||||
dms_client = mock.MagicMock
|
||||
dms_client.endpoints = {}
|
||||
@@ -24,8 +23,15 @@ class Test_dms_endpoint_ssl_enabled:
|
||||
|
||||
def test_dms_endpoint_ssl_none(self):
|
||||
dms_client = mock.MagicMock
|
||||
endpoint_arn = f"arn:aws:dms:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:endpoint:test-endpoint-no-ssl"
|
||||
dms_client.endpoints = {
|
||||
"test-endpoint-no-ssl": Endpoint(id="test-endpoint-no-ssl", ssl_mode="none")
|
||||
endpoint_arn: Endpoint(
|
||||
arn=endpoint_arn,
|
||||
id="test-endpoint-no-ssl",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
ssl_mode="none",
|
||||
tags=[{"Key": "Name", "Value": "test-endpoint-no-ssl"}],
|
||||
)
|
||||
}
|
||||
dms_client.audited_account = AWS_ACCOUNT_NUMBER
|
||||
dms_client.audited_partition = "aws"
|
||||
@@ -45,18 +51,29 @@ class Test_dms_endpoint_ssl_enabled:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "FAIL"
|
||||
assert result[0].resource_id == "test-endpoint-no-ssl"
|
||||
assert result[0].resource_arn == "test-endpoint-no-ssl"
|
||||
assert (
|
||||
result[0].resource_arn
|
||||
== f"arn:aws:dms:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:endpoint:test-endpoint-no-ssl"
|
||||
)
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "DMS Endpoint test-endpoint-no-ssl is not using SSL."
|
||||
)
|
||||
assert result[0].resource_tags == [
|
||||
{"Key": "Name", "Value": "test-endpoint-no-ssl"}
|
||||
]
|
||||
|
||||
def test_dms_endpoint_ssl_require(self):
|
||||
dms_client = mock.MagicMock
|
||||
endpoint_arn = f"arn:aws:dms:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:endpoint:test-endpoint-ssl-require"
|
||||
dms_client.endpoints = {
|
||||
"test-endpoint-ssl-require": Endpoint(
|
||||
id="test-endpoint-ssl-require", ssl_mode="require"
|
||||
endpoint_arn: Endpoint(
|
||||
arn=endpoint_arn,
|
||||
id="test-endpoint-ssl-require",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
ssl_mode="require",
|
||||
tags=[{"Key": "Name", "Value": "test-endpoint-ssl-require"}],
|
||||
)
|
||||
}
|
||||
dms_client.audited_account = AWS_ACCOUNT_NUMBER
|
||||
@@ -77,18 +94,26 @@ class Test_dms_endpoint_ssl_enabled:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == "test-endpoint-ssl-require"
|
||||
assert result[0].resource_arn == "test-endpoint-ssl-require"
|
||||
assert result[0].resource_arn == endpoint_arn
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "DMS Endpoint test-endpoint-ssl-require is using SSL with mode: require."
|
||||
)
|
||||
assert result[0].resource_tags == [
|
||||
{"Key": "Name", "Value": "test-endpoint-ssl-require"}
|
||||
]
|
||||
|
||||
def test_dms_endpoint_ssl_verify_ca(self):
|
||||
dms_client = mock.MagicMock
|
||||
endpoint_arn = f"arn:aws:dms:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:endpoint:test-endpoint-ssl-verify-ca"
|
||||
dms_client.endpoints = {
|
||||
"test-endpoint-ssl-verify-ca": Endpoint(
|
||||
id="test-endpoint-ssl-verify-ca", ssl_mode="verify-ca"
|
||||
endpoint_arn: Endpoint(
|
||||
arn=endpoint_arn,
|
||||
id="test-endpoint-ssl-verify-ca",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
ssl_mode="verify-ca",
|
||||
tags=[{"Key": "Name", "Value": "test-endpoint-ssl-verify-ca"}],
|
||||
)
|
||||
}
|
||||
dms_client.audited_account = AWS_ACCOUNT_NUMBER
|
||||
@@ -109,18 +134,26 @@ class Test_dms_endpoint_ssl_enabled:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == "test-endpoint-ssl-verify-ca"
|
||||
assert result[0].resource_arn == "test-endpoint-ssl-verify-ca"
|
||||
assert result[0].resource_arn == endpoint_arn
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "DMS Endpoint test-endpoint-ssl-verify-ca is using SSL with mode: verify-ca."
|
||||
)
|
||||
assert result[0].resource_tags == [
|
||||
{"Key": "Name", "Value": "test-endpoint-ssl-verify-ca"}
|
||||
]
|
||||
|
||||
def test_dms_endpoint_ssl_verify_full(self):
|
||||
dms_client = mock.MagicMock
|
||||
endpoint_arn = f"arn:aws:dms:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:endpoint:test-endpoint-ssl-verify-full"
|
||||
dms_client.endpoints = {
|
||||
"test-endpoint-ssl-verify-full": Endpoint(
|
||||
id="test-endpoint-ssl-verify-full", ssl_mode="verify-full"
|
||||
endpoint_arn: Endpoint(
|
||||
arn=endpoint_arn,
|
||||
id="test-endpoint-ssl-verify-full",
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
ssl_mode="verify-full",
|
||||
tags=[{"Key": "Name", "Value": "test-endpoint-ssl-verify-full"}],
|
||||
)
|
||||
}
|
||||
dms_client.audited_account = AWS_ACCOUNT_NUMBER
|
||||
@@ -141,9 +174,12 @@ class Test_dms_endpoint_ssl_enabled:
|
||||
assert len(result) == 1
|
||||
assert result[0].status == "PASS"
|
||||
assert result[0].resource_id == "test-endpoint-ssl-verify-full"
|
||||
assert result[0].resource_arn == "test-endpoint-ssl-verify-full"
|
||||
assert result[0].resource_arn == endpoint_arn
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert (
|
||||
result[0].status_extended
|
||||
== "DMS Endpoint test-endpoint-ssl-verify-full is using SSL with mode: verify-full."
|
||||
)
|
||||
assert result[0].resource_tags == [
|
||||
{"Key": "Name", "Value": "test-endpoint-ssl-verify-full"}
|
||||
]
|
||||
|
||||
+8
@@ -40,6 +40,7 @@ class Test_dms_instance_minor_version_upgrade_enabled:
|
||||
auto_minor_version_upgrade=False,
|
||||
multi_az=True,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
tags=[{"Key": "Name", "Value": DMS_INSTANCE_NAME}],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -62,6 +63,9 @@ class Test_dms_instance_minor_version_upgrade_enabled:
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == DMS_INSTANCE_NAME
|
||||
assert result[0].resource_arn == DMS_INSTANCE_ARN
|
||||
assert result[0].resource_tags == [
|
||||
{"Key": "Name", "Value": DMS_INSTANCE_NAME}
|
||||
]
|
||||
|
||||
def test_dms_instance_minor_version_upgrade_enabled(self):
|
||||
dms_client = mock.MagicMock
|
||||
@@ -76,6 +80,7 @@ class Test_dms_instance_minor_version_upgrade_enabled:
|
||||
auto_minor_version_upgrade=True,
|
||||
multi_az=True,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
tags=[{"Key": "Name", "Value": DMS_INSTANCE_NAME}],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -98,3 +103,6 @@ class Test_dms_instance_minor_version_upgrade_enabled:
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == DMS_INSTANCE_NAME
|
||||
assert result[0].resource_arn == DMS_INSTANCE_ARN
|
||||
assert result[0].resource_tags == [
|
||||
{"Key": "Name", "Value": DMS_INSTANCE_NAME}
|
||||
]
|
||||
|
||||
@@ -40,6 +40,7 @@ class Test_dms_instance_multi_az:
|
||||
auto_minor_version_upgrade=False,
|
||||
multi_az=False,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
tags=[{"Key": "Name", "Value": DMS_INSTANCE_NAME}],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -62,6 +63,9 @@ class Test_dms_instance_multi_az:
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == DMS_INSTANCE_NAME
|
||||
assert result[0].resource_arn == DMS_INSTANCE_ARN
|
||||
assert result[0].resource_tags == [
|
||||
{"Key": "Name", "Value": DMS_INSTANCE_NAME}
|
||||
]
|
||||
|
||||
def test_dms_instance_multi_az_enabled(self):
|
||||
dms_client = mock.MagicMock
|
||||
@@ -76,6 +80,7 @@ class Test_dms_instance_multi_az:
|
||||
auto_minor_version_upgrade=True,
|
||||
multi_az=True,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
tags=[{"Key": "Name", "Value": DMS_INSTANCE_NAME}],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -98,3 +103,6 @@ class Test_dms_instance_multi_az:
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == DMS_INSTANCE_NAME
|
||||
assert result[0].resource_arn == DMS_INSTANCE_ARN
|
||||
assert result[0].resource_tags == [
|
||||
{"Key": "Name", "Value": DMS_INSTANCE_NAME}
|
||||
]
|
||||
|
||||
+28
-2
@@ -45,7 +45,6 @@ class Test_dms_instance_no_public_access:
|
||||
result = check.execute()
|
||||
assert len(result) == 0
|
||||
|
||||
@mock_aws
|
||||
def test_dms_private(self):
|
||||
dms_client = mock.MagicMock
|
||||
dms_client.instances = []
|
||||
@@ -60,6 +59,7 @@ class Test_dms_instance_no_public_access:
|
||||
auto_minor_version_upgrade=False,
|
||||
multi_az=False,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
tags=[{"Key": "Name", "Value": DMS_INSTANCE_NAME}],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -88,8 +88,13 @@ class Test_dms_instance_no_public_access:
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == DMS_INSTANCE_NAME
|
||||
assert result[0].resource_arn == DMS_INSTANCE_ARN
|
||||
assert result[0].resource_tags == [
|
||||
{
|
||||
"Key": "Name",
|
||||
"Value": DMS_INSTANCE_NAME,
|
||||
}
|
||||
]
|
||||
|
||||
@mock_aws
|
||||
def test_dms_public(self):
|
||||
dms_client = mock.MagicMock
|
||||
dms_client.instances = []
|
||||
@@ -104,6 +109,7 @@ class Test_dms_instance_no_public_access:
|
||||
auto_minor_version_upgrade=False,
|
||||
multi_az=False,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
tags=[{"Key": "Name", "Value": DMS_INSTANCE_NAME}],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -132,6 +138,12 @@ class Test_dms_instance_no_public_access:
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == DMS_INSTANCE_NAME
|
||||
assert result[0].resource_arn == DMS_INSTANCE_ARN
|
||||
assert result[0].resource_tags == [
|
||||
{
|
||||
"Key": "Name",
|
||||
"Value": DMS_INSTANCE_NAME,
|
||||
}
|
||||
]
|
||||
|
||||
@mock_aws
|
||||
def test_dms_public_with_public_sg(self):
|
||||
@@ -163,6 +175,7 @@ class Test_dms_instance_no_public_access:
|
||||
auto_minor_version_upgrade=False,
|
||||
multi_az=False,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
tags=[{"Key": "Name", "Value": DMS_INSTANCE_NAME}],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -201,6 +214,12 @@ class Test_dms_instance_no_public_access:
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == DMS_INSTANCE_NAME
|
||||
assert result[0].resource_arn == DMS_INSTANCE_ARN
|
||||
assert result[0].resource_tags == [
|
||||
{
|
||||
"Key": "Name",
|
||||
"Value": DMS_INSTANCE_NAME,
|
||||
}
|
||||
]
|
||||
|
||||
@mock_aws
|
||||
def test_dms_public_with_filtered_sg(self):
|
||||
@@ -232,6 +251,7 @@ class Test_dms_instance_no_public_access:
|
||||
auto_minor_version_upgrade=False,
|
||||
multi_az=False,
|
||||
region=AWS_REGION_US_EAST_1,
|
||||
tags=[{"Key": "Name", "Value": DMS_INSTANCE_NAME}],
|
||||
)
|
||||
)
|
||||
|
||||
@@ -270,3 +290,9 @@ class Test_dms_instance_no_public_access:
|
||||
assert result[0].region == AWS_REGION_US_EAST_1
|
||||
assert result[0].resource_id == DMS_INSTANCE_NAME
|
||||
assert result[0].resource_arn == DMS_INSTANCE_ARN
|
||||
assert result[0].resource_tags == [
|
||||
{
|
||||
"Key": "Name",
|
||||
"Value": DMS_INSTANCE_NAME,
|
||||
}
|
||||
]
|
||||
|
||||
@@ -14,6 +14,9 @@ DMS_INSTANCE_ARN = (
|
||||
)
|
||||
KMS_KEY_ID = f"arn:aws:kms:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:key/abcdabcd-1234-abcd-1234-abcdabcdabcd"
|
||||
|
||||
DMS_ENDPOINT_NAME = "dms-endpoint"
|
||||
DMS_ENDPOINT_ARN = f"arn:aws:dms:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:endpoint:{DMS_ENDPOINT_NAME}"
|
||||
|
||||
# Mocking Access Analyzer Calls
|
||||
make_api_call = botocore.client.BaseClient._make_api_call
|
||||
|
||||
@@ -34,6 +37,31 @@ def mock_make_api_call(self, operation_name, kwargs):
|
||||
},
|
||||
]
|
||||
}
|
||||
elif operation_name == "DescribeEndpoints":
|
||||
return {
|
||||
"Endpoints": [
|
||||
{
|
||||
"EndpointIdentifier": DMS_ENDPOINT_NAME,
|
||||
"EndpointArn": DMS_ENDPOINT_ARN,
|
||||
"SslMode": "require",
|
||||
}
|
||||
]
|
||||
}
|
||||
elif operation_name == "ListTagsForResource":
|
||||
if kwargs["ResourceArn"] == DMS_INSTANCE_ARN:
|
||||
return {
|
||||
"TagList": [
|
||||
{"Key": "Name", "Value": "rep-instance"},
|
||||
{"Key": "Owner", "Value": "admin"},
|
||||
]
|
||||
}
|
||||
elif kwargs["ResourceArn"] == DMS_ENDPOINT_ARN:
|
||||
return {
|
||||
"TagList": [
|
||||
{"Key": "Name", "Value": "dms-endpoint"},
|
||||
{"Key": "Owner", "Value": "admin"},
|
||||
]
|
||||
}
|
||||
|
||||
return make_api_call(self, operation_name, kwargs)
|
||||
|
||||
@@ -84,3 +112,25 @@ class Test_DMS_Service:
|
||||
assert dms.instances[0].auto_minor_version_upgrade
|
||||
assert dms.instances[0].multi_az
|
||||
assert dms.instances[0].security_groups == []
|
||||
|
||||
# Test DMS Endpoints
|
||||
def test_describe_endpoints(self):
|
||||
aws_provider = set_mocked_aws_provider()
|
||||
dms = DMS(aws_provider)
|
||||
|
||||
assert len(dms.endpoints) == 1
|
||||
assert dms.endpoints[DMS_ENDPOINT_ARN].id == DMS_ENDPOINT_NAME
|
||||
assert dms.endpoints[DMS_ENDPOINT_ARN].ssl_mode == "require"
|
||||
|
||||
def test_list_tags(self):
|
||||
aws_provider = set_mocked_aws_provider()
|
||||
dms = DMS(aws_provider)
|
||||
|
||||
assert dms.instances[0].tags == [
|
||||
{"Key": "Name", "Value": "rep-instance"},
|
||||
{"Key": "Owner", "Value": "admin"},
|
||||
]
|
||||
assert dms.endpoints[DMS_ENDPOINT_ARN].tags == [
|
||||
{"Key": "Name", "Value": "dms-endpoint"},
|
||||
{"Key": "Owner", "Value": "admin"},
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user