EC2 - VpcEndpointServiceConfiguration (#4815)

This commit is contained in:
Bert Blommers 2022-01-30 22:00:26 -01:00 committed by GitHub
parent f554ad3997
commit 2fd6f34060
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 907 additions and 76 deletions

View File

@ -268,6 +268,8 @@ jobs:
cd .. cd ..
- name: "Create report" - name: "Create report"
run: | run: |
ls -la
cp server_output.log moto-terraform-tests/build/server_output.log
cd moto-terraform-tests cd moto-terraform-tests
bin/create-report bin/create-report
bin/create-report-cli bin/create-report-cli

View File

@ -1280,7 +1280,7 @@
## ec2 ## ec2
<details> <details>
<summary>34% implemented</summary> <summary>35% implemented</summary>
- [ ] accept_reserved_instances_exchange_quote - [ ] accept_reserved_instances_exchange_quote
- [ ] accept_transit_gateway_multicast_domain_associations - [ ] accept_transit_gateway_multicast_domain_associations
@ -1394,7 +1394,7 @@
- [X] create_vpc - [X] create_vpc
- [X] create_vpc_endpoint - [X] create_vpc_endpoint
- [ ] create_vpc_endpoint_connection_notification - [ ] create_vpc_endpoint_connection_notification
- [ ] create_vpc_endpoint_service_configuration - [X] create_vpc_endpoint_service_configuration
- [X] create_vpc_peering_connection - [X] create_vpc_peering_connection
- [X] create_vpn_connection - [X] create_vpn_connection
- [ ] create_vpn_connection_route - [ ] create_vpn_connection_route
@ -1455,7 +1455,7 @@
- [X] delete_volume - [X] delete_volume
- [X] delete_vpc - [X] delete_vpc
- [ ] delete_vpc_endpoint_connection_notifications - [ ] delete_vpc_endpoint_connection_notifications
- [ ] delete_vpc_endpoint_service_configurations - [X] delete_vpc_endpoint_service_configurations
- [X] delete_vpc_endpoints - [X] delete_vpc_endpoints
- [X] delete_vpc_peering_connection - [X] delete_vpc_peering_connection
- [X] delete_vpn_connection - [X] delete_vpn_connection
@ -1593,8 +1593,8 @@
- [ ] describe_vpc_classic_link_dns_support - [ ] describe_vpc_classic_link_dns_support
- [ ] describe_vpc_endpoint_connection_notifications - [ ] describe_vpc_endpoint_connection_notifications
- [ ] describe_vpc_endpoint_connections - [ ] describe_vpc_endpoint_connections
- [ ] describe_vpc_endpoint_service_configurations - [X] describe_vpc_endpoint_service_configurations
- [ ] describe_vpc_endpoint_service_permissions - [X] describe_vpc_endpoint_service_permissions
- [X] describe_vpc_endpoint_services - [X] describe_vpc_endpoint_services
- [X] describe_vpc_endpoints - [X] describe_vpc_endpoints
- [X] describe_vpc_peering_connections - [X] describe_vpc_peering_connections
@ -1728,9 +1728,9 @@
- [X] modify_vpc_attribute - [X] modify_vpc_attribute
- [ ] modify_vpc_endpoint - [ ] modify_vpc_endpoint
- [ ] modify_vpc_endpoint_connection_notification - [ ] modify_vpc_endpoint_connection_notification
- [ ] modify_vpc_endpoint_service_configuration - [X] modify_vpc_endpoint_service_configuration
- [ ] modify_vpc_endpoint_service_payer_responsibility - [ ] modify_vpc_endpoint_service_payer_responsibility
- [ ] modify_vpc_endpoint_service_permissions - [X] modify_vpc_endpoint_service_permissions
- [X] modify_vpc_peering_connection_options - [X] modify_vpc_peering_connection_options
- [X] modify_vpc_tenancy - [X] modify_vpc_tenancy
- [ ] modify_vpn_connection - [ ] modify_vpn_connection

View File

@ -1,6 +1,7 @@
include README.md LICENSE AUTHORS.md include README.md LICENSE AUTHORS.md
include requirements.txt requirements-dev.txt tox.ini include requirements.txt requirements-dev.txt tox.ini
include moto/config/resources/aws_managed_rules.json include moto/config/resources/aws_managed_rules.json
include moto/ec2/_models/*.py
include moto/ec2/resources/instance_types.json include moto/ec2/resources/instance_types.json
include moto/ec2/resources/instance_type_offerings/*/*.json include moto/ec2/resources/instance_type_offerings/*/*.json
include moto/ec2/resources/amis.json include moto/ec2/resources/amis.json

View File

@ -141,7 +141,7 @@ ec2
- [X] create_vpc - [X] create_vpc
- [X] create_vpc_endpoint - [X] create_vpc_endpoint
- [ ] create_vpc_endpoint_connection_notification - [ ] create_vpc_endpoint_connection_notification
- [ ] create_vpc_endpoint_service_configuration - [X] create_vpc_endpoint_service_configuration
- [X] create_vpc_peering_connection - [X] create_vpc_peering_connection
- [X] create_vpn_connection - [X] create_vpn_connection
- [ ] create_vpn_connection_route - [ ] create_vpn_connection_route
@ -202,7 +202,7 @@ ec2
- [X] delete_volume - [X] delete_volume
- [X] delete_vpc - [X] delete_vpc
- [ ] delete_vpc_endpoint_connection_notifications - [ ] delete_vpc_endpoint_connection_notifications
- [ ] delete_vpc_endpoint_service_configurations - [X] delete_vpc_endpoint_service_configurations
- [X] delete_vpc_endpoints - [X] delete_vpc_endpoints
- [X] delete_vpc_peering_connection - [X] delete_vpc_peering_connection
- [X] delete_vpn_connection - [X] delete_vpn_connection
@ -344,8 +344,16 @@ ec2
- [ ] describe_vpc_classic_link_dns_support - [ ] describe_vpc_classic_link_dns_support
- [ ] describe_vpc_endpoint_connection_notifications - [ ] describe_vpc_endpoint_connection_notifications
- [ ] describe_vpc_endpoint_connections - [ ] describe_vpc_endpoint_connections
- [ ] describe_vpc_endpoint_service_configurations - [X] describe_vpc_endpoint_service_configurations
- [ ] describe_vpc_endpoint_service_permissions
The Filters, MaxResults, NextToken parameters are not yet implemented
- [X] describe_vpc_endpoint_service_permissions
The Filters, MaxResults, NextToken parameters are not yet implemented
- [X] describe_vpc_endpoint_services - [X] describe_vpc_endpoint_services
Return info on services to which you can create a VPC endpoint. Return info on services to which you can create a VPC endpoint.
@ -490,9 +498,13 @@ ec2
- [X] modify_vpc_attribute - [X] modify_vpc_attribute
- [ ] modify_vpc_endpoint - [ ] modify_vpc_endpoint
- [ ] modify_vpc_endpoint_connection_notification - [ ] modify_vpc_endpoint_connection_notification
- [ ] modify_vpc_endpoint_service_configuration - [X] modify_vpc_endpoint_service_configuration
The following parameters are not yet implemented: RemovePrivateDnsName, AddNetworkLoadBalancerArns, RemoveNetworkLoadBalancerArns, AddGatewayLoadBalancerArns, RemoveGatewayLoadBalancerArns
- [ ] modify_vpc_endpoint_service_payer_responsibility - [ ] modify_vpc_endpoint_service_payer_responsibility
- [ ] modify_vpc_endpoint_service_permissions - [X] modify_vpc_endpoint_service_permissions
- [X] modify_vpc_peering_connection_options - [X] modify_vpc_peering_connection_options
- [X] modify_vpc_tenancy - [X] modify_vpc_tenancy
- [ ] modify_vpn_connection - [ ] modify_vpn_connection

39
moto/ec2/_models/core.py Normal file
View File

@ -0,0 +1,39 @@
from moto.core.models import BaseModel
from ..exceptions import FilterNotImplementedError
class TaggedEC2Resource(BaseModel):
def get_tags(self, *args, **kwargs):
tags = []
if self.id:
tags = self.ec2_backend.describe_tags(filters={"resource-id": [self.id]})
return tags
def add_tag(self, key, value):
self.ec2_backend.create_tags([self.id], {key: value})
def add_tags(self, tag_map):
for key, value in tag_map.items():
self.ec2_backend.create_tags([self.id], {key: value})
def get_filter_value(self, filter_name, method_name=None):
tags = self.get_tags()
if filter_name.startswith("tag:"):
tagname = filter_name.replace("tag:", "", 1)
for tag in tags:
if tag["key"] == tagname:
return tag["value"]
return None
elif filter_name == "tag-key":
return [tag["key"] for tag in tags]
elif filter_name == "tag-value":
return [tag["value"] for tag in tags]
value = getattr(self, filter_name.lower().replace("-", "_"), None)
if value is not None:
return value
raise FilterNotImplementedError(filter_name, method_name)

View File

@ -0,0 +1,132 @@
from moto.core.models import CloudFormationModel
from moto.core.utils import get_random_hex
from .core import TaggedEC2Resource
from ..exceptions import UnknownVpcEndpointService
class VPCServiceConfiguration(TaggedEC2Resource, CloudFormationModel):
def __init__(
self, load_balancers, region, acceptance_required, private_dns_name, ec2_backend
):
self.id = f"vpce-svc-{get_random_hex(length=8)}"
self.service_name = f"com.amazonaws.vpce.{region}.{self.id}"
self.service_state = "Available"
self.availability_zones = []
for lb in load_balancers:
for subnet in lb.subnets:
self.availability_zones.append(subnet.availability_zone)
self.gateway_load_balancer_arns = []
self.network_load_balancer_arns = []
for lb in load_balancers:
if lb.loadbalancer_type == "network":
self.service_type = "Interface"
self.network_load_balancer_arns.append(lb.arn)
else:
self.service_type = "Gateway"
self.gateway_load_balancer_arns.append(lb.arn)
self.acceptance_required = acceptance_required
self.manages_vpc_endpoints = False
self.private_dns_name = private_dns_name
self.endpoint_dns_name = f"{self.id}.{region}.vpce.amazonaws.com"
self.principals = []
self.ec2_backend = ec2_backend
class VPCServiceConfigurationBackend(object):
def __init__(self):
self.configurations = {}
super().__init__()
@property
def elbv2_backend(self):
from moto.elbv2.models import elbv2_backends
return elbv2_backends[self.region_name]
def get_vpc_endpoint_service(self, resource_id):
return self.configurations.get(resource_id)
def create_vpc_endpoint_service_configuration(
self, lb_arns, acceptance_required, private_dns_name, tags
):
lbs = self.elbv2_backend.describe_load_balancers(arns=lb_arns, names=None)
config = VPCServiceConfiguration(
load_balancers=lbs,
region=self.region_name,
acceptance_required=acceptance_required,
private_dns_name=private_dns_name,
ec2_backend=self,
)
for tag in tags or []:
tag_key = tag.get("Key")
tag_value = tag.get("Value")
config.add_tag(tag_key, tag_value)
self.configurations[config.id] = config
return config
def describe_vpc_endpoint_service_configurations(self, service_ids):
"""
The Filters, MaxResults, NextToken parameters are not yet implemented
"""
if service_ids:
found_configs = []
for service_id in service_ids:
if service_id in self.configurations:
found_configs.append(self.configurations[service_id])
else:
raise UnknownVpcEndpointService(service_id)
return found_configs
return self.configurations.values()
def delete_vpc_endpoint_service_configurations(self, service_ids):
missing = [s for s in service_ids if s not in self.configurations]
for s in service_ids:
self.configurations.pop(s, None)
return missing
def describe_vpc_endpoint_service_permissions(self, service_id):
"""
The Filters, MaxResults, NextToken parameters are not yet implemented
"""
config = self.describe_vpc_endpoint_service_configurations([service_id])[0]
return config.principals
def modify_vpc_endpoint_service_permissions(
self, service_id, add_principals, remove_principals
):
config = self.describe_vpc_endpoint_service_configurations([service_id])[0]
config.principals += add_principals
config.principals = [p for p in config.principals if p not in remove_principals]
config.principals = list(set(config.principals))
def modify_vpc_endpoint_service_configuration(
self,
service_id,
acceptance_required,
private_dns_name,
add_network_lbs,
remove_network_lbs,
add_gateway_lbs,
remove_gateway_lbs,
):
"""
The following parameters are not yet implemented: RemovePrivateDnsName
"""
config = self.describe_vpc_endpoint_service_configurations([service_id])[0]
if private_dns_name is not None:
config.private_dns_name = private_dns_name
if acceptance_required is not None:
config.acceptance_required = str(acceptance_required).lower() == "true"
for lb in add_network_lbs:
config.network_load_balancer_arns.append(lb)
for lb in remove_network_lbs:
config.network_load_balancer_arns.remove(lb)
for lb in add_gateway_lbs:
config.gateway_load_balancer_arns.append(lb)
for lb in remove_gateway_lbs:
config.gateway_load_balancer_arns.remove(lb)

View File

@ -734,3 +734,19 @@ class InvalidCarrierGatewayID(EC2ClientError):
"InvalidCarrierGatewayID.NotFound", "InvalidCarrierGatewayID.NotFound",
"The CarrierGateway ID '{0}' does not exist".format(carrier_gateway_id), "The CarrierGateway ID '{0}' does not exist".format(carrier_gateway_id),
) )
class NoLoadBalancersProvided(EC2ClientError):
def __init__(self):
super().__init__(
"InvalidParameter",
"exactly one of network_load_balancer_arn or gateway_load_balancer_arn is a required member",
)
class UnknownVpcEndpointService(EC2ClientError):
def __init__(self, service_id):
super().__init__(
"InvalidVpcEndpointServiceId.NotFound",
f"The VpcEndpointService Id '{service_id}' does not exist",
)

View File

@ -17,7 +17,7 @@ from boto3 import Session
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.models import Model, BaseModel, CloudFormationModel from moto.core.models import Model, CloudFormationModel
from moto.core.utils import ( from moto.core.utils import (
iso_8601_datetime_with_milliseconds, iso_8601_datetime_with_milliseconds,
camelcase_to_underscores, camelcase_to_underscores,
@ -121,6 +121,8 @@ from .exceptions import (
InvalidGatewayIDError, InvalidGatewayIDError,
InvalidCarrierGatewayID, InvalidCarrierGatewayID,
) )
from ._models.core import TaggedEC2Resource
from ._models.vpc_service_configuration import VPCServiceConfigurationBackend
from .utils import ( from .utils import (
EC2_RESOURCE_TO_PREFIX, EC2_RESOURCE_TO_PREFIX,
EC2_PREFIX_TO_RESOURCE, EC2_PREFIX_TO_RESOURCE,
@ -239,42 +241,6 @@ class StateReason(object):
self.code = code self.code = code
class TaggedEC2Resource(BaseModel):
def get_tags(self, *args, **kwargs):
tags = []
if self.id:
tags = self.ec2_backend.describe_tags(filters={"resource-id": [self.id]})
return tags
def add_tag(self, key, value):
self.ec2_backend.create_tags([self.id], {key: value})
def add_tags(self, tag_map):
for key, value in tag_map.items():
self.ec2_backend.create_tags([self.id], {key: value})
def get_filter_value(self, filter_name, method_name=None):
tags = self.get_tags()
if filter_name.startswith("tag:"):
tagname = filter_name.replace("tag:", "", 1)
for tag in tags:
if tag["key"] == tagname:
return tag["value"]
return None
elif filter_name == "tag-key":
return [tag["key"] for tag in tags]
elif filter_name == "tag-value":
return [tag["value"] for tag in tags]
value = getattr(self, filter_name.lower().replace("-", "_"), None)
if value is not None:
return value
raise FilterNotImplementedError(filter_name, method_name)
class NetworkInterface(TaggedEC2Resource, CloudFormationModel): class NetworkInterface(TaggedEC2Resource, CloudFormationModel):
def __init__( def __init__(
self, self,
@ -503,6 +469,8 @@ class NetworkInterface(TaggedEC2Resource, CloudFormationModel):
return self.description return self.description
elif filter_name == "attachment.instance-id": elif filter_name == "attachment.instance-id":
return self.instance.id if self.instance else None return self.instance.id if self.instance else None
elif filter_name == "attachment.instance-owner-id":
return self.owner_id
else: else:
return super().get_filter_value(filter_name, "DescribeNetworkInterfaces") return super().get_filter_value(filter_name, "DescribeNetworkInterfaces")
@ -1509,27 +1477,6 @@ class SettingsBackend(object):
class TagBackend(object): class TagBackend(object):
VALID_TAG_FILTERS = ["key", "resource-id", "resource-type", "value"] VALID_TAG_FILTERS = ["key", "resource-id", "resource-type", "value"]
VALID_TAG_RESOURCE_FILTER_TYPES = [
"customer-gateway",
"dhcp-options",
"image",
"instance",
"internet-gateway",
"network-acl",
"network-interface",
"reserved-instances",
"route-table",
"security-group",
"snapshot",
"spot-instances-request",
"subnet",
"volume",
"vpc",
"vpc-flow-log",
"vpc-peering-connection" "vpn-connection",
"vpn-gateway",
]
def __init__(self): def __init__(self):
self.tags = defaultdict(dict) self.tags = defaultdict(dict)
super().__init__() super().__init__()
@ -8667,6 +8614,7 @@ class EC2Backend(
FlowLogsBackend, FlowLogsBackend,
NetworkInterfaceBackend, NetworkInterfaceBackend,
VPNConnectionBackend, VPNConnectionBackend,
VPCServiceConfigurationBackend,
VPCPeeringConnectionBackend, VPCPeeringConnectionBackend,
RouteTableBackend, RouteTableBackend,
RouteBackend, RouteBackend,
@ -8781,6 +8729,8 @@ class EC2Backend(
self.get_volume(volume_id=resource_id) self.get_volume(volume_id=resource_id)
elif resource_prefix == EC2_RESOURCE_TO_PREFIX["vpc"]: elif resource_prefix == EC2_RESOURCE_TO_PREFIX["vpc"]:
self.get_vpc(vpc_id=resource_id) self.get_vpc(vpc_id=resource_id)
elif resource_prefix == EC2_RESOURCE_TO_PREFIX["vpc-endpoint-service"]:
self.get_vpc_endpoint_service(resource_id)
elif resource_prefix == EC2_RESOURCE_TO_PREFIX["vpc-peering-connection"]: elif resource_prefix == EC2_RESOURCE_TO_PREFIX["vpc-peering-connection"]:
self.get_vpc_peering_connection(vpc_pcx_id=resource_id) self.get_vpc_peering_connection(vpc_pcx_id=resource_id)
elif resource_prefix == EC2_RESOURCE_TO_PREFIX["vpn-connection"]: elif resource_prefix == EC2_RESOURCE_TO_PREFIX["vpn-connection"]:

View File

@ -30,6 +30,7 @@ from .virtual_private_gateways import VirtualPrivateGateways
from .vm_export import VMExport from .vm_export import VMExport
from .vm_import import VMImport from .vm_import import VMImport
from .vpcs import VPCs from .vpcs import VPCs
from .vpc_service_configuration import VPCEndpointServiceConfiguration
from .vpc_peering_connections import VPCPeeringConnections from .vpc_peering_connections import VPCPeeringConnections
from .vpn_connections import VPNConnections from .vpn_connections import VPNConnections
from .windows import Windows from .windows import Windows
@ -74,6 +75,7 @@ class EC2Response(
VMExport, VMExport,
VMImport, VMImport,
VPCs, VPCs,
VPCEndpointServiceConfiguration,
VPCPeeringConnections, VPCPeeringConnections,
VPNConnections, VPNConnections,
Windows, Windows,

View File

@ -0,0 +1,223 @@
from moto.core.responses import BaseResponse
from ..exceptions import NoLoadBalancersProvided
class VPCEndpointServiceConfiguration(BaseResponse):
def create_vpc_endpoint_service_configuration(self):
gateway_lbs = self._get_multi_param("GatewayLoadBalancerArn")
network_lbs = self._get_multi_param("NetworkLoadBalancerArn")
if not gateway_lbs and not network_lbs:
raise NoLoadBalancersProvided
tags = self._get_multi_param("TagSpecification")
if tags:
tags = tags[0].get("Tag")
acceptance_required = (
str(self._get_param("AcceptanceRequired", "true")).lower() == "true"
)
private_dns_name = self._get_param("PrivateDnsName")
config = self.ec2_backend.create_vpc_endpoint_service_configuration(
gateway_lbs or network_lbs,
acceptance_required=acceptance_required,
private_dns_name=private_dns_name,
tags=tags,
)
template = self.response_template(CREATE_VPC_ENDPOINT_SERVICE_CONFIGURATION)
return template.render(config=config)
def describe_vpc_endpoint_service_configurations(self):
service_ids = self._get_multi_param("ServiceId")
configs = self.ec2_backend.describe_vpc_endpoint_service_configurations(
service_ids
)
template = self.response_template(DESCRIBE_VPC_ENDPOINT_SERVICE_CONFIGURATION)
return template.render(configs=configs)
def delete_vpc_endpoint_service_configurations(self):
service_ids = self._get_multi_param("ServiceId")
missing_configs = self.ec2_backend.delete_vpc_endpoint_service_configurations(
service_ids
)
template = self.response_template(DELETE_VPC_ENDPOINT_SERVICE_CONFIGURATION)
return template.render(missing=missing_configs)
def describe_vpc_endpoint_service_permissions(self):
service_id = self._get_param("ServiceId")
principals = self.ec2_backend.describe_vpc_endpoint_service_permissions(
service_id
)
template = self.response_template(DESCRIBE_VPC_ENDPOINT_SERVICE_PERMISSIONS)
return template.render(principals=principals)
def modify_vpc_endpoint_service_configuration(self):
service_id = self._get_param("ServiceId")
private_dns_name = self._get_param("PrivateDnsName")
acceptance_required = self._get_param("AcceptanceRequired")
add_network_lbs = self._get_multi_param("AddNetworkLoadBalancerArn")
remove_network_lbs = self._get_multi_param("RemoveNetworkLoadBalancerArn")
add_gateway_lbs = self._get_multi_param("AddGatewayLoadBalancerArn")
remove_gateway_lbs = self._get_multi_param("RemoveGatewayLoadBalancerArn")
self.ec2_backend.modify_vpc_endpoint_service_configuration(
service_id,
acceptance_required=acceptance_required,
private_dns_name=private_dns_name,
add_network_lbs=add_network_lbs,
remove_network_lbs=remove_network_lbs,
add_gateway_lbs=add_gateway_lbs,
remove_gateway_lbs=remove_gateway_lbs,
)
return MODIFY_VPC_ENDPOINT_SERVICE_CONFIGURATION
def modify_vpc_endpoint_service_permissions(self):
service_id = self._get_param("ServiceId")
add_principals = self._get_multi_param("AddAllowedPrincipals")
remove_principals = self._get_multi_param("RemoveAllowedPrincipals")
self.ec2_backend.modify_vpc_endpoint_service_permissions(
service_id, add_principals, remove_principals
)
return MODIFY_VPC_ENDPOINT_SERVICE_PERMISSIONS
CREATE_VPC_ENDPOINT_SERVICE_CONFIGURATION = """
<CreateVpcEndpointServiceConfigurationResult xmlns="http://ec2.amazonaws.com/doc/2013-10-15/">
<requestId>7a62c49f-347e-4fc4-9331-6e8eEXAMPLE</requestId>
<serviceConfiguration>
<serviceType>
<item><serviceType>{{ config.service_type }}</serviceType></item>
</serviceType>
<serviceId>{{ config.id }}</serviceId>
<serviceName>{{ config.service_name }}</serviceName>
<serviceState>{{ config.service_state }}</serviceState>
<availabilityZoneSet>
{% for zone in config.availability_zones %}<item>{{ zone }}</item>{% endfor %}
</availabilityZoneSet>
<acceptanceRequired>{{ 'true' if config.acceptance_required else 'false' }}</acceptanceRequired>
<managesVpcEndpoints>{{ 'true' if config.manages_vpc_endpoints else 'false' }}</managesVpcEndpoints>
{%- if config.network_load_balancer_arns %}
<networkLoadBalancerArnSet>
{% for lb in config.network_load_balancer_arns %}<item>{{ lb }}</item>{% endfor %}
</networkLoadBalancerArnSet>
{% endif -%}
{%- if config.gateway_load_balancer_arns %}
<gatewayLoadBalancerArnSet>
{% for lb in config.gateway_load_balancer_arns %}<item>{{ lb }}</item>{% endfor %}
</gatewayLoadBalancerArnSet>
{% endif -%}
<baseEndpointDnsNameSet><item>{{ config.endpoint_dns_name }}</item></baseEndpointDnsNameSet>
<privateDnsName>{{ config.private_dns_name }}</privateDnsName>
<privateDnsNameConfiguration>
{% if config.private_dns_name %}
<state>verified</state>
<type>TXT</type>
<value>val</value>
<name>n</name>
{% endif %}
</privateDnsNameConfiguration>
</serviceConfiguration>
</CreateVpcEndpointServiceConfigurationResult>
"""
DESCRIBE_VPC_ENDPOINT_SERVICE_CONFIGURATION = """
<DescribeVpcEndpointServiceConfigurationsResult>
<serviceConfigurationSet>
{% for config in configs %}
<item>
<serviceType>
<item><serviceType>{{ config.service_type }}</serviceType></item>
</serviceType>
<serviceId>{{ config.id }}</serviceId>
<serviceName>{{ config.service_name }}</serviceName>
<serviceState>{{ config.service_state }}</serviceState>
<availabilityZoneSet>
{% for zone in config.availability_zones %}<item>{{ zone }}</item>{% endfor %}
</availabilityZoneSet>
<acceptanceRequired>{{ 'true' if config.acceptance_required else 'false' }}</acceptanceRequired>
<managesVpcEndpoints>{{ 'true' if config.manages_vpc_endpoints else 'false' }}</managesVpcEndpoints>
{%- if config.network_load_balancer_arns %}
<networkLoadBalancerArnSet>
{% for lb in config.network_load_balancer_arns %}<item>{{ lb }}</item>{% endfor %}
</networkLoadBalancerArnSet>
{% endif -%}
{%- if config.gateway_load_balancer_arns %}
<gatewayLoadBalancerArnSet>
{% for lb in config.gateway_load_balancer_arns %}<item>{{ lb }}</item>{% endfor %}
</gatewayLoadBalancerArnSet>
{% endif -%}
<baseEndpointDnsNameSet><item>{{ config.endpoint_dns_name }}</item></baseEndpointDnsNameSet>
<privateDnsName>{{ config.private_dns_name }}</privateDnsName>
<privateDnsNameConfiguration>
{% if config.private_dns_name %}
<state>verified</state>
<type>TXT</type>
<value>val</value>
<name>n</name>
{% endif %}
</privateDnsNameConfiguration>
<tagSet>
{% for tag in config.get_tags() %}
<item>
<key>{{ tag.key }}</key>
<value>{{ tag.value }}</value>
</item>
{% endfor %}
</tagSet>
</item>
{% endfor %}
</serviceConfigurationSet>
</DescribeVpcEndpointServiceConfigurationsResult>
"""
DELETE_VPC_ENDPOINT_SERVICE_CONFIGURATION = """
<DeleteVpcEndpointServiceConfigurationsResult>
<unsuccessful>
{% for m in missing %}
<item>
<error>
<code>InvalidVpcEndpointService.NotFound</code>
<message>The VpcEndpointService Id '{{ m }}' does not exist</message>
</error>
<resourceId>{{ m }}</resourceId>
</item>
{% endfor %}
</unsuccessful>
</DeleteVpcEndpointServiceConfigurationsResult>
"""
DESCRIBE_VPC_ENDPOINT_SERVICE_PERMISSIONS = """
<DescribeVpcEndpointServicePermissionsResult>
<allowedPrincipals>
{% for principal in principals %}
<item>
<principal>{{ principal }}</principal>
</item>
{% endfor %}
</allowedPrincipals>
</DescribeVpcEndpointServicePermissionsResult>
"""
MODIFY_VPC_ENDPOINT_SERVICE_PERMISSIONS = """
<ModifyVpcEndpointServicePermissionsResult>
<return>true</return>
</ModifyVpcEndpointServicePermissionsResult>
"""
MODIFY_VPC_ENDPOINT_SERVICE_CONFIGURATION = """
<ModifyVpcEndpointServiceConfigurationResult>
<return>true</return>
</ModifyVpcEndpointServiceConfigurationResult>
"""

View File

@ -43,6 +43,7 @@ EC2_RESOURCE_TO_PREFIX = {
"volume": "vol", "volume": "vol",
"vpc": "vpc", "vpc": "vpc",
"vpc-endpoint": "vpce", "vpc-endpoint": "vpce",
"vpc-endpoint-service": "vpce-svc",
"managed-prefix-list": "pl", "managed-prefix-list": "pl",
"vpc-cidr-association-id": "vpc-cidr-assoc", "vpc-cidr-association-id": "vpc-cidr-assoc",
"vpc-elastic-ip": "eipalloc", "vpc-elastic-ip": "eipalloc",
@ -626,6 +627,8 @@ def get_prefix(resource_id):
if resource_id_prefix == EC2_RESOURCE_TO_PREFIX["network-interface"]: if resource_id_prefix == EC2_RESOURCE_TO_PREFIX["network-interface"]:
if after.startswith("attach"): if after.startswith("attach"):
resource_id_prefix = EC2_RESOURCE_TO_PREFIX["network-interface-attachment"] resource_id_prefix = EC2_RESOURCE_TO_PREFIX["network-interface-attachment"]
if resource_id.startswith(EC2_RESOURCE_TO_PREFIX["vpc-endpoint-service"]):
resource_id_prefix = EC2_RESOURCE_TO_PREFIX["vpc-endpoint-service"]
if resource_id_prefix not in EC2_RESOURCE_TO_PREFIX.values(): if resource_id_prefix not in EC2_RESOURCE_TO_PREFIX.values():
uuid4hex = re.compile(r"[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}\Z", re.I) uuid4hex = re.compile(r"[0-9a-f]{12}4[0-9a-f]{3}[89ab][0-9a-f]{15}\Z", re.I)
if uuid4hex.match(resource_id) is not None: if uuid4hex.match(resource_id) is not None:

View File

@ -4,7 +4,7 @@ from jinja2 import Template
from botocore.exceptions import ParamValidationError from botocore.exceptions import ParamValidationError
from collections import OrderedDict from collections import OrderedDict
from moto.core.exceptions import RESTError from moto.core.exceptions import RESTError
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import ( from moto.core.utils import (
iso_8601_datetime_with_milliseconds, iso_8601_datetime_with_milliseconds,
get_random_hex, get_random_hex,
@ -428,6 +428,7 @@ class FakeLoadBalancer(CloudFormationModel):
"access_logs.s3.prefix", "access_logs.s3.prefix",
"deletion_protection.enabled", "deletion_protection.enabled",
"idle_timeout.timeout_seconds", "idle_timeout.timeout_seconds",
"load_balancing.cross_zone.enabled",
"routing.http2.enabled", "routing.http2.enabled",
"routing.http.drop_invalid_header_fields.enabled", "routing.http.drop_invalid_header_fields.enabled",
} }
@ -618,7 +619,7 @@ class ELBv2Backend(BaseBackend):
vpc_id = subnets[0].vpc_id vpc_id = subnets[0].vpc_id
arn = make_arn_for_load_balancer( arn = make_arn_for_load_balancer(
account_id=1, name=name, region_name=self.region_name account_id=ACCOUNT_ID, name=name, region_name=self.region_name
) )
dns_name = "%s-1.%s.elb.amazonaws.com" % (name, self.region_name) dns_name = "%s-1.%s.elb.amazonaws.com" % (name, self.region_name)
@ -944,7 +945,7 @@ Member must satisfy regular expression pattern: {}".format(
) )
arn = make_arn_for_target_group( arn = make_arn_for_target_group(
account_id=1, name=name, region_name=self.region_name account_id=ACCOUNT_ID, name=name, region_name=self.region_name
) )
target_group = FakeTargetGroup(name, arn, **kwargs) target_group = FakeTargetGroup(name, arn, **kwargs)
self.target_groups[target_group.arn] = target_group self.target_groups[target_group.arn] = target_group

View File

@ -133,3 +133,4 @@ TestAccAWSDataSourceIAMRole
TestAccAWSDataSourceIAMUser TestAccAWSDataSourceIAMUser
TestAccAWSIAMAccountAlias TestAccAWSIAMAccountAlias
TestAccAWSIAMOpenIDConnectProvider TestAccAWSIAMOpenIDConnectProvider
TestAccAWSVpcEndpointService

View File

@ -6,6 +6,7 @@ from botocore.exceptions import ClientError
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from moto import mock_ec2, settings from moto import mock_ec2, settings
from moto.core import ACCOUNT_ID
from moto.ec2.utils import random_private_ip from moto.ec2.utils import random_private_ip
from tests import EXAMPLE_AMI_ID from tests import EXAMPLE_AMI_ID
from uuid import uuid4 from uuid import uuid4
@ -488,6 +489,38 @@ def test_elastic_network_interfaces_get_by_attachment_instance_id():
enis.get("NetworkInterfaces").should.have.length_of(0) enis.get("NetworkInterfaces").should.have.length_of(0)
@mock_ec2
def test_elastic_network_interfaces_get_by_attachment_instance_owner_id():
ec2_resource = boto3.resource("ec2", region_name="us-west-2")
ec2_client = boto3.client("ec2", region_name="us-west-2")
vpc = ec2_resource.create_vpc(CidrBlock="10.0.0.0/16")
subnet = ec2_resource.create_subnet(
VpcId=vpc.id, CidrBlock="10.0.0.0/24", AvailabilityZone="us-west-2a"
)
security_group1 = ec2_resource.create_security_group(
GroupName=str(uuid4()), Description="desc"
)
create_instances_result = ec2_resource.create_instances(
ImageId=EXAMPLE_AMI_ID, MinCount=1, MaxCount=1
)
instance = create_instances_result[0]
eni1 = ec2_resource.create_network_interface(
SubnetId=subnet.id, Groups=[security_group1.id]
)
ec2_client.attach_network_interface(
NetworkInterfaceId=eni1.id, InstanceId=instance.id, DeviceIndex=1
)
filters = [{"Name": "attachment.instance-owner-id", "Values": [ACCOUNT_ID]}]
enis = ec2_client.describe_network_interfaces(Filters=filters)["NetworkInterfaces"]
eni_ids = [eni["NetworkInterfaceId"] for eni in enis]
eni_ids.should.contain(eni1.id)
@mock_ec2 @mock_ec2
def test_elastic_network_interfaces_describe_network_interfaces_with_filter(): def test_elastic_network_interfaces_describe_network_interfaces_with_filter():
ec2 = boto3.resource("ec2", region_name="us-west-2") ec2 = boto3.resource("ec2", region_name="us-west-2")

View File

@ -0,0 +1,397 @@
import boto3
import pytest
import sure # noqa # pylint: disable=unused-import
from botocore.exceptions import ClientError
from moto import mock_ec2, mock_elbv2
from moto.core.utils import get_random_hex
# See our Development Tips on writing tests for hints on how to write good tests:
# http://docs.getmoto.org/en/latest/docs/contributing/development_tips/tests.html
@mock_ec2
def test_create_vpc_endpoint_service_configuration_without_params():
client = boto3.client("ec2", region_name="us-west-2")
with pytest.raises(ClientError) as exc:
client.create_vpc_endpoint_service_configuration()
err = exc.value.response["Error"]
err["Code"].should.equal("InvalidParameter")
err["Message"].should.equal(
"exactly one of network_load_balancer_arn or gateway_load_balancer_arn is a required member"
)
@mock_ec2
@mock_elbv2
def test_create_vpc_endpoint_service_configuration_with_network_load_balancer():
region_name = "eu-west-3"
client = boto3.client("ec2", region_name=region_name)
lb_arn = create_load_balancer(
region_name=region_name, lb_type="network", zone="eu-west-3b"
)
resp = client.create_vpc_endpoint_service_configuration(
NetworkLoadBalancerArns=[lb_arn]
)
resp.should.have.key("ServiceConfiguration")
config = resp["ServiceConfiguration"]
config.should.have.key("ServiceType").equals([{"ServiceType": "Interface"}])
config.should.have.key("ServiceId").match("^vpce-svc-")
config.should.have.key("ServiceName").equals(
f"com.amazonaws.vpce.eu-west-3.{config['ServiceId']}"
)
config.should.have.key("ServiceState").equals("Available")
config.should.have.key("AvailabilityZones").equals(["eu-west-3b"])
config.should.have.key("AcceptanceRequired").equals(True)
config.should.have.key("ManagesVpcEndpoints").equals(False)
config.should.have.key("NetworkLoadBalancerArns").equals([lb_arn])
config.should.have.key("BaseEndpointDnsNames").equals(
[f"{config['ServiceId']}.eu-west-3.vpce.amazonaws.com"]
)
config.should.have.key("PrivateDnsNameConfiguration").equals({})
config.shouldnt.have.key("GatewayLoadBalancerArns")
@mock_ec2
@mock_elbv2
def test_create_vpc_endpoint_service_configuration_with_gateway_load_balancer():
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
resp = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)
resp.should.have.key("ServiceConfiguration")
config = resp["ServiceConfiguration"]
config.should.have.key("ServiceType").equals([{"ServiceType": "Gateway"}])
config.should.have.key("ServiceId").match("^vpce-svc-")
config.should.have.key("ServiceName").equals(
f"com.amazonaws.vpce.us-east-2.{config['ServiceId']}"
)
config.should.have.key("ServiceState").equals("Available")
config.should.have.key("AvailabilityZones").equals(["us-east-1c"])
config.should.have.key("AcceptanceRequired").equals(True)
config.should.have.key("ManagesVpcEndpoints").equals(False)
config.should.have.key("GatewayLoadBalancerArns").equals([lb_arn])
config.should.have.key("BaseEndpointDnsNames").equals(
[f"{config['ServiceId']}.us-east-2.vpce.amazonaws.com"]
)
config.should.have.key("PrivateDnsNameConfiguration").equals({})
config.shouldnt.have.key("NetworkLoadBalancerArns")
@mock_ec2
@mock_elbv2
def test_create_vpc_endpoint_service_configuration_with_options():
client = boto3.client("ec2", region_name="us-east-2")
lb_arn = create_load_balancer(
region_name="us-east-2", lb_type="gateway", zone="us-east-1c"
)
resp = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn],
AcceptanceRequired=False,
PrivateDnsName="example.com",
)
resp.should.have.key("ServiceConfiguration")
config = resp["ServiceConfiguration"]
config.should.have.key("AcceptanceRequired").equals(False)
config.should.have.key("PrivateDnsName").equals("example.com")
config.should.have.key("PrivateDnsNameConfiguration").equals(
{"Name": "n", "State": "verified", "Type": "TXT", "Value": "val"}
)
@mock_ec2
@mock_elbv2
def test_describe_vpc_endpoint_service_configurations():
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
config1 = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)["ServiceConfiguration"]["ServiceId"]
config2 = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)["ServiceConfiguration"]["ServiceId"]
resp = client.describe_vpc_endpoint_service_configurations()
resp.should.have.key("ServiceConfigurations")
service_ids = [s["ServiceId"] for s in resp["ServiceConfigurations"]]
service_ids.should.contain(config1)
service_ids.should.contain(config2)
resp = client.describe_vpc_endpoint_service_configurations(ServiceIds=[config2])
resp.should.have.key("ServiceConfigurations").length_of(1)
result = resp["ServiceConfigurations"][0]
result.should.have.key("ServiceId").equals(config2)
result.should.have.key("ServiceName")
result.should.have.key("ServiceState")
result.should.have.key("GatewayLoadBalancerArns").equals([lb_arn])
@mock_ec2
@mock_elbv2
@pytest.mark.parametrize(
"tags",
[
[{"Key": "k1", "Value": "v1"}],
[{"Key": "k1", "Value": "v1"}, {"Key": "k2", "Value": "v2"}],
],
)
def test_describe_vpc_endpoint_service_configurations_with_tags(tags):
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
service_id = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn],
TagSpecifications=[{"ResourceType": "vpc-endpoint-service", "Tags": tags}],
)["ServiceConfiguration"]["ServiceId"]
resp = client.describe_vpc_endpoint_service_configurations(ServiceIds=[service_id])
resp.should.have.key("ServiceConfigurations").length_of(1)
result = resp["ServiceConfigurations"][0]
result.should.have.key("Tags").length_of(len(tags))
for tag in tags:
result["Tags"].should.contain(tag)
@mock_ec2
@mock_elbv2
def test_describe_vpc_endpoint_service_configurations_and_add_tags():
tags = [{"Key": "k1", "Value": "v1"}]
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
service_id = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)["ServiceConfiguration"]["ServiceId"]
client.create_tags(Resources=[service_id], Tags=tags)
resp = client.describe_vpc_endpoint_service_configurations(ServiceIds=[service_id])
resp.should.have.key("ServiceConfigurations").length_of(1)
result = resp["ServiceConfigurations"][0]
result.should.have.key("Tags").length_of(len(tags))
for tag in tags:
result["Tags"].should.contain(tag)
@mock_ec2
def test_describe_vpc_endpoint_service_configurations_unknown():
client = boto3.client("ec2", region_name="eu-west-3")
with pytest.raises(ClientError) as exc:
# Will always fail if at least one ServiceId is unknown
client.describe_vpc_endpoint_service_configurations(
ServiceIds=["vpce-svc-unknown"]
)
err = exc.value.response["Error"]
err["Code"].should.equal("InvalidVpcEndpointServiceId.NotFound")
err["Message"].should.equal(
"The VpcEndpointService Id 'vpce-svc-unknown' does not exist"
)
@mock_ec2
@mock_elbv2
def test_delete_vpc_endpoint_service_configurations():
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
service_id = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)["ServiceConfiguration"]["ServiceId"]
resp = client.delete_vpc_endpoint_service_configurations(ServiceIds=[service_id])
resp.should.have.key("Unsuccessful").equals([])
@mock_ec2
def test_delete_vpc_endpoint_service_configurations_already_deleted():
client = boto3.client("ec2", region_name="eu-west-3")
resp = client.delete_vpc_endpoint_service_configurations(
ServiceIds=["vpce-svc-03cf101d15c3bff53"]
)
resp.should.have.key("Unsuccessful").length_of(1)
u = resp["Unsuccessful"][0]
u.should.have.key("ResourceId").equals("vpce-svc-03cf101d15c3bff53")
u.should.have.key("Error")
u["Error"].should.have.key("Code").equals("InvalidVpcEndpointService.NotFound")
u["Error"].should.have.key("Message").equals(
"The VpcEndpointService Id 'vpce-svc-03cf101d15c3bff53' does not exist"
)
@mock_ec2
@mock_elbv2
def test_describe_vpc_endpoint_service_permissions():
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
service_id = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)["ServiceConfiguration"]["ServiceId"]
resp = client.describe_vpc_endpoint_service_permissions(ServiceId=service_id)
resp.should.have.key("AllowedPrincipals").equals([])
@mock_ec2
@mock_elbv2
def test_modify_vpc_endpoint_service_permissions():
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
service_id = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)["ServiceConfiguration"]["ServiceId"]
client.modify_vpc_endpoint_service_permissions(
ServiceId=service_id, AddAllowedPrincipals=["prin1", "cipal2"]
)
resp = client.describe_vpc_endpoint_service_permissions(ServiceId=service_id)
resp.should.have.key("AllowedPrincipals").length_of(2)
resp["AllowedPrincipals"].should.contain({"Principal": "prin1"})
resp["AllowedPrincipals"].should.contain({"Principal": "cipal2"})
client.modify_vpc_endpoint_service_permissions(
ServiceId=service_id, RemoveAllowedPrincipals=["prin1"]
)
resp = client.describe_vpc_endpoint_service_permissions(ServiceId=service_id)
resp.should.have.key("AllowedPrincipals").length_of(1)
resp["AllowedPrincipals"].should.contain({"Principal": "cipal2"})
@mock_ec2
@mock_elbv2
def test_modify_vpc_endpoint_service_configuration():
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
service_id = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)["ServiceConfiguration"]["ServiceId"]
client.modify_vpc_endpoint_service_configuration(
ServiceId=service_id, PrivateDnsName="dnsname", AcceptanceRequired=False
)
config = client.describe_vpc_endpoint_service_configurations(
ServiceIds=[service_id]
)["ServiceConfigurations"][0]
config.should.have.key("AcceptanceRequired").equals(False)
config.should.have.key("PrivateDnsName").equals("dnsname")
@mock_ec2
@mock_elbv2
def test_modify_vpc_endpoint_service_configuration_with_new_loadbalancers():
region = "us-east-2"
client = boto3.client("ec2", region_name=region)
lb_arn = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
lb_arn2 = create_load_balancer(
region_name=region, lb_type="gateway", zone="us-east-1c"
)
lb_arn3 = create_load_balancer(
region_name=region, lb_type="network", zone="us-east-1c"
)
service_id = client.create_vpc_endpoint_service_configuration(
GatewayLoadBalancerArns=[lb_arn]
)["ServiceConfiguration"]["ServiceId"]
client.modify_vpc_endpoint_service_configuration(
ServiceId=service_id,
AddNetworkLoadBalancerArns=[lb_arn3],
AddGatewayLoadBalancerArns=[lb_arn2],
)
config = client.describe_vpc_endpoint_service_configurations(
ServiceIds=[service_id]
)["ServiceConfigurations"][0]
config["GatewayLoadBalancerArns"].should.equal([lb_arn, lb_arn2])
config["NetworkLoadBalancerArns"].should.equal([lb_arn3])
client.modify_vpc_endpoint_service_configuration(
ServiceId=service_id,
RemoveNetworkLoadBalancerArns=[lb_arn3],
RemoveGatewayLoadBalancerArns=[lb_arn],
)
config = client.describe_vpc_endpoint_service_configurations(
ServiceIds=[service_id]
)["ServiceConfigurations"][0]
config["GatewayLoadBalancerArns"].should.equal([lb_arn2])
config.shouldnt.have.key("NetworkLoadBalancerArns")
def create_load_balancer(region_name, zone, lb_type):
ec2 = boto3.resource("ec2", region_name=region_name)
elbv2 = boto3.client("elbv2", region_name=region_name)
vpc = ec2.create_vpc(CidrBlock="172.28.7.0/24", InstanceTenancy="default")
subnet = ec2.create_subnet(
VpcId=vpc.id, CidrBlock="172.28.7.192/26", AvailabilityZone=zone
)
lb_name = f"lb_vpce-{get_random_hex(length=10)}"
response = elbv2.create_load_balancer(
Name=lb_name, Subnets=[subnet.id], Scheme="internal", Type=lb_type
)
return response["LoadBalancers"][0]["LoadBalancerArn"]

View File

@ -19,7 +19,7 @@ def test_create_load_balancer():
lb = response.get("LoadBalancers")[0] lb = response.get("LoadBalancers")[0]
lb.get("DNSName").should.equal("my-lb-1.us-east-1.elb.amazonaws.com") lb.get("DNSName").should.equal("my-lb-1.us-east-1.elb.amazonaws.com")
lb.get("LoadBalancerArn").should.equal( lb.get("LoadBalancerArn").should.equal(
"arn:aws:elasticloadbalancing:us-east-1:1:loadbalancer/my-lb/50dc6c495c0c9188" f"arn:aws:elasticloadbalancing:us-east-1:{ACCOUNT_ID}:loadbalancer/my-lb/50dc6c495c0c9188"
) )
lb.get("SecurityGroups").should.equal([security_group.id]) lb.get("SecurityGroups").should.equal([security_group.id])
lb.get("AvailabilityZones").should.equal( lb.get("AvailabilityZones").should.equal(
@ -1224,6 +1224,25 @@ def test_modify_load_balancer_attributes_routing_http2_enabled():
routing_http2_enabled["Value"].should.equal("false") routing_http2_enabled["Value"].should.equal("false")
@mock_elbv2
@mock_ec2
def test_modify_load_balancer_attributes_crosszone_enabled():
response, _, _, _, _, client = create_load_balancer()
arn = response["LoadBalancers"][0]["LoadBalancerArn"]
client.modify_load_balancer_attributes(
LoadBalancerArn=arn,
Attributes=[
{"Key": "load_balancing.cross_zone.enabled", "Value": "false"},
{"Key": "deletion_protection.enabled", "Value": "false"},
],
)
attrs = client.describe_load_balancer_attributes(LoadBalancerArn=arn)["Attributes"]
attrs.should.contain({"Key": "deletion_protection.enabled", "Value": "false"})
attrs.should.contain({"Key": "load_balancing.cross_zone.enabled", "Value": "false"})
@mock_elbv2 @mock_elbv2
@mock_ec2 @mock_ec2
def test_modify_load_balancer_attributes_routing_http_drop_invalid_header_fields_enabled(): def test_modify_load_balancer_attributes_routing_http_drop_invalid_header_fields_enabled():

View File

@ -153,7 +153,7 @@ def test_create_target_group_and_listeners():
e.value.operation_name.should.equal("DeleteTargetGroup") e.value.operation_name.should.equal("DeleteTargetGroup")
e.value.args.should.equal( e.value.args.should.equal(
( (
"An error occurred (ResourceInUse) when calling the DeleteTargetGroup operation: The target group 'arn:aws:elasticloadbalancing:us-east-1:1:targetgroup/a-target/50dc6c495c0c9188' is currently in use by a listener or a rule", f"An error occurred (ResourceInUse) when calling the DeleteTargetGroup operation: The target group 'arn:aws:elasticloadbalancing:us-east-1:{ACCOUNT_ID}:targetgroup/a-target/50dc6c495c0c9188' is currently in use by a listener or a rule",
) )
) # NOQA ) # NOQA