diff --git a/prowler/providers/aws/services/ec2/ec2_launch_template_no_secrets/ec2_launch_template_no_secrets.py b/prowler/providers/aws/services/ec2/ec2_launch_template_no_secrets/ec2_launch_template_no_secrets.py index 23e75af13e..b78ecc2284 100644 --- a/prowler/providers/aws/services/ec2/ec2_launch_template_no_secrets/ec2_launch_template_no_secrets.py +++ b/prowler/providers/aws/services/ec2/ec2_launch_template_no_secrets/ec2_launch_template_no_secrets.py @@ -23,10 +23,10 @@ class ec2_launch_template_no_secrets(Check): versions_with_secrets = [] for version in template.versions: - if "UserData" not in version.template_data: + if not version.template_data.user_data: continue - user_data = b64decode(version.template_data["UserData"]) + user_data = b64decode(version.template_data.user_data) try: if user_data[0:2] == b"\x1f\x8b": # GZIP magic number diff --git a/prowler/providers/aws/services/ec2/ec2_service.py b/prowler/providers/aws/services/ec2/ec2_service.py index aa1a730390..c90943b932 100644 --- a/prowler/providers/aws/services/ec2/ec2_service.py +++ b/prowler/providers/aws/services/ec2/ec2_service.py @@ -1,5 +1,6 @@ from datetime import datetime -from typing import Optional +from ipaddress import IPv4Address, IPv6Address, ip_address +from typing import Optional, Union from botocore.client import ClientError from pydantic import BaseModel @@ -28,7 +29,7 @@ class EC2(AWSService): self.regions_with_snapshots = {} self.__threading_call__(self._describe_snapshots) self.__threading_call__(self._determine_public_snapshots, self.snapshots) - self.network_interfaces = [] + self.network_interfaces = {} self.__threading_call__(self._describe_network_interfaces) self.images = [] self.__threading_call__(self._describe_images) @@ -47,7 +48,7 @@ class EC2(AWSService): self.launch_templates = [] self.__threading_call__(self._describe_launch_templates) self.__threading_call__( - self._get_launch_template_versions, self.launch_templates + self._describe_launch_template_versions, self.launch_templates ) self.vpn_endpoints = {} self.__threading_call__(self._describe_vpn_endpoints) @@ -235,8 +236,34 @@ class EC2(AWSService): ) for page in describe_network_interfaces_paginator.paginate(): for interface in page["NetworkInterfaces"]: - eni = NetworkInterface( - id=interface["NetworkInterfaceId"], + id = interface["NetworkInterfaceId"] + public_ip_addresses = [] + + # Check for public IPs in the 'PrivateIpAddresses' block + for private_ip_info in interface.get("PrivateIpAddresses", []): + private_association = private_ip_info.get("Association", {}) + public_ip_str = private_association.get("PublicIp") + if public_ip_str: + public_ip = ip_address(public_ip_str) + if public_ip.is_global: + public_ip_addresses.append(public_ip) + + private_ip_str = private_ip_info.get("PrivateIpAddress") + if private_ip_str: + private_ip = ip_address(private_ip_str) + if private_ip.is_global: + public_ip_addresses.append(private_ip) + + # Check for public IPs in the 'IPv6Addresses' block + for ipv6_info in interface.get("Ipv6Addresses", []): + ipv6_address_str = ipv6_info.get("Ipv6Address") + if ipv6_address_str: + ipv6_address = ip_address(ipv6_address_str) + if ipv6_address.is_global: + public_ip_addresses.append(ipv6_address) + + self.network_interfaces[id] = NetworkInterface( + id=id, association=interface.get("Association", {}), attachment=interface.get("Attachment", {}), private_ip=interface.get("PrivateIpAddress"), @@ -245,8 +272,8 @@ class EC2(AWSService): vpc_id=interface["VpcId"], region=regional_client.region, tags=interface.get("TagSet"), + public_ip_addresses=public_ip_addresses, ) - self.network_interfaces.append(eni) # Add Network Interface to Security Group # 'Groups': [ # { @@ -255,7 +282,7 @@ class EC2(AWSService): # }, # ], self._add_network_interfaces_to_security_groups( - eni, interface.get("Groups", []) + self.network_interfaces[id], interface.get("Groups", []) ) except Exception as error: @@ -478,6 +505,7 @@ class EC2(AWSService): arn=template_arn, region=regional_client.region, versions=[], + tags=template.get("Tags"), ) ) @@ -486,7 +514,7 @@ class EC2(AWSService): f"{regional_client.region} -- {error.__class__.__name__}[{error.__traceback__.tb_lineno}]: {error}" ) - def _get_launch_template_versions(self, launch_template): + def _describe_launch_template_versions(self, launch_template): try: regional_client = self.regional_clients[launch_template.region] describe_launch_template_versions_paginator = regional_client.get_paginator( @@ -497,10 +525,26 @@ class EC2(AWSService): LaunchTemplateId=launch_template.id ): for template_version in page["LaunchTemplateVersions"]: + enis = [] + associate_public_ip = False + for eni in template_version["LaunchTemplateData"].get( + "NetworkInterfaces", [] + ): + network_interface_id = eni.get("NetworkInterfaceId") + if network_interface_id in self.network_interfaces: + enis.append(self.network_interfaces[network_interface_id]) + if eni.get("AssociatePublicIpAddress", False): + associate_public_ip = True launch_template.versions.append( LaunchTemplateVersion( version_number=template_version["VersionNumber"], - template_data=template_version["LaunchTemplateData"], + template_data=TemplateData( + user_data=template_version["LaunchTemplateData"].get( + "UserData", "" + ), + network_interfaces=enis, + associate_public_ip_address=associate_public_ip, + ), ) ) @@ -614,6 +658,7 @@ class NetworkInterface(BaseModel): association: dict attachment: dict private_ip: Optional[str] + public_ip_addresses: list[Union[IPv4Address, IPv6Address]] type: str subnet_id: str vpc_id: str @@ -678,9 +723,15 @@ class InstanceMetadataDefaults(BaseModel): region: str +class TemplateData(BaseModel): + user_data: str + network_interfaces: Optional[list[NetworkInterface]] + associate_public_ip_address: Optional[bool] + + class LaunchTemplateVersion(BaseModel): version_number: int - template_data: dict + template_data: TemplateData class LaunchTemplate(BaseModel): @@ -689,6 +740,7 @@ class LaunchTemplate(BaseModel): arn: str region: str versions: list[LaunchTemplateVersion] = [] + tags: Optional[list] = [] class VpnEndpoint(BaseModel): diff --git a/prowler/providers/aws/services/route53/route53_dangling_ip_subdomain_takeover/route53_dangling_ip_subdomain_takeover.py b/prowler/providers/aws/services/route53/route53_dangling_ip_subdomain_takeover/route53_dangling_ip_subdomain_takeover.py index 2ef1d53fc0..daa54e5562 100644 --- a/prowler/providers/aws/services/route53/route53_dangling_ip_subdomain_takeover/route53_dangling_ip_subdomain_takeover.py +++ b/prowler/providers/aws/services/route53/route53_dangling_ip_subdomain_takeover/route53_dangling_ip_subdomain_takeover.py @@ -19,7 +19,7 @@ class route53_dangling_ip_subdomain_takeover(Check): public_ips = [] public_ips.extend([eip.public_ip for eip in ec2_client.elastic_ips]) # Add public IPs from Network Interfaces - for network_interface in ec2_client.network_interfaces: + for network_interface in ec2_client.network_interfaces.values(): if ( network_interface.association and network_interface.association.get("PublicIp") diff --git a/tests/providers/aws/services/ec2/ec2_launch_template_no_secrets/ec2_launch_template_no_secrets_test.py b/tests/providers/aws/services/ec2/ec2_launch_template_no_secrets/ec2_launch_template_no_secrets_test.py index 7e889fbc1c..9f75048dd2 100644 --- a/tests/providers/aws/services/ec2/ec2_launch_template_no_secrets/ec2_launch_template_no_secrets_test.py +++ b/tests/providers/aws/services/ec2/ec2_launch_template_no_secrets/ec2_launch_template_no_secrets_test.py @@ -3,15 +3,50 @@ from os import path from pathlib import Path from unittest import mock +import botocore from boto3 import client from moto import mock_aws from prowler.config.config import encoding_format_utf_8 +from prowler.providers.aws.services.ec2.ec2_service import ( + LaunchTemplate, + LaunchTemplateVersion, + TemplateData, +) from tests.providers.aws.utils import AWS_REGION_US_EAST_1, set_mocked_aws_provider ACTUAL_DIRECTORY = Path(path.dirname(path.realpath(__file__))) FIXTURES_DIR_NAME = "fixtures" +make_api_call = botocore.client.BaseClient._make_api_call + + +def mock_make_api_call(self, operation_name, kwarg): + if operation_name == "DescribeLaunchTemplateVersions": + return { + "LaunchTemplateVersions": [ + { + "VersionNumber": 123, + "LaunchTemplateData": { + "UserData": b64encode( + "DB_PASSWORD=foobar123".encode(encoding_format_utf_8) + ).decode(encoding_format_utf_8), + "NetworkInterfaces": [{"AssociatePublicIpAddress": True}], + }, + } + ] + } + elif operation_name == "DescribeLaunchTemplates": + return { + "LaunchTemplates": [ + { + "LaunchTemplateName": "tester1", + "LaunchTemplateId": "lt-1234567890", + } + ] + } + return make_api_call(self, operation_name, kwarg) + class Test_ec2_launch_template_no_secrets: @mock_aws @@ -88,33 +123,8 @@ class Test_ec2_launch_template_no_secrets: assert result[0].resource_id == launch_template_id assert result[0].region == AWS_REGION_US_EAST_1 - @mock_aws + @mock.patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) def test_one_launch_template_with_secrets(self): - launch_template_name = "tester" - - f = open( - f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture", - "rb", - ) - secrets = f.read() - - ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1) - ec2_client.create_launch_template( - LaunchTemplateName=launch_template_name, - VersionDescription="Launch Template with secrets", - LaunchTemplateData={ - "InstanceType": "t1.micro", - "UserData": b64encode(secrets).decode(encoding_format_utf_8), - }, - ) - - launch_template_version = ec2_client.describe_launch_template_versions( - LaunchTemplateName=launch_template_name - )["LaunchTemplateVersions"][0]["VersionNumber"] - - launch_template_id = ec2_client.describe_launch_templates()["LaunchTemplates"][ - 0 - ]["LaunchTemplateId"] from prowler.providers.aws.services.ec2.ec2_service import EC2 @@ -139,14 +149,18 @@ class Test_ec2_launch_template_no_secrets: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name} in template versions: {launch_template_version}." + == "Potential secret found in User Data for EC2 Launch Template tester1 in template versions: 123." ) - assert result[0].resource_id == launch_template_id + assert result[0].resource_id == "lt-1234567890" assert result[0].region == AWS_REGION_US_EAST_1 - @mock_aws def test_one_launch_template_with_secrets_in_multiple_versions(self): + ec2_client = mock.MagicMock() launch_template_name = "tester" + launch_template_id = "lt-1234567890" + launch_template_arn = ( + f"arn:aws:ec2:us-east-1:123456789012:launch-template/{launch_template_id}" + ) f = open( f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture", @@ -154,46 +168,38 @@ class Test_ec2_launch_template_no_secrets: ) secrets = f.read() - ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1) - ec2_client.create_launch_template( - LaunchTemplateName=launch_template_name, - VersionDescription="Launch Template with secrets", - LaunchTemplateData={ - "InstanceType": "t1.micro", - "UserData": b64encode(secrets).decode(encoding_format_utf_8), - }, + launch_template_data = TemplateData( + user_data=b64encode(secrets).decode(encoding_format_utf_8), + associate_public_ip_address=True, ) - ec2_client.create_launch_template_version( - LaunchTemplateName=launch_template_name, - VersionDescription="Second Launch Template version with secrets", - LaunchTemplateData={ - "InstanceType": "t1.micro", - "UserData": b64encode(secrets).decode(encoding_format_utf_8), - }, - ) - - launch_template_id = ec2_client.describe_launch_templates()["LaunchTemplates"][ - 0 - ]["LaunchTemplateId"] - - launch_template_version_numbers = [ - str(v["VersionNumber"]) - for v in ec2_client.describe_launch_template_versions( - LaunchTemplateName=launch_template_name - )["LaunchTemplateVersions"] + launch_template_versions = [ + LaunchTemplateVersion( + version_number=1, + template_data=launch_template_data, + ), + LaunchTemplateVersion( + version_number=2, + template_data=launch_template_data, + ), ] - from prowler.providers.aws.services.ec2.ec2_service import EC2 + launch_template = LaunchTemplate( + name=launch_template_name, + id=launch_template_id, + arn=launch_template_arn, + region=AWS_REGION_US_EAST_1, + versions=launch_template_versions, + ) - aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + ec2_client.launch_templates = [launch_template] with mock.patch( "prowler.providers.common.provider.Provider.get_global_provider", - return_value=aws_provider, + return_value=ec2_client, ), mock.patch( "prowler.providers.aws.services.ec2.ec2_launch_template_no_secrets.ec2_launch_template_no_secrets.ec2_client", - new=EC2(aws_provider), + new=ec2_client, ): # Test Check from prowler.providers.aws.services.ec2.ec2_launch_template_no_secrets.ec2_launch_template_no_secrets import ( @@ -207,14 +213,18 @@ class Test_ec2_launch_template_no_secrets: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name} in template versions: {', '.join(launch_template_version_numbers)}." + == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name} in template versions: 1, 2." ) assert result[0].resource_id == launch_template_id assert result[0].region == AWS_REGION_US_EAST_1 - @mock_aws def test_one_launch_template_with_secrets_in_single_version(self): + ec2_client = mock.MagicMock() launch_template_name = "tester" + launch_template_id = "lt-1234567890" + launch_template_arn = ( + f"arn:aws:ec2:us-east-1:123456789012:launch-template/{launch_template_id}" + ) f = open( f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture", @@ -222,42 +232,44 @@ class Test_ec2_launch_template_no_secrets: ) secrets = f.read() - ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1) - ec2_client.create_launch_template( - LaunchTemplateName=launch_template_name, - VersionDescription="Launch Template with secrets", - LaunchTemplateData={ - "InstanceType": "t1.micro", - "UserData": b64encode(secrets).decode(encoding_format_utf_8), - }, + launch_template_data_secrets = TemplateData( + user_data=b64encode(secrets).decode(encoding_format_utf_8), + associate_public_ip_address=True, + ) + launch_template_data_no_secrets = TemplateData( + user_data=b64encode("sinsecretos".encode(encoding_format_utf_8)).decode( + encoding_format_utf_8 + ), + associate_public_ip_address=True, ) - version_with_secrets = ec2_client.describe_launch_template_versions( - LaunchTemplateName=launch_template_name, - )["LaunchTemplateVersions"][0]["VersionNumber"] + launch_template_versions = [ + LaunchTemplateVersion( + version_number=1, + template_data=launch_template_data_secrets, + ), + LaunchTemplateVersion( + version_number=2, + template_data=launch_template_data_no_secrets, + ), + ] - ec2_client.create_launch_template_version( - LaunchTemplateName=launch_template_name, - VersionDescription="Second Launch Template version without secrets", - LaunchTemplateData={ - "InstanceType": "t1.micro", - }, + launch_template = LaunchTemplate( + name=launch_template_name, + id=launch_template_id, + arn=launch_template_arn, + region=AWS_REGION_US_EAST_1, + versions=launch_template_versions, ) - launch_template_id = ec2_client.describe_launch_templates()["LaunchTemplates"][ - 0 - ]["LaunchTemplateId"] - - from prowler.providers.aws.services.ec2.ec2_service import EC2 - - aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + ec2_client.launch_templates = [launch_template] with mock.patch( "prowler.providers.common.provider.Provider.get_global_provider", - return_value=aws_provider, + return_value=ec2_client, ), mock.patch( "prowler.providers.aws.services.ec2.ec2_launch_template_no_secrets.ec2_launch_template_no_secrets.ec2_client", - new=EC2(aws_provider), + new=ec2_client, ): # Test Check from prowler.providers.aws.services.ec2.ec2_launch_template_no_secrets.ec2_launch_template_no_secrets import ( @@ -271,14 +283,18 @@ class Test_ec2_launch_template_no_secrets: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name} in template versions: {version_with_secrets}." + == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name} in template versions: 1." ) assert result[0].resource_id == launch_template_id assert result[0].region == AWS_REGION_US_EAST_1 - @mock_aws def test_one_launch_template_with_secrets_gzip(self): + ec2_client = mock.MagicMock() launch_template_name = "tester" + launch_template_id = "lt-1234567890" + launch_template_arn = ( + f"arn:aws:ec2:us-east-1:123456789012:launch-template/{launch_template_id}" + ) f = open( f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture.gz", @@ -286,34 +302,34 @@ class Test_ec2_launch_template_no_secrets: ) secrets = f.read() - ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1) - ec2_client.create_launch_template( - LaunchTemplateName=launch_template_name, - VersionDescription="Launch Template with secrets", - LaunchTemplateData={ - "InstanceType": "t1.micro", - "UserData": b64encode(secrets).decode(encoding_format_utf_8), - }, + launch_template_data = TemplateData( + user_data=b64encode(secrets).decode(encoding_format_utf_8), + associate_public_ip_address=True, ) - launch_template_version = ec2_client.describe_launch_template_versions( - LaunchTemplateName=launch_template_name - )["LaunchTemplateVersions"][0]["VersionNumber"] + launch_template_versions = [ + LaunchTemplateVersion( + version_number=1, + template_data=launch_template_data, + ), + ] - launch_template_id = ec2_client.describe_launch_templates()["LaunchTemplates"][ - 0 - ]["LaunchTemplateId"] + launch_template = LaunchTemplate( + name=launch_template_name, + id=launch_template_id, + arn=launch_template_arn, + region=AWS_REGION_US_EAST_1, + versions=launch_template_versions, + ) - from prowler.providers.aws.services.ec2.ec2_service import EC2 - - aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + ec2_client.launch_templates = [launch_template] with mock.patch( "prowler.providers.common.provider.Provider.get_global_provider", - return_value=aws_provider, + return_value=ec2_client, ), mock.patch( "prowler.providers.aws.services.ec2.ec2_launch_template_no_secrets.ec2_launch_template_no_secrets.ec2_client", - new=EC2(aws_provider), + new=ec2_client, ): # Test Check from prowler.providers.aws.services.ec2.ec2_launch_template_no_secrets.ec2_launch_template_no_secrets import ( @@ -327,7 +343,7 @@ class Test_ec2_launch_template_no_secrets: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name} in template versions: {launch_template_version}." + == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name} in template versions: 1." ) assert result[0].resource_id == launch_template_id assert result[0].region == AWS_REGION_US_EAST_1 @@ -377,10 +393,19 @@ class Test_ec2_launch_template_no_secrets: assert result[0].resource_id == launch_template_id assert result[0].region == AWS_REGION_US_EAST_1 - @mock_aws + @mock.patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) def test_two_launch_templates_one_template_with_secrets(self): - launch_template_name_with_secrets = "tester1" - launch_template_name_without_secrets = "tester2" + ec2_client = mock.MagicMock() + launch_template_name1 = "tester-secrets" + launch_template_name2 = "tester-no-secrets" + launch_template_id1 = "lt-1234567890" + launch_template_id2 = "lt-0987654321" + launch_template_arn1 = ( + f"arn:aws:ec2:us-east-1:123456789012:launch-template/{launch_template_id1}" + ) + launch_template_arn2 = ( + f"arn:aws:ec2:us-east-1:123456789012:launch-template/{launch_template_id2}" + ) f = open( f"{ACTUAL_DIRECTORY}/{FIXTURES_DIR_NAME}/fixture", @@ -388,43 +413,56 @@ class Test_ec2_launch_template_no_secrets: ) secrets = f.read() - ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1) - ec2_client.create_launch_template( - LaunchTemplateName=launch_template_name_with_secrets, - VersionDescription="Launch Template with secrets", - LaunchTemplateData={ - "InstanceType": "t1.micro", - "UserData": b64encode(secrets).decode(encoding_format_utf_8), - }, + launch_template_data_secrets = TemplateData( + user_data=b64encode(secrets).decode(encoding_format_utf_8), + associate_public_ip_address=True, + ) + launch_template_data_no_secrets = TemplateData( + user_data=b64encode("sinsecretos".encode(encoding_format_utf_8)).decode( + encoding_format_utf_8 + ), + associate_public_ip_address=True, ) - launch_template_id = ec2_client.describe_launch_templates()["LaunchTemplates"][ - 0 - ]["LaunchTemplateId"] - template_version_with_secrets = ec2_client.describe_launch_template_versions( - LaunchTemplateName=launch_template_name_with_secrets - )["LaunchTemplateVersions"][0]["VersionNumber"] + launch_template_secrets_version = [ + LaunchTemplateVersion( + version_number=1, + template_data=launch_template_data_secrets, + ), + ] + launch_template_no_secret_version = [ + LaunchTemplateVersion( + version_number=2, + template_data=launch_template_data_no_secrets, + ), + ] - # Create second launch template with no secret in UserData (NOT a new version) - ec2_client.create_launch_template( - LaunchTemplateName=launch_template_name_without_secrets, - VersionDescription="Launch Template without secrets", - LaunchTemplateData={ - "InstanceType": "t1.micro", - "UserData": b64encode(b"Test").decode(encoding_format_utf_8), - }, + launch_template_secrets = LaunchTemplate( + name=launch_template_name1, + id=launch_template_id1, + arn=launch_template_arn1, + region=AWS_REGION_US_EAST_1, + versions=launch_template_secrets_version, + ) + launch_template_no_secrets = LaunchTemplate( + name=launch_template_name2, + id=launch_template_id2, + arn=launch_template_arn2, + region=AWS_REGION_US_EAST_1, + versions=launch_template_no_secret_version, ) - from prowler.providers.aws.services.ec2.ec2_service import EC2 - - aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) + ec2_client.launch_templates = [ + launch_template_secrets, + launch_template_no_secrets, + ] with mock.patch( "prowler.providers.common.provider.Provider.get_global_provider", - return_value=aws_provider, + return_value=ec2_client, ), mock.patch( "prowler.providers.aws.services.ec2.ec2_launch_template_no_secrets.ec2_launch_template_no_secrets.ec2_client", - new=EC2(aws_provider), + new=ec2_client, ): # Test Check from prowler.providers.aws.services.ec2.ec2_launch_template_no_secrets.ec2_launch_template_no_secrets import ( @@ -438,12 +476,18 @@ class Test_ec2_launch_template_no_secrets: assert result[0].status == "FAIL" assert ( result[0].status_extended - == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name_with_secrets} in template versions: {template_version_with_secrets}." + == f"Potential secret found in User Data for EC2 Launch Template {launch_template_name1} in template versions: 1." ) - assert result[0].resource_id == launch_template_id + assert result[0].resource_id == launch_template_id1 assert result[0].region == AWS_REGION_US_EAST_1 assert result[1].status == "PASS" + assert ( + result[1].status_extended + == f"No secrets found in User Data of any version for EC2 Launch Template {launch_template_name2}." + ) + assert result[1].resource_id == launch_template_id2 + assert result[1].region == AWS_REGION_US_EAST_1 @mock_aws def test_one_launch_template_with_unicode_error(self): diff --git a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port_test.py b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port_test.py index 0838994fe5..4e3ea6b636 100644 --- a/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port_test.py +++ b/tests/providers/aws/services/ec2/ec2_securitygroup_allow_ingress_from_internet_to_any_port/ec2_securitygroup_allow_ingress_from_internet_to_any_port_test.py @@ -204,6 +204,7 @@ class Test_ec2_securitygroup_allow_ingress_from_internet_to_any_port: association={}, attachment={"InstanceOwnerId": test["eni_instance_owner"]}, private_ip="1", + public_ip_addresses=[], type=test["eni_interface_type"], subnet_id="1", vpc_id="1", diff --git a/tests/providers/aws/services/ec2/ec2_service_test.py b/tests/providers/aws/services/ec2/ec2_service_test.py index d46c7e2307..46786b46f8 100644 --- a/tests/providers/aws/services/ec2/ec2_service_test.py +++ b/tests/providers/aws/services/ec2/ec2_service_test.py @@ -26,6 +26,20 @@ make_api_call = botocore.client.BaseClient._make_api_call def mock_make_api_call(self, operation_name, kwarg): + if operation_name == "DescribeLaunchTemplateVersions": + return { + "LaunchTemplateVersions": [ + { + "VersionNumber": 123, + "LaunchTemplateData": { + "UserData": b64encode( + "foobar123".encode(encoding_format_utf_8) + ).decode(encoding_format_utf_8), + "NetworkInterfaces": [{"AssociatePublicIpAddress": True}], + }, + } + ] + } if operation_name == "DescribeClientVpnEndpoints": return { "ClientVpnEndpoints": [ @@ -40,7 +54,6 @@ def mock_make_api_call(self, operation_name, kwarg): } ] } - # Si no es la operación que queremos interceptar, llamamos al método original return make_api_call(self, operation_name, kwarg) @@ -531,21 +544,21 @@ class Test_EC2_Service: ) ec2 = EC2(aws_provider) assert len(ec2.network_interfaces) == 1 - assert ec2.network_interfaces[0].association - assert ec2.network_interfaces[0].attachment - assert ec2.network_interfaces[0].id == eni.id - assert ec2.network_interfaces[0].private_ip == eni.private_ip_address - assert ec2.network_interfaces[0].subnet_id == subnet.id - assert ec2.network_interfaces[0].type == eni.interface_type - assert ec2.network_interfaces[0].vpc_id == vpc.id - assert ec2.network_interfaces[0].region == AWS_REGION_US_EAST_1 - assert ec2.network_interfaces[0].tags == [ + assert ec2.network_interfaces[eni.id].association + assert ec2.network_interfaces[eni.id].attachment + assert ec2.network_interfaces[eni.id].id == eni.id + assert ec2.network_interfaces[eni.id].private_ip == eni.private_ip_address + assert ec2.network_interfaces[eni.id].subnet_id == subnet.id + assert ec2.network_interfaces[eni.id].type == eni.interface_type + assert ec2.network_interfaces[eni.id].vpc_id == vpc.id + assert ec2.network_interfaces[eni.id].region == AWS_REGION_US_EAST_1 + assert ec2.network_interfaces[eni.id].tags == [ {"Key": "string", "Value": "string"}, ] # Check if ENI was added to security group for sg in ec2.security_groups.values(): if sg.id == eni.groups[0]["GroupId"]: - assert sg.network_interfaces == ec2.network_interfaces + assert sg.network_interfaces[0] == ec2.network_interfaces[eni.id] # Test EC2 Describe Images @mock_aws @@ -676,57 +689,43 @@ class Test_EC2_Service: # Test EC2 Describe Launch Templates @mock_aws - def test_get_launch_template_versions(self): + @mock.patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) + def test_describe_launch_template_versions(self): # Generate EC2 Client ec2_client = client("ec2", region_name=AWS_REGION_US_EAST_1) TEMPLATE_NAME = "tester1" TEMPLATE_INSTANCE_TYPE = "c5.large" - KNOWN_SECRET_USER_DATA = "DB_PASSWORD=foobar123" # Create EC2 Launch Template API ec2_client.create_launch_template( LaunchTemplateName=TEMPLATE_NAME, - VersionDescription="Test EC Launch Template 1", + VersionDescription="Test EC Launch Template 1 (Secret in UserData)", LaunchTemplateData={ "InstanceType": TEMPLATE_INSTANCE_TYPE, }, ) - - # Create EC2 Launch Template Version API - ec2_client.create_launch_template_version( - LaunchTemplateName=TEMPLATE_NAME, - VersionDescription="Updated Test EC Launch Template 1", - LaunchTemplateData={ - "InstanceType": TEMPLATE_INSTANCE_TYPE, - "UserData": b64encode( - KNOWN_SECRET_USER_DATA.encode(encoding_format_utf_8) - ).decode(encoding_format_utf_8), - }, - ) - + launch_template_id = ec2_client.describe_launch_templates()["LaunchTemplates"][ + 0 + ]["LaunchTemplateId"] # EC2 client for this test class - aws_provider = set_mocked_aws_provider( - [AWS_REGION_EU_WEST_1, AWS_REGION_US_EAST_1] - ) + aws_provider = set_mocked_aws_provider([AWS_REGION_US_EAST_1]) ec2 = EC2(aws_provider) assert len(ec2.launch_templates) == 1 - assert ec2.launch_templates[0].name == TEMPLATE_NAME assert ec2.launch_templates[0].region == AWS_REGION_US_EAST_1 + assert ec2.launch_templates[0].id == launch_template_id + assert len(ec2.launch_templates[0].versions) == 1 - assert len(ec2.launch_templates[0].versions) == 2 + version = ec2.launch_templates[0].versions[0] - version1, version2 = ec2.launch_templates[0].versions - - assert version1.template_data["InstanceType"] == TEMPLATE_INSTANCE_TYPE - - assert version2.template_data["InstanceType"] == TEMPLATE_INSTANCE_TYPE assert ( - b64decode(version2.template_data["UserData"]).decode(encoding_format_utf_8) - == KNOWN_SECRET_USER_DATA + b64decode(version.template_data.user_data).decode(encoding_format_utf_8) + == "foobar123" ) + assert version.template_data.associate_public_ip_address + # Test EC2 Describe VPN Endpoints @mock.patch("botocore.client.BaseClient._make_api_call", new=mock_make_api_call) def test_describe_vpn_endpoints(self):