EC2 - VpcEndpointServiceConfiguration (#4815)
This commit is contained in:
parent
f554ad3997
commit
2fd6f34060
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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
39
moto/ec2/_models/core.py
Normal 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)
|
132
moto/ec2/_models/vpc_service_configuration.py
Normal file
132
moto/ec2/_models/vpc_service_configuration.py
Normal 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)
|
@ -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",
|
||||||
|
)
|
||||||
|
@ -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"]:
|
||||||
|
@ -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,
|
||||||
|
223
moto/ec2/responses/vpc_service_configuration.py
Normal file
223
moto/ec2/responses/vpc_service_configuration.py
Normal 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>
|
||||||
|
"""
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -133,3 +133,4 @@ TestAccAWSDataSourceIAMRole
|
|||||||
TestAccAWSDataSourceIAMUser
|
TestAccAWSDataSourceIAMUser
|
||||||
TestAccAWSIAMAccountAlias
|
TestAccAWSIAMAccountAlias
|
||||||
TestAccAWSIAMOpenIDConnectProvider
|
TestAccAWSIAMOpenIDConnectProvider
|
||||||
|
TestAccAWSVpcEndpointService
|
||||||
|
@ -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")
|
||||||
|
397
tests/test_ec2/test_vpc_service_configuration.py
Normal file
397
tests/test_ec2/test_vpc_service_configuration.py
Normal 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"]
|
@ -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():
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user