chore(elasticache): enhance service and checks (#4329)

This commit is contained in:
Sergio Garcia
2024-07-01 10:06:24 -04:00
committed by GitHub
parent de777a6417
commit 82ccdc45d2
20 changed files with 421 additions and 147 deletions
@@ -16,9 +16,12 @@ class elasticache_cluster_uses_public_subnet(Check):
report.region = cluster.region
report.status = "PASS"
report.status_extended = (
f"Cluster {cluster.id} is not using public subnets."
)
if cluster.engine == "redis":
report.status_extended = (
f"Elasticache Redis Node {cluster.id} is not using public subnets."
)
else:
report.status_extended = f"Elasticache Memcached Cluster {cluster.id} is not using public subnets."
public_subnets = []
for subnet in cluster.subnets:
@@ -30,7 +33,10 @@ class elasticache_cluster_uses_public_subnet(Check):
if len(public_subnets) > 0:
report.status = "FAIL"
report.status_extended = f"Cluster {cluster.id} is using {', '.join(public_subnets)} public subnets."
if cluster.engine == "redis":
report.status_extended = f"Elasticache Redis Node {cluster.id} is using {', '.join(public_subnets)} public subnets."
else:
report.status_extended = f"Elasticache Memcached Cluster {cluster.id} is using {', '.join(public_subnets)} public subnets."
findings.append(report)
@@ -1,14 +1,14 @@
{
"Provider": "aws",
"CheckID": "elasticache_cluster_backup_enabled",
"CheckTitle": "Ensure Elasticache Cluster has automatic backups enabled.",
"CheckID": "elasticache_redis_cluster_backup_enabled",
"CheckTitle": "Ensure Elasticache Redis cache cluster has automatic backups enabled.",
"CheckType": [],
"ServiceName": "elasticache",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "high",
"ResourceType": "AWSElastiCacheClusters",
"Description": "Ensure Elasticache Cluster has automatic backups enabled.",
"Description": "Ensure Elasticache Redis cache cluster has automatic backups enabled.",
"Risk": "Ensure that your Amazon ElastiCache Redis cache clusters have a sufficient backup retention period set in order to fulfill your organization's compliance requirements. The retention period represents the number of days for which Amazon ElastiCache service retains automatic Redis cluster backups before deleting them.",
"RelatedUrl": "https://docs.aws.amazon.com/securityhub/latest/userguide/elasticache-controls.html#elasticache-1",
"Remediation": {
@@ -4,7 +4,7 @@ from prowler.providers.aws.services.elasticache.elasticache_client import (
)
class elasticache_cluster_backup_enabled(Check):
class elasticache_redis_cluster_backup_enabled(Check):
def execute(self):
findings = []
for repl_group in elasticache_client.replication_groups.values():
@@ -12,18 +12,19 @@ class elasticache_cluster_backup_enabled(Check):
report.region = repl_group.region
report.resource_id = repl_group.id
report.resource_arn = repl_group.arn
report.resource_tags = repl_group.tags
report.status = "FAIL"
report.status_extended = f"Elasticache Cluster {repl_group.id} does not have automated snapshot backups enabled."
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} does not have automated snapshot backups enabled."
if repl_group.snapshot_retention > elasticache_client.audit_config.get(
"minimum_snapshot_retention_period", 7
):
report.status = "PASS"
report.status_extended = f"Elasticache Cluster {repl_group.id} has automated snapshot backups enabled with retention period {repl_group.snapshot_retention} days."
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} has automated snapshot backups enabled with retention period {repl_group.snapshot_retention} days."
else:
if repl_group.snapshot_retention > 0:
report.status = "FAIL"
report.check_metadata.Severity = "low"
report.status_extended = f"Elasticache Cluster {repl_group.id} has automated snapshot backups enabled with retention period {repl_group.snapshot_retention} days. Recommended to increase the snapshot retention period to a minimum of 7 days."
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} has automated snapshot backups enabled with retention period {repl_group.snapshot_retention} days. Recommended to increase the snapshot retention period to a minimum of 7 days."
findings.append(report)
@@ -1,15 +1,15 @@
{
"Provider": "aws",
"CheckID": "elasticache_replication_group_encrypted_in_transit",
"CheckTitle": "Ensure Elasticache Replication Groups have in transit encryption enabled.",
"CheckID": "elasticache_redis_cluster_in_transit_encryption_enabled",
"CheckTitle": "Ensure Elasticache Redis cache clusters have in transit encryption enabled.",
"CheckType": [],
"ServiceName": "elasticache",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"ResourceType": "AWSElastiCacheReplicationGroups",
"Description": "Ensure Elasticache Replication Groups have in transit encryption enabled.",
"Risk": "There is a risk of exposing sensitive data if Elasticache Replication Group does not have in transit encryption enabled.",
"Description": "Ensure Elasticache Redis cache clusters have in transit encryption enabled.",
"Risk": "There is a risk of exposing sensitive data if Elasticache Redis cache cluster does not have in transit encryption enabled.",
"RelatedUrl": "https://docs.aws.amazon.com/securityhub/latest/userguide/elasticache-controls.html#elasticache-5",
"Remediation": {
"Code": {
@@ -19,7 +19,7 @@
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_10/"
},
"Recommendation": {
"Text": "Ensure your Elasticache replication groups have in transit encryption enabled.",
"Text": "Ensure your Elasticache Redis cache clusters have in transit encryption enabled.",
"Url": "https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/in-transit-encryption.html"
}
},
@@ -4,7 +4,7 @@ from prowler.providers.aws.services.elasticache.elasticache_client import (
)
class elasticache_replication_group_encrypted_in_transit(Check):
class elasticache_redis_cluster_in_transit_encryption_enabled(Check):
def execute(self):
findings = []
for repl_group in elasticache_client.replication_groups.values():
@@ -12,11 +12,12 @@ class elasticache_replication_group_encrypted_in_transit(Check):
report.region = repl_group.region
report.resource_id = repl_group.id
report.resource_arn = repl_group.arn
report.resource_tags = repl_group.tags
report.status = "FAIL"
report.status_extended = f"Elasticache Replication Group {repl_group.id} does not have in transit encryption enabled."
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} does not have in transit encryption enabled."
if repl_group.transit_encryption:
report.status = "PASS"
report.status_extended = f"Elasticache Replication Group {repl_group.id} has in transit encryption enabled."
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} has in transit encryption enabled."
findings.append(report)
@@ -1,14 +1,14 @@
{
"Provider": "aws",
"CheckID": "elasticache_cluster_multi_az_enabled",
"CheckTitle": "Ensure Elasticache Cluster has Multi-AZ enabled.",
"CheckID": "elasticache_redis_cluster_multi_az_enabled",
"CheckTitle": "Ensure Elasticache Elasticache Redis cache cluster has Multi-AZ enabled.",
"CheckType": [],
"ServiceName": "elasticache",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"ResourceType": "AWSElastiCacheClusters",
"Description": "Ensure Elasticache Cluster has Multi-AZ enabled.",
"Description": "Ensure Elasticache Elasticache Redis cache cluster has Multi-AZ enabled.",
"Risk": "Ensure that your Amazon ElastiCache Redis cache clusters has Multi-AZ enabled.",
"RelatedUrl": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/ElastiCache/elasticache-multi-az.html#",
"Remediation": {
@@ -19,7 +19,7 @@
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/ensure-aws-elasticache-redis-cluster-with-multi-az-automatic-failover-feature-set-to-enabled/"
},
"Recommendation": {
"Text": "Ensure Elasticache Cluster has Multi-AZ enabled.",
"Text": "Ensure Elasticache Elasticache Redis cache cluster has Multi-AZ enabled.",
"Url": "https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/ElastiCache/elasticache-multi-az.html#"
}
},
@@ -4,7 +4,7 @@ from prowler.providers.aws.services.elasticache.elasticache_client import (
)
class elasticache_cluster_multi_az_enabled(Check):
class elasticache_redis_cluster_multi_az_enabled(Check):
def execute(self):
findings = []
for repl_group in elasticache_client.replication_groups.values():
@@ -12,15 +12,12 @@ class elasticache_cluster_multi_az_enabled(Check):
report.region = repl_group.region
report.resource_id = repl_group.id
report.resource_arn = repl_group.arn
report.resource_tags = repl_group.tags
report.status = "FAIL"
report.status_extended = (
f"Elasticache Cluster {repl_group.id} does not have Multi-AZ enabled."
)
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} does not have Multi-AZ enabled."
if repl_group.multi_az == "enabled":
report.status = "PASS"
report.status_extended = (
f"Elasticache Cluster {repl_group.id} has Multi-AZ enabled."
)
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} has Multi-AZ enabled."
findings.append(report)
@@ -1,15 +1,15 @@
{
"Provider": "aws",
"CheckID": "elasticache_replication_group_encrypted_at_rest",
"CheckTitle": "Ensure Elasticache Replication Groups have at rest encryption enabled.",
"CheckID": "elasticache_redis_cluster_rest_encryption_enabled",
"CheckTitle": "Ensure Elasticache Redis cache clusters have at rest encryption enabled.",
"CheckType": [],
"ServiceName": "elasticache",
"SubServiceName": "",
"ResourceIdTemplate": "arn:partition:service:region:account-id:resource-id",
"Severity": "medium",
"ResourceType": "AWSElastiCacheReplicationGroups",
"Description": "Ensure Elasticache Replication Groups have at rest encryption enabled.",
"Risk": "There is a risk of exposing sensitive data if Elasticache Replication Group does not have at rest encryption enabled.",
"Description": "Ensure Elasticache Redis cache clusters have at rest encryption enabled.",
"Risk": "There is a risk of exposing sensitive data if Elasticache Redis cache clusters does not have at rest encryption enabled.",
"RelatedUrl": "https://docs.aws.amazon.com/securityhub/latest/userguide/elasticache-controls.html#elasticache-4",
"Remediation": {
"Code": {
@@ -19,7 +19,7 @@
"Terraform": "https://docs.prowler.com/checks/aws/general-policies/general_9/"
},
"Recommendation": {
"Text": "Ensure your Elasticache replication groups have at rest encryption enabled.",
"Text": "Ensure your Elasticache Redis cache clusters have at rest encryption enabled.",
"Url": "https://docs.aws.amazon.com/AmazonElastiCache/latest/red-ug/at-rest-encryption.html#at-rest-encryption-enable"
}
},
@@ -4,7 +4,7 @@ from prowler.providers.aws.services.elasticache.elasticache_client import (
)
class elasticache_replication_group_encrypted_at_rest(Check):
class elasticache_redis_cluster_rest_encryption_enabled(Check):
def execute(self):
findings = []
for repl_group in elasticache_client.replication_groups.values():
@@ -12,11 +12,12 @@ class elasticache_replication_group_encrypted_at_rest(Check):
report.region = repl_group.region
report.resource_id = repl_group.id
report.resource_arn = repl_group.arn
report.resource_tags = repl_group.tags
report.status = "FAIL"
report.status_extended = f"Elasticache Replication Group {repl_group.id} does not have at rest encryption enabled."
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} does not have at rest encryption enabled."
if repl_group.encrypted:
report.status = "PASS"
report.status_extended = f"Elasticache Replication Group {repl_group.id} has at rest encryption enabled."
report.status_extended = f"Elasticache Redis cache cluster {repl_group.id} has at rest encryption enabled."
findings.append(report)
@@ -1,6 +1,5 @@
from typing import Optional
from botocore.exceptions import ClientError
from pydantic import BaseModel
from prowler.lib.logger import logger
@@ -17,31 +16,33 @@ class ElastiCache(AWSService):
self.replication_groups = {}
self.__threading_call__(self.__describe_cache_clusters__)
self.__threading_call__(self.__describe_cache_subnet_groups__)
self.__list_tags_for_resource__()
self.__threading_call__(self.__describe_replication_groups__)
self.__list_tags_for_resource__()
def __describe_cache_clusters__(self, regional_client):
# Memcached Clusters and Redis Nodes
logger.info("Elasticache - Describing Cache Clusters...")
try:
for cache_cluster in regional_client.describe_cache_clusters()[
"CacheClusters"
]:
cluster_arn = cache_cluster["ARN"]
if not self.audit_resources or (
is_resource_filtered(cluster_arn, self.audit_resources)
):
self.clusters[cluster_arn] = Cluster(
id=cache_cluster["CacheClusterId"],
arn=cluster_arn,
region=regional_client.region,
security_groups=[
sg["SecurityGroupId"]
for sg in cache_cluster["SecurityGroups"]
if sg["Status"] == "active"
],
cache_subnet_group_id=cache_cluster.get(
"CacheSubnetGroupName", None
),
try:
cluster_arn = cache_cluster["ARN"]
if not self.audit_resources or (
is_resource_filtered(cluster_arn, self.audit_resources)
):
self.clusters[cluster_arn] = Cluster(
id=cache_cluster["CacheClusterId"],
arn=cluster_arn,
region=regional_client.region,
engine=cache_cluster["Engine"],
cache_subnet_group_id=cache_cluster.get(
"CacheSubnetGroupName", None
),
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
logger.error(
@@ -75,23 +76,31 @@ class ElastiCache(AWSService):
f"{error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __list_tags_for_resource__(self):
logger.info("Elasticache - Listing Tags...")
def __describe_replication_groups__(self, regional_client):
# Redis Clusters
logger.info("Elasticache - Describing Replication Groups...")
try:
for cluster in self.clusters.values():
for repl_group in regional_client.describe_replication_groups()[
"ReplicationGroups"
]:
try:
regional_client = self.regional_clients[cluster.region]
cluster.tags = regional_client.list_tags_for_resource(
ResourceName=cluster.arn
)["TagList"]
except ClientError as error:
if error.response["Error"]["Code"] == "CacheClusterNotFound":
logger.warning(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
else:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
replication_arn = repl_group["ARN"]
if not self.audit_resources or (
is_resource_filtered(replication_arn, self.audit_resources)
):
self.replication_groups[replication_arn] = ReplicationGroup(
id=repl_group["ReplicationGroupId"],
arn=replication_arn,
region=regional_client.region,
status=repl_group["Status"],
snapshot_retention=repl_group.get(
"SnapshotRetentionLimit", 0
),
encrypted=repl_group.get("AtRestEncryptionEnabled", False),
transit_encryption=repl_group.get(
"TransitEncryptionEnabled", False
),
multi_az=repl_group.get("MultiAZ", "disabled"),
)
except Exception as error:
logger.error(
@@ -102,25 +111,38 @@ class ElastiCache(AWSService):
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def __describe_replication_groups__(self, regional_client):
logger.info("Elasticache - Describing Replication Groups...")
def __list_tags_for_resource__(self):
logger.info("Elasticache - Listing Tags...")
try:
for repl_group in regional_client.describe_replication_groups()[
"ReplicationGroups"
]:
replication_arn = repl_group["ARN"]
if not self.audit_resources or (
is_resource_filtered(replication_arn, self.audit_resources)
):
self.replication_groups[replication_arn] = ReplicationGroup(
id=repl_group["ReplicationGroupId"],
arn=replication_arn,
region=regional_client.region,
status=repl_group["Status"],
snapshot_retention=repl_group.get("SnapshotRetentionLimit", 0),
encrypted=repl_group["AtRestEncryptionEnabled"],
transit_encryption=repl_group["TransitEncryptionEnabled"],
multi_az=repl_group["MultiAZ"],
for cluster in self.clusters.values():
try:
regional_client = self.regional_clients[cluster.region]
cluster.tags = regional_client.list_tags_for_resource(
ResourceName=cluster.arn
)["TagList"]
except regional_client.exceptions.CacheClusterNotFoundFault as error:
logger.warning(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
for repl_group in self.replication_groups.values():
try:
regional_client = self.regional_clients[repl_group.region]
repl_group.tags = regional_client.list_tags_for_resource(
ResourceName=repl_group.arn
)["TagList"]
except (
regional_client.exceptions.ReplicationGroupNotFoundFault
) as error:
logger.warning(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
except Exception as error:
logger.error(
@@ -132,7 +154,7 @@ class Cluster(BaseModel):
id: str
arn: str
region: str
security_groups: list[str] = []
engine: str
cache_subnet_group_id: Optional[str]
subnets: list = []
tags: Optional[list]
@@ -147,3 +169,4 @@ class ReplicationGroup(BaseModel):
encrypted: bool
transit_encryption: bool
multi_az: str
tags: Optional[list]
@@ -9,6 +9,8 @@ from tests.providers.aws.services.elasticache.elasticache_service_test import (
ELASTICACHE_CLUSTER_ARN,
ELASTICACHE_CLUSTER_NAME,
ELASTICACHE_CLUSTER_TAGS,
ELASTICACHE_ENGINE,
ELASTICACHE_ENGINE_MEMCACHED,
SUBNET_1,
SUBNET_2,
SUBNET_GROUP_NAME,
@@ -67,6 +69,7 @@ class Test_elasticache_cluster_uses_public_subnet:
arn=ELASTICACHE_CLUSTER_ARN,
name=ELASTICACHE_CLUSTER_NAME,
id=ELASTICACHE_CLUSTER_NAME,
engine=ELASTICACHE_ENGINE,
region=AWS_REGION_US_EAST_1,
cache_subnet_group_id=SUBNET_GROUP_NAME,
tags=ELASTICACHE_CLUSTER_TAGS,
@@ -99,7 +102,7 @@ class Test_elasticache_cluster_uses_public_subnet:
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Cluster {ELASTICACHE_CLUSTER_NAME} is not using public subnets."
== f"Elasticache Redis Node {ELASTICACHE_CLUSTER_NAME} is not using public subnets."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == ELASTICACHE_CLUSTER_NAME
@@ -115,6 +118,7 @@ class Test_elasticache_cluster_uses_public_subnet:
arn=ELASTICACHE_CLUSTER_ARN,
name=ELASTICACHE_CLUSTER_NAME,
id=ELASTICACHE_CLUSTER_NAME,
engine=ELASTICACHE_ENGINE,
region=AWS_REGION_US_EAST_1,
cache_subnet_group_id=SUBNET_GROUP_NAME,
subnets=[SUBNET_1, SUBNET_2],
@@ -176,7 +180,7 @@ class Test_elasticache_cluster_uses_public_subnet:
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Cluster {ELASTICACHE_CLUSTER_NAME} is not using public subnets."
== f"Elasticache Redis Node {ELASTICACHE_CLUSTER_NAME} is not using public subnets."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == ELASTICACHE_CLUSTER_NAME
@@ -192,6 +196,7 @@ class Test_elasticache_cluster_uses_public_subnet:
arn=ELASTICACHE_CLUSTER_ARN,
name=ELASTICACHE_CLUSTER_NAME,
id=ELASTICACHE_CLUSTER_NAME,
engine=ELASTICACHE_ENGINE,
region=AWS_REGION_US_EAST_1,
cache_subnet_group_id=SUBNET_GROUP_NAME,
subnets=[SUBNET_1, SUBNET_2],
@@ -253,7 +258,163 @@ class Test_elasticache_cluster_uses_public_subnet:
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Cluster {ELASTICACHE_CLUSTER_NAME} is using subnet-1, subnet-2 public subnets."
== f"Elasticache Redis Node {ELASTICACHE_CLUSTER_NAME} is using subnet-1, subnet-2 public subnets."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == ELASTICACHE_CLUSTER_NAME
assert result[0].resource_arn == ELASTICACHE_CLUSTER_ARN
assert result[0].resource_tags == ELASTICACHE_CLUSTER_TAGS
def test_elasticache_clusters_using_public_subnets_memcached(self):
# Mock ElastiCache Service
elasticache_service = MagicMock
elasticache_service.clusters = {}
elasticache_service.clusters[ELASTICACHE_CLUSTER_ARN] = Cluster(
arn=ELASTICACHE_CLUSTER_ARN,
name=ELASTICACHE_CLUSTER_NAME,
id=ELASTICACHE_CLUSTER_NAME,
engine=ELASTICACHE_ENGINE_MEMCACHED,
region=AWS_REGION_US_EAST_1,
cache_subnet_group_id=SUBNET_GROUP_NAME,
subnets=[SUBNET_1, SUBNET_2],
tags=ELASTICACHE_CLUSTER_TAGS,
)
# Mock VPC Service
vpc_client = MagicMock
vpc_client.vpc_subnets = {}
vpc_client.vpc_subnets[SUBNET_1] = VpcSubnet(
id=SUBNET_1,
name=SUBNET_1,
arn="arn_test",
default=False,
vpc_id=VPC_ID,
cidr_block="192.168.0.0/24",
availability_zone=AWS_REGION_US_EAST_1_AZA,
public=True,
nat_gateway=False,
region=AWS_REGION_US_EAST_1,
tags=[],
mapPublicIpOnLaunch=False,
)
vpc_client.vpc_subnets[SUBNET_2] = VpcSubnet(
id=SUBNET_2,
name=SUBNET_2,
arn="arn_test",
default=False,
vpc_id=VPC_ID,
cidr_block="192.168.0.1/24",
availability_zone=AWS_REGION_US_EAST_1_AZB,
public=True,
nat_gateway=False,
region=AWS_REGION_US_EAST_1,
tags=[],
mapPublicIpOnLaunch=False,
)
with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_aws_provider([AWS_REGION_US_EAST_1]),
), mock.patch(
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
), mock.patch(
"prowler.providers.aws.services.vpc.vpc_service.VPC",
new=vpc_client,
), mock.patch(
"prowler.providers.aws.services.vpc.vpc_client.vpc_client",
new=vpc_client,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_uses_public_subnet.elasticache_cluster_uses_public_subnet import (
elasticache_cluster_uses_public_subnet,
)
check = elasticache_cluster_uses_public_subnet()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Elasticache Memcached Cluster {ELASTICACHE_CLUSTER_NAME} is using subnet-1, subnet-2 public subnets."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == ELASTICACHE_CLUSTER_NAME
assert result[0].resource_arn == ELASTICACHE_CLUSTER_ARN
assert result[0].resource_tags == ELASTICACHE_CLUSTER_TAGS
def test_elasticache_clusters_using_private_subnets_memchached(self):
# Mock ElastiCache Service
elasticache_service = MagicMock
elasticache_service.clusters = {}
elasticache_service.clusters[ELASTICACHE_CLUSTER_ARN] = Cluster(
arn=ELASTICACHE_CLUSTER_ARN,
name=ELASTICACHE_CLUSTER_NAME,
id=ELASTICACHE_CLUSTER_NAME,
engine=ELASTICACHE_ENGINE_MEMCACHED,
region=AWS_REGION_US_EAST_1,
cache_subnet_group_id=SUBNET_GROUP_NAME,
subnets=[SUBNET_1, SUBNET_2],
tags=ELASTICACHE_CLUSTER_TAGS,
)
# Mock VPC Service
vpc_client = MagicMock
vpc_client.vpc_subnets = {}
vpc_client.vpc_subnets[SUBNET_1] = VpcSubnet(
id=SUBNET_1,
name=SUBNET_1,
arn="arn_test",
default=False,
vpc_id=VPC_ID,
cidr_block="192.168.0.0/24",
availability_zone=AWS_REGION_US_EAST_1_AZA,
public=False,
nat_gateway=False,
region=AWS_REGION_US_EAST_1,
tags=[],
mapPublicIpOnLaunch=False,
)
vpc_client.vpc_subnets[SUBNET_2] = VpcSubnet(
id=SUBNET_2,
name=SUBNET_2,
arn="arn_test",
default=False,
vpc_id=VPC_ID,
cidr_block="192.168.0.1/24",
availability_zone=AWS_REGION_US_EAST_1_AZB,
public=False,
nat_gateway=False,
region=AWS_REGION_US_EAST_1,
tags=[],
mapPublicIpOnLaunch=False,
)
with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_aws_provider([AWS_REGION_US_EAST_1]),
), mock.patch(
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
), mock.patch(
"prowler.providers.aws.services.vpc.vpc_service.VPC",
new=vpc_client,
), mock.patch(
"prowler.providers.aws.services.vpc.vpc_client.vpc_client",
new=vpc_client,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_uses_public_subnet.elasticache_cluster_uses_public_subnet import (
elasticache_cluster_uses_public_subnet,
)
check = elasticache_cluster_uses_public_subnet()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Elasticache Memcached Cluster {ELASTICACHE_CLUSTER_NAME} is not using public subnets."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == ELASTICACHE_CLUSTER_NAME
@@ -20,12 +20,15 @@ REPLICATION_GROUP_SNAPSHOT_RETENTION = "0"
REPLICATION_GROUP_ENCRYPTION = True
REPLICATION_GROUP_TRANSIT_ENCRYPTION = True
REPLICATION_GROUP_MULTI_AZ = "enabled"
REPLICATION_GROUP_TAGS = [
{"Key": "environment", "Value": "test"},
]
# Patch every AWS call using Boto3
make_api_call = botocore.client.BaseClient._make_api_call
class Test_elasticache_cluster_backup_enabled:
class Test_elasticache_redis_cluster_backup_enabled:
@mock_aws
def test_elasticache_no_replication_groups(self):
@@ -40,11 +43,11 @@ class Test_elasticache_cluster_backup_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_client,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_backup_enabled.elasticache_cluster_backup_enabled import (
elasticache_cluster_backup_enabled,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_backup_enabled.elasticache_redis_cluster_backup_enabled import (
elasticache_redis_cluster_backup_enabled,
)
check = elasticache_cluster_backup_enabled()
check = elasticache_redis_cluster_backup_enabled()
result = check.execute()
assert len(result) == 0
@@ -62,6 +65,7 @@ class Test_elasticache_cluster_backup_enabled:
encrypted=False,
transit_encryption=False,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
elasticache_client.audit_config = {"minimum_snapshot_retention_period": 7}
@@ -72,24 +76,25 @@ class Test_elasticache_cluster_backup_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_client,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_backup_enabled.elasticache_cluster_backup_enabled import (
elasticache_cluster_backup_enabled,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_backup_enabled.elasticache_redis_cluster_backup_enabled import (
elasticache_redis_cluster_backup_enabled,
)
check = elasticache_cluster_backup_enabled()
check = elasticache_redis_cluster_backup_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Elasticache Cluster {REPLICATION_GROUP_ID} does not have automated snapshot backups enabled."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} does not have automated snapshot backups enabled."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
def test_elasticache_cluster_backup_enabled(self):
def test_elasticache_redis_cluster_backup_enabled(self):
# Mock ElastiCache Service
elasticache_client = MagicMock
elasticache_client.replication_groups = {}
@@ -103,6 +108,7 @@ class Test_elasticache_cluster_backup_enabled:
encrypted=REPLICATION_GROUP_ENCRYPTION,
transit_encryption=REPLICATION_GROUP_TRANSIT_ENCRYPTION,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
elasticache_client.audit_config = {"minimum_snapshot_retention_period": 7}
@@ -114,24 +120,25 @@ class Test_elasticache_cluster_backup_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_client,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_backup_enabled.elasticache_cluster_backup_enabled import (
elasticache_cluster_backup_enabled,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_backup_enabled.elasticache_redis_cluster_backup_enabled import (
elasticache_redis_cluster_backup_enabled,
)
check = elasticache_cluster_backup_enabled()
check = elasticache_redis_cluster_backup_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Elasticache Cluster {REPLICATION_GROUP_ID} has automated snapshot backups enabled with retention period 9 days."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} has automated snapshot backups enabled with retention period 9 days."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
def test_elasticache_cluster_backup_enabled_modified_retention(self):
def test_elasticache_redis_cluster_backup_enabled_modified_retention(self):
# Mock ElastiCache Service
elasticache_client = MagicMock
elasticache_client.replication_groups = {}
@@ -145,6 +152,7 @@ class Test_elasticache_cluster_backup_enabled:
encrypted=REPLICATION_GROUP_ENCRYPTION,
transit_encryption=REPLICATION_GROUP_TRANSIT_ENCRYPTION,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
elasticache_client.audit_config = {"minimum_snapshot_retention_period": 1}
@@ -155,19 +163,64 @@ class Test_elasticache_cluster_backup_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_client,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_backup_enabled.elasticache_cluster_backup_enabled import (
elasticache_cluster_backup_enabled,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_backup_enabled.elasticache_redis_cluster_backup_enabled import (
elasticache_redis_cluster_backup_enabled,
)
check = elasticache_cluster_backup_enabled()
check = elasticache_redis_cluster_backup_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Elasticache Cluster {REPLICATION_GROUP_ID} has automated snapshot backups enabled with retention period 3 days."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} has automated snapshot backups enabled with retention period 3 days."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
def test_elasticache_redis_cluster_backup_enabled_low_retention(self):
# Mock ElastiCache Service
elasticache_client = MagicMock
elasticache_client.replication_groups = {}
elasticache_client.replication_groups[REPLICATION_GROUP_ARN] = ReplicationGroup(
arn=REPLICATION_GROUP_ARN,
id=REPLICATION_GROUP_ID,
region=AWS_REGION_US_EAST_1,
status=REPLICATION_GROUP_STATUS,
snapshot_retention=2,
encrypted=REPLICATION_GROUP_ENCRYPTION,
transit_encryption=REPLICATION_GROUP_TRANSIT_ENCRYPTION,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
elasticache_client.audit_config = {"minimum_snapshot_retention_period": 3}
with mock.patch(
"prowler.providers.common.provider.Provider.get_global_provider",
return_value=set_mocked_aws_provider([AWS_REGION_US_EAST_1]),
), mock.patch(
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_client,
):
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_backup_enabled.elasticache_redis_cluster_backup_enabled import (
elasticache_redis_cluster_backup_enabled,
)
check = elasticache_redis_cluster_backup_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} has automated snapshot backups enabled with retention period 2 days. Recommended to increase the snapshot retention period to a minimum of 7 days."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
assert result[0].check_metadata.Severity == "low"
@@ -20,6 +20,10 @@ REPLICATION_GROUP_SNAPSHOT_RETENTION = "0"
REPLICATION_GROUP_ENCRYPTION = True
REPLICATION_GROUP_TRANSIT_ENCRYPTION = True
REPLICATION_GROUP_MULTI_AZ = "enabled"
REPLICATION_GROUP_TAGS = [
{"Key": "environment", "Value": "test"},
]
# Patch every AWS call using Boto3
make_api_call = botocore.client.BaseClient._make_api_call
@@ -40,11 +44,11 @@ class Test_elasticache_replication_group_in_transit_encryption_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_replication_group_encrypted_in_transit.elasticache_replication_group_encrypted_in_transit import (
elasticache_replication_group_encrypted_in_transit,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_in_transit_encryption_enabled.elasticache_redis_cluster_in_transit_encryption_enabled import (
elasticache_redis_cluster_in_transit_encryption_enabled,
)
check = elasticache_replication_group_encrypted_in_transit()
check = elasticache_redis_cluster_in_transit_encryption_enabled()
result = check.execute()
assert len(result) == 0
@@ -63,6 +67,7 @@ class Test_elasticache_replication_group_in_transit_encryption_enabled:
encrypted=REPLICATION_GROUP_ENCRYPTION,
transit_encryption=False,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
)
@@ -73,22 +78,23 @@ class Test_elasticache_replication_group_in_transit_encryption_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_replication_group_encrypted_in_transit.elasticache_replication_group_encrypted_in_transit import (
elasticache_replication_group_encrypted_in_transit,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_in_transit_encryption_enabled.elasticache_redis_cluster_in_transit_encryption_enabled import (
elasticache_redis_cluster_in_transit_encryption_enabled,
)
check = elasticache_replication_group_encrypted_in_transit()
check = elasticache_redis_cluster_in_transit_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Elasticache Replication Group {REPLICATION_GROUP_ID} does not have in transit encryption enabled."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} does not have in transit encryption enabled."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
def test_elasticache_replication_groups_in_transit_encryption_enabled(self):
# Mock ElastiCache Service
@@ -105,6 +111,7 @@ class Test_elasticache_replication_group_in_transit_encryption_enabled:
encrypted=REPLICATION_GROUP_ENCRYPTION,
transit_encryption=REPLICATION_GROUP_TRANSIT_ENCRYPTION,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
)
@@ -115,19 +122,20 @@ class Test_elasticache_replication_group_in_transit_encryption_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_replication_group_encrypted_in_transit.elasticache_replication_group_encrypted_in_transit import (
elasticache_replication_group_encrypted_in_transit,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_in_transit_encryption_enabled.elasticache_redis_cluster_in_transit_encryption_enabled import (
elasticache_redis_cluster_in_transit_encryption_enabled,
)
check = elasticache_replication_group_encrypted_in_transit()
check = elasticache_redis_cluster_in_transit_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Elasticache Replication Group {REPLICATION_GROUP_ID} has in transit encryption enabled."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} has in transit encryption enabled."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
@@ -20,6 +20,10 @@ REPLICATION_GROUP_SNAPSHOT_RETENTION = "0"
REPLICATION_GROUP_ENCRYPTION = True
REPLICATION_GROUP_TRANSIT_ENCRYPTION = True
REPLICATION_GROUP_MULTI_AZ = "enabled"
REPLICATION_GROUP_TAGS = [
{"Key": "environment", "Value": "test"},
]
# Patch every AWS call using Boto3
make_api_call = botocore.client.BaseClient._make_api_call
@@ -40,11 +44,11 @@ class Test_elasticache_replication_group_multi_az_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_multi_az_enabled.elasticache_cluster_multi_az_enabled import (
elasticache_cluster_multi_az_enabled,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_multi_az_enabled.elasticache_redis_cluster_multi_az_enabled import (
elasticache_redis_cluster_multi_az_enabled,
)
check = elasticache_cluster_multi_az_enabled()
check = elasticache_redis_cluster_multi_az_enabled()
result = check.execute()
assert len(result) == 0
@@ -63,6 +67,7 @@ class Test_elasticache_replication_group_multi_az_enabled:
encrypted=False,
transit_encryption=False,
multi_az="disabled",
tags=REPLICATION_GROUP_TAGS,
)
)
@@ -73,24 +78,25 @@ class Test_elasticache_replication_group_multi_az_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_multi_az_enabled.elasticache_cluster_multi_az_enabled import (
elasticache_cluster_multi_az_enabled,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_multi_az_enabled.elasticache_redis_cluster_multi_az_enabled import (
elasticache_redis_cluster_multi_az_enabled,
)
check = elasticache_cluster_multi_az_enabled()
check = elasticache_redis_cluster_multi_az_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Elasticache Cluster {REPLICATION_GROUP_ID} does not have Multi-AZ enabled."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} does not have Multi-AZ enabled."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
def test_elasticache_cluster_multi_az_enabled(self):
def test_elasticache_redis_cluster_multi_az_enabled(self):
# Mock ElastiCache Service
elasticache_service = MagicMock
elasticache_service.replication_groups = {}
@@ -105,6 +111,7 @@ class Test_elasticache_replication_group_multi_az_enabled:
encrypted=REPLICATION_GROUP_ENCRYPTION,
transit_encryption=REPLICATION_GROUP_TRANSIT_ENCRYPTION,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
)
@@ -115,19 +122,20 @@ class Test_elasticache_replication_group_multi_az_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_cluster_multi_az_enabled.elasticache_cluster_multi_az_enabled import (
elasticache_cluster_multi_az_enabled,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_multi_az_enabled.elasticache_redis_cluster_multi_az_enabled import (
elasticache_redis_cluster_multi_az_enabled,
)
check = elasticache_cluster_multi_az_enabled()
check = elasticache_redis_cluster_multi_az_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Elasticache Cluster {REPLICATION_GROUP_ID} has Multi-AZ enabled."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} has Multi-AZ enabled."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
@@ -20,6 +20,9 @@ REPLICATION_GROUP_SNAPSHOT_RETENTION = "0"
REPLICATION_GROUP_ENCRYPTION = True
REPLICATION_GROUP_TRANSIT_ENCRYPTION = True
REPLICATION_GROUP_MULTI_AZ = True
REPLICATION_GROUP_TAGS = [
{"Key": "environment", "Value": "test"},
]
# Patch every AWS call using Boto3
make_api_call = botocore.client.BaseClient._make_api_call
@@ -40,11 +43,11 @@ class Test_elasticache_replication_group_at_rest_encryption_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_replication_group_encrypted_at_rest.elasticache_replication_group_encrypted_at_rest import (
elasticache_replication_group_encrypted_at_rest,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_rest_encryption_enabled.elasticache_redis_cluster_rest_encryption_enabled import (
elasticache_redis_cluster_rest_encryption_enabled,
)
check = elasticache_replication_group_encrypted_at_rest()
check = elasticache_redis_cluster_rest_encryption_enabled()
result = check.execute()
assert len(result) == 0
@@ -63,6 +66,7 @@ class Test_elasticache_replication_group_at_rest_encryption_enabled:
encrypted=False,
transit_encryption=False,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
)
@@ -73,22 +77,23 @@ class Test_elasticache_replication_group_at_rest_encryption_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_replication_group_encrypted_at_rest.elasticache_replication_group_encrypted_at_rest import (
elasticache_replication_group_encrypted_at_rest,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_rest_encryption_enabled.elasticache_redis_cluster_rest_encryption_enabled import (
elasticache_redis_cluster_rest_encryption_enabled,
)
check = elasticache_replication_group_encrypted_at_rest()
check = elasticache_redis_cluster_rest_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "FAIL"
assert (
result[0].status_extended
== f"Elasticache Replication Group {REPLICATION_GROUP_ID} does not have at rest encryption enabled."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} does not have at rest encryption enabled."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
def test_elasticache_replication_groups_at_rest_encryption_enabled(self):
# Mock ElastiCache Service
@@ -105,6 +110,7 @@ class Test_elasticache_replication_group_at_rest_encryption_enabled:
encrypted=REPLICATION_GROUP_ENCRYPTION,
transit_encryption=REPLICATION_GROUP_TRANSIT_ENCRYPTION,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)
)
@@ -115,19 +121,20 @@ class Test_elasticache_replication_group_at_rest_encryption_enabled:
"prowler.providers.aws.services.elasticache.elasticache_service.ElastiCache",
new=elasticache_service,
):
from prowler.providers.aws.services.elasticache.elasticache_replication_group_encrypted_at_rest.elasticache_replication_group_encrypted_at_rest import (
elasticache_replication_group_encrypted_at_rest,
from prowler.providers.aws.services.elasticache.elasticache_redis_cluster_rest_encryption_enabled.elasticache_redis_cluster_rest_encryption_enabled import (
elasticache_redis_cluster_rest_encryption_enabled,
)
check = elasticache_replication_group_encrypted_at_rest()
check = elasticache_redis_cluster_rest_encryption_enabled()
result = check.execute()
assert len(result) == 1
assert result[0].status == "PASS"
assert (
result[0].status_extended
== f"Elasticache Replication Group {REPLICATION_GROUP_ID} has at rest encryption enabled."
== f"Elasticache Redis cache cluster {REPLICATION_GROUP_ID} has at rest encryption enabled."
)
assert result[0].region == AWS_REGION_US_EAST_1
assert result[0].resource_id == REPLICATION_GROUP_ID
assert result[0].resource_arn == REPLICATION_GROUP_ARN
assert result[0].resource_tags == REPLICATION_GROUP_TAGS
@@ -21,6 +21,7 @@ SUBNET_2 = "subnet-2"
ELASTICACHE_CLUSTER_NAME = "test-cluster"
ELASTICACHE_CLUSTER_ARN = f"arn:aws:elasticache:{AWS_REGION_US_EAST_1}:{AWS_ACCOUNT_NUMBER}:{ELASTICACHE_CLUSTER_NAME}"
ELASTICACHE_ENGINE = "redis"
ELASTICACHE_ENGINE_MEMCACHED = "memcached"
ELASTICACHE_CLUSTER_TAGS = [
{"Key": "environment", "Value": "test"},
@@ -33,6 +34,10 @@ REPLICATION_GROUP_SNAPSHOT_RETENTION = "0"
REPLICATION_GROUP_ENCRYPTION = True
REPLICATION_GROUP_TRANSIT_ENCRYPTION = True
REPLICATION_GROUP_MULTI_AZ = "enabled"
REPLICATION_GROUP_TAGS = [
{"Key": "environment", "Value": "test"},
]
# Mocking Access Analyzer Calls
make_api_call = botocore.client.BaseClient._make_api_call
@@ -53,6 +58,7 @@ def mock_make_api_call(self, operation_name, kwargs):
"CacheClusterId": ELASTICACHE_CLUSTER_NAME,
"CacheSubnetGroupName": SUBNET_GROUP_NAME,
"ARN": ELASTICACHE_CLUSTER_ARN,
"Engine": ELASTICACHE_ENGINE,
"SecurityGroups": [],
},
]
@@ -143,7 +149,7 @@ class Test_ElastiCache_Service:
elasticache = ElastiCache(aws_provider)
assert elasticache.audited_account == AWS_ACCOUNT_NUMBER
# Test ElastiCache Clusters
# Test Elasticache Redis cache clusters
def test_describe_cache_clusters(self):
aws_provider = set_mocked_aws_provider()
elasticache = ElastiCache(aws_provider)
@@ -154,6 +160,7 @@ class Test_ElastiCache_Service:
arn=ELASTICACHE_CLUSTER_ARN,
name=ELASTICACHE_CLUSTER_NAME,
id=ELASTICACHE_CLUSTER_NAME,
engine=ELASTICACHE_ENGINE,
region=AWS_REGION_US_EAST_1,
security_groups=[],
cache_subnet_group_id=SUBNET_GROUP_NAME,
@@ -161,7 +168,7 @@ class Test_ElastiCache_Service:
tags=ELASTICACHE_CLUSTER_TAGS,
)
# Test ElastiCache Replication Groups
# Test Elasticache Redis cache clusters
def test_describe_replication_groups(self):
aws_provider = set_mocked_aws_provider()
elasticache = ElastiCache(aws_provider)
@@ -179,4 +186,5 @@ class Test_ElastiCache_Service:
encrypted=REPLICATION_GROUP_ENCRYPTION,
transit_encryption=REPLICATION_GROUP_TRANSIT_ENCRYPTION,
multi_az=REPLICATION_GROUP_MULTI_AZ,
tags=REPLICATION_GROUP_TAGS,
)