feat(EC2): Change service to adjust the data saved in template_data in LaunchTemplateVersion (#4848)

This commit is contained in:
Mario Rodriguez Lopez
2024-09-09 18:32:39 +02:00
committed by GitHub
parent 39e8485fc1
commit bab59bc86e
6 changed files with 289 additions and 193 deletions
@@ -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
@@ -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):
@@ -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")
@@ -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):
@@ -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",
@@ -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):