feat(rds): add missing tags to RDS checks (#5230)

This commit is contained in:
Rubén De la Torre Vico
2024-09-27 15:34:25 +02:00
committed by GitHub
parent c4a39662ae
commit c047b29140
10 changed files with 95 additions and 3 deletions
@@ -13,6 +13,7 @@ class rds_cluster_critical_event_subscription(Check):
report.resource_id = rds_client.audited_account
report.resource_arn = rds_client._get_rds_arn_template(db_event.region)
report.region = db_event.region
report.resource_tags = db_event.tags
if db_event.source_type == "db-cluster" and db_event.enabled:
if db_event.event_list == [] or set(db_event.event_list) == {
"maintenance",
@@ -20,12 +21,14 @@ class rds_cluster_critical_event_subscription(Check):
}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "PASS"
report.status_extended = "RDS cluster events are subscribed."
elif db_event.event_list == ["maintenance"]:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = (
"RDS cluster event category of failure is not subscribed."
@@ -34,6 +37,7 @@ class rds_cluster_critical_event_subscription(Check):
elif db_event.event_list == ["failure"]:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = "RDS cluster event category of maintenance is not subscribed."
@@ -13,6 +13,7 @@ class rds_instance_critical_event_subscription(Check):
report.resource_id = rds_client.audited_account
report.resource_arn = rds_client._get_rds_arn_template(db_event.region)
report.region = db_event.region
report.resource_tags = db_event.tags
if db_event.source_type == "db-instance" and db_event.enabled:
if db_event.event_list == [] or set(db_event.event_list) == {
"maintenance",
@@ -21,21 +22,25 @@ class rds_instance_critical_event_subscription(Check):
}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "PASS"
report.status_extended = "RDS instance events are subscribed."
elif set(db_event.event_list) == {"maintenance"}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = "RDS instance event categories of configuration change and failure are not subscribed."
elif set(db_event.event_list) == {"configuration change"}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = "RDS instance event categories of maintenance and failure are not subscribed."
elif set(db_event.event_list) == {"failure"}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = "RDS instance event categories of maintenance and configuration change are not subscribed."
elif set(db_event.event_list) == {
@@ -44,6 +49,7 @@ class rds_instance_critical_event_subscription(Check):
}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = (
"RDS instance event category of failure is not subscribed."
@@ -54,6 +60,7 @@ class rds_instance_critical_event_subscription(Check):
}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = "RDS instance event category of configuration change is not subscribed."
elif set(db_event.event_list) == {
@@ -62,6 +69,7 @@ class rds_instance_critical_event_subscription(Check):
}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = "RDS instance event category of maintenance is not subscribed."
findings.append(report)
@@ -13,12 +13,14 @@ class rds_instance_event_subscription_parameter_groups(Check):
report.resource_id = rds_client.audited_account
report.resource_arn = rds_client._get_rds_arn_template(db_event.region)
report.region = db_event.region
report.resource_tags = []
if db_event.source_type == "db-parameter-group" and db_event.enabled:
if db_event.event_list == [] or db_event.event_list == [
"configuration change",
]:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "PASS"
report.status_extended = (
"RDS parameter group events are subscribed."
@@ -13,6 +13,7 @@ class rds_instance_event_subscription_security_groups(Check):
report.resource_id = rds_client.audited_account
report.resource_arn = rds_client._get_rds_arn_template(db_event.region)
report.region = db_event.region
report.resource_tags = []
if db_event.source_type == "db-security-group" and db_event.enabled:
if db_event.event_list == [] or set(db_event.event_list) == {
"failure",
@@ -20,6 +21,7 @@ class rds_instance_event_subscription_security_groups(Check):
}:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "PASS"
report.status_extended = (
"RDS security group events are subscribed."
@@ -28,12 +30,14 @@ class rds_instance_event_subscription_security_groups(Check):
elif db_event.event_list == ["configuration change"]:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = "RDS security group event category of failure is not subscribed."
elif db_event.event_list == ["failure"]:
report.resource_id = db_event.id
report.resource_arn = db_event.arn
report.resource_tags = db_event.tags
report.status = "FAIL"
report.status_extended = "RDS security group event category of configuration change is not subscribed."
@@ -32,6 +32,7 @@ class RDS(AWSService):
self.__threading_call__(self._describe_db_cluster_snapshot_attributes)
self.__threading_call__(self._describe_db_engine_versions)
self.__threading_call__(self._describe_db_event_subscriptions)
self.__threading_call__(self._list_tags, self.db_event_subscriptions)
def _get_rds_arn_template(self, region):
return (
@@ -463,6 +464,7 @@ class RDS(AWSService):
event_list=[],
enabled=False,
region=regional_client.region,
tags=[],
)
)
except Exception as error:
@@ -470,6 +472,17 @@ class RDS(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(ResourceName=resource.arn)["TagList"]
except Exception as error:
logger.error(
f"{resource.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
class Certificate(BaseModel):
id: str
@@ -578,3 +591,4 @@ class EventSubscription(BaseModel):
event_list: list
enabled: bool
region: str
tags: Optional[list]
@@ -44,6 +44,7 @@ class Test_rds_cluster_critical_event_subscription:
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == RDS_ACCOUNT_ARN
assert result[0].resource_tags == []
@mock_aws
def test_rds_cluster_event_subscription_enabled(self):
@@ -93,6 +94,7 @@ class Test_rds_cluster_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@mock_aws
def test_rds_cluster_event_failure_only_subscription(self):
@@ -145,6 +147,7 @@ class Test_rds_cluster_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@mock_aws
def test_rds_cluster_event_maintenance_only_subscription(self):
@@ -194,3 +197,4 @@ class Test_rds_cluster_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == []
@@ -46,6 +46,7 @@ class Test_rds_instance_critical_event_subscription:
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == RDS_ACCOUNT_ARN
assert result[0].resource_tags == []
@mock_aws
def test_rds_no_events_ignoring(self):
@@ -130,6 +131,7 @@ class Test_rds_instance_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@mock_aws
def test_rds_instance_event_failure_only_subscription(self):
@@ -190,6 +192,7 @@ class Test_rds_instance_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@mock_aws
def test_rds_instance_event_maintenance_only_subscription(self):
@@ -247,6 +250,7 @@ class Test_rds_instance_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == []
@mock_aws
def test_rds_instance_event_configuration_change_only_subscription(self):
@@ -304,6 +308,7 @@ class Test_rds_instance_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == []
@mock_aws
def test_rds_instance_event_configuration_change_and_maintenance(self):
@@ -361,6 +366,7 @@ class Test_rds_instance_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == []
@mock_aws
def test_rds_instance_event_configuration_change_and_failure(self):
@@ -418,6 +424,7 @@ class Test_rds_instance_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == []
@mock_aws
def test_rds_instance_event_failure_and_maintenance(self):
@@ -475,3 +482,4 @@ class Test_rds_instance_critical_event_subscription:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == []
@@ -46,6 +46,7 @@ class Test_rds_instance__no_event_subscriptions:
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == RDS_ACCOUNT_ARN
assert result[0].resource_tags == []
@mock_aws
def test_rds_no_events_ignoring(self):
@@ -130,6 +131,7 @@ class Test_rds_instance__no_event_subscriptions:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@mock_aws
def test_rds_parameter_event_configuration_change_only_subscription(self):
@@ -187,3 +189,4 @@ class Test_rds_instance__no_event_subscriptions:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == []
@@ -14,7 +14,7 @@ make_api_call = botocore.client.BaseClient._make_api_call
RDS_ACCOUNT_ARN = f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:account"
class Test_rds_instance__no_event_subscriptions:
class Test_rds_instance_no_event_subscriptions:
@mock_aws
def test_rds_no_events(self):
from prowler.providers.aws.services.rds.rds_service import RDS
@@ -46,6 +46,7 @@ class Test_rds_instance__no_event_subscriptions:
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == RDS_ACCOUNT_ARN
assert result[0].resource_tags == []
@mock_aws
def test_rds_no_events_ignoring(self):
@@ -130,6 +131,7 @@ class Test_rds_instance__no_event_subscriptions:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@mock_aws
def test_rds_security_event_failure_only_subscription(self):
@@ -190,7 +192,7 @@ class Test_rds_instance__no_event_subscriptions:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == []
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@mock_aws
def test_rds_security_event_configuration_change_only_subscription(self):
@@ -215,6 +217,9 @@ class Test_rds_instance__no_event_subscriptions:
SourceType="db-security-group",
EventCategories=["configuration change"],
Enabled=True,
Tags=[
{"Key": "test", "Value": "testing"},
],
)
from prowler.providers.aws.services.rds.rds_service import RDS
@@ -248,6 +253,7 @@ class Test_rds_instance__no_event_subscriptions:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@mock_aws
def test_rds_no_security_group_event_subscription(self):
@@ -272,6 +278,9 @@ class Test_rds_instance__no_event_subscriptions:
SourceType="db-instance",
EventCategories=["configuration change"],
Enabled=True,
Tags=[
{"Key": "test", "Value": "testing"},
],
)
from prowler.providers.aws.services.rds.rds_service import RDS
@@ -302,6 +311,7 @@ class Test_rds_instance__no_event_subscriptions:
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == RDS_ACCOUNT_ARN
assert result[0].resource_tags == []
@mock_aws
def test_rds_no_event_subscription(self):
@@ -349,6 +359,7 @@ class Test_rds_instance__no_event_subscriptions:
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == AWS_ACCOUNT_NUMBER
assert result[0].resource_arn == RDS_ACCOUNT_ARN
assert result[0].resource_tags == []
@mock_aws
def test_rds_security_event_subscription_both_enabled(self):
@@ -409,3 +420,4 @@ class Test_rds_instance__no_event_subscriptions:
result[0].resource_arn
== f"arn:aws:rds:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:es:TestSub"
)
assert result[0].resource_tags == [{"Key": "test", "Value": "testing"}]
@@ -33,7 +33,6 @@ def mock_make_api_call(self, operation_name, kwarg):
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
class Test_RDS_Service:
# Test Dynamo Service
@mock_aws
def test_service(self):
@@ -382,3 +381,37 @@ class Test_RDS_Service:
rds.db_engines[AWS_REGION_US_EAST_1]["mysql"].engine_description
== "description"
)
@mock_aws
def test_list_tags(self):
# RDS client for this test class
conn = client("rds", region_name=AWS_REGION_US_EAST_1)
conn.create_db_instance(
DBInstanceIdentifier="db-primary-1",
AllocatedStorage=10,
Engine="postgres",
DBName="staging-postgres",
DBInstanceClass="db.m1.small",
)
event_sub = conn.create_event_subscription(
SubscriptionName="TestSub",
SnsTopicArn=f"arn:aws:sns:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:test",
SourceType="db-security-group",
Enabled=True,
Tags=[
{"Key": "test", "Value": "testing"},
],
)
# Tag event subscription
conn.add_tags_to_resource(
ResourceName=event_sub["EventSubscription"]["EventSubscriptionArn"],
Tags=[
{"Key": "test", "Value": "testing"},
],
)
aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1])
rds = RDS(aws_provider)
assert len(rds.db_event_subscriptions) == 1
assert rds.db_event_subscriptions[0].tags == [
{"Key": "test", "Value": "testing"},
]