feat(elasticbeanstalk): Add new service ElasticBeanstalk (#5322)

Co-authored-by: Sergio <sergio@prowler.com>
This commit is contained in:
Mario Rodriguez Lopez
2024-10-09 15:29:19 +02:00
committed by GitHub
parent 0c149461b3
commit 16191a7b15
4 changed files with 277 additions and 0 deletions
@@ -0,0 +1,6 @@
from prowler.providers.aws.services.elasticbeanstalk.elasticbeanstalk_service import (
ElasticBeanstalk,
)
from prowler.providers.common.provider import Provider
elasticbeanstalk_client = ElasticBeanstalk(Provider.get_global_provider())
@@ -0,0 +1,106 @@
from typing import Optional
from pydantic import BaseModel
from prowler.lib.logger import logger
from prowler.lib.scan_filters.scan_filters import is_resource_filtered
from prowler.providers.aws.lib.service.service import AWSService
class ElasticBeanstalk(AWSService):
def __init__(self, provider):
# Call AWSService's __init__
super().__init__(__class__.__name__, provider)
self.environments = {}
self.__threading_call__(self._describe_environments)
self.__threading_call__(
self._describe_configuration_settings, self.environments.values()
)
self.__threading_call__(
self._list_tags_for_resource, self.environments.values()
)
def _describe_environments(self, regional_client):
logger.info("ElasticBeanstalk - Describing environments...")
try:
describe_environment_paginator = regional_client.get_paginator(
"describe_environments"
)
for page in describe_environment_paginator.paginate():
for environment in page["Environments"]:
environment_arn = environment["EnvironmentArn"]
if not self.audit_resources or (
is_resource_filtered(environment_arn, self.audit_resources)
):
self.environments[environment_arn] = Environment(
id=environment["EnvironmentId"],
arn=environment_arn,
application_name=environment["ApplicationName"],
name=environment["EnvironmentName"],
region=regional_client.region,
)
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def _describe_configuration_settings(self, environment):
logger.info("ElasticBeanstalk - Describing configuration settings...")
try:
regional_client = self.regional_clients[environment.region]
configuration_settings = regional_client.describe_configuration_settings(
ApplicationName=environment.application_name,
EnvironmentName=environment.name,
)
option_settings = configuration_settings["ConfigurationSettings"][0].get(
"OptionSettings", {}
)
for option in option_settings:
if (
option["Namespace"] == "aws:elasticbeanstalk:healthreporting:system"
and option["OptionName"] == "SystemType"
):
environment.health_reporting = option.get("Value", "basic")
elif (
option["Namespace"] == "aws:elasticbeanstalk:managedactions"
and option["OptionName"] == "ManagedActionsEnabled"
):
environment.managed_platform_updates = option.get("Value", "false")
elif (
option["Namespace"] == "aws:elasticbeanstalk:cloudwatch:logs"
and option["OptionName"] == "StreamLogs"
):
environment.cloudwatch_stream_logs = option.get("Value", "false")
except Exception as error:
logger.error(
f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}"
)
def _list_tags_for_resource(self, resource: any):
logger.info("ElasticBeanstalk - List Tags...")
try:
regional_client = self.regional_clients[resource.region]
response = regional_client.list_tags_for_resource(ResourceArn=resource.arn)[
"ResourceTags"
]
resource.tags = response
except Exception as error:
logger.error(
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}"
)
class Environment(BaseModel):
id: str
name: str
arn: str
region: str
application_name: str
health_reporting: Optional[str]
managed_platform_updates: Optional[str]
cloudwatch_stream_logs: Optional[str]
tags: Optional[list] = []
@@ -0,0 +1,165 @@
from unittest.mock import patch
import botocore
from boto3 import client
from moto import mock_aws
from prowler.providers.aws.services.elasticbeanstalk.elasticbeanstalk_service import (
ElasticBeanstalk,
)
from tests.providers.aws.utils import AWS_REGION_EU_WEST_1, set_mocked_aws_provider
# Mocking Access Analyzer Calls
make_api_call = botocore.client.BaseClient._make_api_call
def mock_make_api_call(self, operation_name, kwarg):
if operation_name == "DescribeConfigurationSettings":
return {
"ConfigurationSettings": [
{
"OptionSettings": [
{
"Namespace": "aws:elasticbeanstalk:healthreporting:system",
"OptionName": "SystemType",
"Value": "enhanced",
},
{
"Namespace": "aws:elasticbeanstalk:managedactions",
"OptionName": "ManagedActionsEnabled",
"Value": "true",
},
{
"Namespace": "aws:elasticbeanstalk:cloudwatch:logs",
"OptionName": "StreamLogs",
"Value": "true",
},
],
}
]
}
return make_api_call(self, operation_name, kwarg)
# Mock generate_regional_clients()
def mock_generate_regional_clients(provider, service):
regional_client = provider._session.current_session.client(
service, region_name=AWS_REGION_EU_WEST_1
)
regional_client.region = AWS_REGION_EU_WEST_1
return {AWS_REGION_EU_WEST_1: regional_client}
@patch(
"prowler.providers.aws.aws_provider.AwsProvider.generate_regional_clients",
new=mock_generate_regional_clients,
)
@patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call)
class Test_ElasticBeanstalk_Service:
# Test ElasticBeanstalk Client
@mock_aws
def test_get_client(self):
elasticbeanstalk = ElasticBeanstalk(set_mocked_aws_provider())
assert (
elasticbeanstalk.regional_clients[AWS_REGION_EU_WEST_1].__class__.__name__
== "ElasticBeanstalk"
)
# Test ElasticBeanstalk Session
@mock_aws
def test__get_session__(self):
elasticbeanstalk = ElasticBeanstalk(set_mocked_aws_provider())
assert elasticbeanstalk.session.__class__.__name__ == "Session"
# Test ElasticBeanstalk Service
@mock_aws
def test__get_service__(self):
elasticbeanstalk = ElasticBeanstalk(set_mocked_aws_provider())
assert elasticbeanstalk.service == "elasticbeanstalk"
# Test _describe_environments
@mock_aws
def test_describe_environments(self):
# Create ElasticBeanstalk app and env
elasticbeanstalk_client = client(
"elasticbeanstalk", region_name=AWS_REGION_EU_WEST_1
)
elasticbeanstalk_client.create_application(ApplicationName="test-app")
environment = elasticbeanstalk_client.create_environment(
ApplicationName="test-app",
EnvironmentName="test-env",
)
# ElasticBeanstalk Class
elasticbeanstalk = ElasticBeanstalk(set_mocked_aws_provider())
assert len(elasticbeanstalk.environments) == 1
assert (
elasticbeanstalk.environments[environment["EnvironmentArn"]].id
== environment["EnvironmentId"]
)
assert (
elasticbeanstalk.environments[environment["EnvironmentArn"]].name
== "test-env"
)
assert (
elasticbeanstalk.environments[environment["EnvironmentArn"]].region
== AWS_REGION_EU_WEST_1
)
assert (
elasticbeanstalk.environments[
environment["EnvironmentArn"]
].application_name
== "test-app"
)
# Test _describe_configuration_settings
@mock_aws
def test_describe_configuration_settings(self):
# Create ElasticBeanstalk app and env
elasticbeanstalk_client = client(
"elasticbeanstalk", region_name=AWS_REGION_EU_WEST_1
)
elasticbeanstalk_client.create_application(ApplicationName="test-app")
environment = elasticbeanstalk_client.create_environment(
ApplicationName="test-app",
EnvironmentName="test-env",
)
# ElasticBeanstalk Class
elasticbeanstalk = ElasticBeanstalk(set_mocked_aws_provider())
assert (
elasticbeanstalk.environments[
environment["EnvironmentArn"]
].health_reporting
== "enhanced"
)
assert (
elasticbeanstalk.environments[
environment["EnvironmentArn"]
].managed_platform_updates
== "true"
)
assert (
elasticbeanstalk.environments[
environment["EnvironmentArn"]
].cloudwatch_stream_logs
== "true"
)
@mock_aws
def test_list_tags_for_resource(self):
# Create ElasticBeanstalk app and env
elasticbeanstalk_client = client(
"elasticbeanstalk", region_name=AWS_REGION_EU_WEST_1
)
elasticbeanstalk_client.create_application(ApplicationName="test-app")
environment = elasticbeanstalk_client.create_environment(
ApplicationName="test-app",
EnvironmentName="test-env",
Tags=[{"Key": "test-key", "Value": "test-value"}],
)
# ElasticBeanstalk Class
elasticbeanstalk = ElasticBeanstalk(set_mocked_aws_provider())
assert elasticbeanstalk.environments[environment["EnvironmentArn"]].tags == [
{"Key": "test-key", "Value": "test-value"}
]