Repository: prowler-cloud/prowler

Issue:
[Bug]: cloudwatch_log_group_retention_policy_specific_days_enabled not measuring "never expire"
### Steps to Reproduce

When having log groups in cloudwatch that are set to "never expire", the mentioned check sees it as "0 days"

### Expected behavior

Check should be able to detect the "never expire" log group retention setting

### Actual Result with Screenshots or Logs

![image](https://user-images.githubusercontent.com/49124793/234209263-caf09398-6eee-40f3-af76-2249899021b8.png)
![image](https://user-images.githubusercontent.com/49124793/234209482-7fe1abab-20dd-4982-a05c-f3b254d8e393.png)


### How did you install Prowler?

From pip package (pip install prowler)

### Environment Resource

Workstation

### OS used

WSL2 on Windows 11

### Prowler version

Prowler 3.4.0 (it is the latest version, yay!)

### Pip version

pip 22.0.2 from /usr/lib/python3/dist-packages/pip (python 3.10)

### Context

_No response_


Discussion:
Hi @blaargh, we are going to review this and we'll get back to you.

Thanks for using Prowler!

Resolving patch:
diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.py
--- a/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.py
+++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled.py
@@ -13,11 +13,17 @@ def execute(self):
             report.resource_id = log_group.name
             report.resource_arn = log_group.arn
             report.resource_tags = log_group.tags
-            if log_group.retention_days < specific_retention_days:
+            if (
+                log_group.never_expire is False
+                and log_group.retention_days < specific_retention_days
+            ):
                 report.status = "FAIL"
                 report.status_extended = f"Log Group {log_group.name} has less than {specific_retention_days} days retention period ({log_group.retention_days} days)."
             else:
                 report.status = "PASS"
-                report.status_extended = f"Log Group {log_group.name} comply with {specific_retention_days} days retention period since it has {log_group.retention_days} days."
+                if log_group.never_expire is True:
+                    report.status_extended = f"Log Group {log_group.name} comply with {specific_retention_days} days retention period since it never expires."
+                else:
+                    report.status_extended = f"Log Group {log_group.name} comply with {specific_retention_days} days retention period since it has {log_group.retention_days} days."
             findings.append(report)
         return findings
diff --git a/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py b/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py
--- a/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py
+++ b/prowler/providers/aws/services/cloudwatch/cloudwatch_service.py
@@ -152,17 +152,18 @@ def __describe_log_groups__(self, regional_client):
                     if not self.audit_resources or (
                         is_resource_filtered(log_group["arn"], self.audit_resources)
                     ):
-                        kms = None
-                        retention_days = 0
-                        if "kmsKeyId" in log_group:
-                            kms = log_group["kmsKeyId"]
-                        if "retentionInDays" in log_group:
-                            retention_days = log_group["retentionInDays"]
+                        never_expire = False
+                        kms = log_group.get("kmsKeyId")
+                        retention_days = log_group.get("retentionInDays")
+                        if not retention_days:
+                            never_expire = True
+                            retention_days = 9999
                         self.log_groups.append(
                             LogGroup(
                                 arn=log_group["arn"],
                                 name=log_group["logGroupName"],
                                 retention_days=retention_days,
+                                never_expire=never_expire,
                                 kms_id=kms,
                                 region=regional_client.region,
                             )
@@ -240,6 +241,7 @@ class LogGroup(BaseModel):
     arn: str
     name: str
     retention_days: int
+    never_expire: bool
     kms_id: Optional[str]
     region: str
     log_streams: dict[


Test patch:
diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled_test.py
--- a/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled_test.py
+++ b/tests/providers/aws/services/cloudwatch/cloudwatch_log_group_retention_policy_specific_days_enabled/cloudwatch_log_group_retention_policy_specific_days_enabled_test.py
@@ -66,7 +66,7 @@ def test_cloudwatch_no_log_groups(self):
             assert len(result) == 0
 
     @mock_logs
-    def test_cloudwatch_log_group_without_retention_days(self):
+    def test_cloudwatch_log_group_without_retention_days_never_expires(self):
         # Generate Logs Client
         logs_client = client("logs", region_name=AWS_REGION)
         # Request Logs group
@@ -103,12 +103,17 @@ def test_cloudwatch_log_group_without_retention_days(self):
             result = check.execute()
 
             assert len(result) == 1
-            assert result[0].status == "FAIL"
+            assert result[0].status == "PASS"
             assert (
                 result[0].status_extended
-                == "Log Group test has less than 365 days retention period (0 days)."
+                == "Log Group test comply with 365 days retention period since it never expires."
             )
             assert result[0].resource_id == "test"
+            assert (
+                result[0].resource_arn
+                == f"arn:aws:logs:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:log-group:test"
+            )
+            assert result[0].region == AWS_REGION
 
     @mock_logs
     def test_cloudwatch_log_group_with_compliant_retention_days(self):
@@ -155,6 +160,11 @@ def test_cloudwatch_log_group_with_compliant_retention_days(self):
                 == "Log Group test comply with 365 days retention period since it has 400 days."
             )
             assert result[0].resource_id == "test"
+            assert (
+                result[0].resource_arn
+                == f"arn:aws:logs:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:log-group:test"
+            )
+            assert result[0].region == AWS_REGION
 
     @mock_logs
     def test_cloudwatch_log_group_with_no_compliant_retention_days(self):
@@ -201,3 +211,8 @@ def test_cloudwatch_log_group_with_no_compliant_retention_days(self):
                 == "Log Group test has less than 365 days retention period (7 days)."
             )
             assert result[0].resource_id == "test"
+            assert (
+                result[0].resource_arn
+                == f"arn:aws:logs:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:log-group:test"
+            )
+            assert result[0].region == AWS_REGION
diff --git a/tests/providers/aws/services/cloudwatch/cloudwatch_service_test.py b/tests/providers/aws/services/cloudwatch/cloudwatch_service_test.py
--- a/tests/providers/aws/services/cloudwatch/cloudwatch_service_test.py
+++ b/tests/providers/aws/services/cloudwatch/cloudwatch_service_test.py
@@ -195,6 +195,34 @@ def test__describe_log_groups__(self):
         assert logs.log_groups[0].name == "/log-group/test"
         assert logs.log_groups[0].retention_days == 400
         assert logs.log_groups[0].kms_id == "test_kms_id"
+        assert not logs.log_groups[0].never_expire
+        assert logs.log_groups[0].region == AWS_REGION
+        assert logs.log_groups[0].tags == [
+            {"tag_key_1": "tag_value_1", "tag_key_2": "tag_value_2"}
+        ]
+
+    @mock_logs
+    def test__describe_log_groups__never_expire(self):
+        # Logs client for this test class
+        logs_client = client("logs", region_name=AWS_REGION)
+        logs_client.create_log_group(
+            logGroupName="/log-group/test",
+            kmsKeyId="test_kms_id",
+            tags={"tag_key_1": "tag_value_1", "tag_key_2": "tag_value_2"},
+        )
+
+        audit_info = self.set_mocked_audit_info()
+        logs = Logs(audit_info)
+        assert len(logs.log_groups) == 1
+        assert (
+            logs.log_groups[0].arn
+            == f"arn:aws:logs:{AWS_REGION}:{AWS_ACCOUNT_NUMBER}:log-group:/log-group/test"
+        )
+        assert logs.log_groups[0].name == "/log-group/test"
+        assert logs.log_groups[0].never_expire
+        # Since it never expires we don't use the retention_days
+        assert logs.log_groups[0].retention_days == 9999
+        assert logs.log_groups[0].kms_id == "test_kms_id"
         assert logs.log_groups[0].region == AWS_REGION
         assert logs.log_groups[0].tags == [
             {"tag_key_1": "tag_value_1", "tag_key_2": "tag_value_2"}