Techdebt: MyPy EC2 (#5936)

This commit is contained in:
Bert Blommers 2023-02-16 20:43:43 -01:00 committed by GitHub
parent e019473dee
commit 418c69f477
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
52 changed files with 380 additions and 474 deletions

View File

@ -64,7 +64,7 @@ class InvalidRequest(EC2ClientError):
class InvalidParameterCombination(EC2ClientError): class InvalidParameterCombination(EC2ClientError):
def __init__(self, msg): def __init__(self, msg: str):
super().__init__("InvalidParameterCombination", msg) super().__init__("InvalidParameterCombination", msg)
@ -340,14 +340,6 @@ class InvalidAddressError(EC2ClientError):
super().__init__("InvalidAddress.NotFound", f"Address '{ip}' not found.") super().__init__("InvalidAddress.NotFound", f"Address '{ip}' not found.")
class LogDestinationNotFoundError(EC2ClientError):
def __init__(self, bucket_name):
super().__init__(
"LogDestinationNotFoundException",
f"LogDestination: '{bucket_name}' does not exist.",
)
class InvalidAllocationIdError(EC2ClientError): class InvalidAllocationIdError(EC2ClientError):
def __init__(self, allocation_id: Any): def __init__(self, allocation_id: Any):
super().__init__( super().__init__(

View File

@ -22,9 +22,9 @@ from moto.packages.boto.ec2.instance import Reservation
from ..exceptions import ( from ..exceptions import (
AvailabilityZoneNotFromRegionError, AvailabilityZoneNotFromRegionError,
EC2ClientError,
InvalidInstanceIdError, InvalidInstanceIdError,
InvalidInstanceTypeError, InvalidInstanceTypeError,
InvalidParameterCombination,
InvalidParameterValueErrorUnknownAttribute, InvalidParameterValueErrorUnknownAttribute,
InvalidSecurityGroupNotFoundError, InvalidSecurityGroupNotFoundError,
OperationNotPermitted4, OperationNotPermitted4,
@ -779,9 +779,7 @@ class InstanceBackend:
) -> List[Tuple[Instance, InstanceState]]: ) -> List[Tuple[Instance, InstanceState]]:
terminated_instances = [] terminated_instances = []
if not instance_ids: if not instance_ids:
raise EC2ClientError( raise InvalidParameterCombination("No instances specified")
"InvalidParameterCombination", "No instances specified"
)
for instance in self.get_multi_instances_by_id(instance_ids): for instance in self.get_multi_instances_by_id(instance_ids):
if instance.disable_api_termination == "true": if instance.disable_api_termination == "true":
raise OperationNotPermitted4(instance.id) raise OperationNotPermitted4(instance.id)

View File

@ -1,5 +1,4 @@
from .account_attributes import AccountAttributes from .account_attributes import AccountAttributes
from .amazon_dev_pay import AmazonDevPay
from .amis import AmisResponse from .amis import AmisResponse
from .availability_zones_and_regions import AvailabilityZonesAndRegions from .availability_zones_and_regions import AvailabilityZonesAndRegions
from .customer_gateways import CustomerGateways from .customer_gateways import CustomerGateways
@ -18,7 +17,6 @@ from .key_pairs import KeyPairs
from .launch_templates import LaunchTemplates from .launch_templates import LaunchTemplates
from .monitoring import Monitoring from .monitoring import Monitoring
from .network_acls import NetworkACLs from .network_acls import NetworkACLs
from .placement_groups import PlacementGroups
from .reserved_instances import ReservedInstances from .reserved_instances import ReservedInstances
from .route_tables import RouteTables from .route_tables import RouteTables
from .security_groups import SecurityGroups from .security_groups import SecurityGroups
@ -29,8 +27,6 @@ from .subnets import Subnets
from .flow_logs import FlowLogs from .flow_logs import FlowLogs
from .tags import TagResponse from .tags import TagResponse
from .virtual_private_gateways import VirtualPrivateGateways from .virtual_private_gateways import VirtualPrivateGateways
from .vm_export import VMExport
from .vm_import import VMImport
from .vpcs import VPCs from .vpcs import VPCs
from .vpc_service_configuration import VPCEndpointServiceConfiguration from .vpc_service_configuration import VPCEndpointServiceConfiguration
from .vpc_peering_connections import VPCPeeringConnections from .vpc_peering_connections import VPCPeeringConnections
@ -46,7 +42,6 @@ from .carrier_gateways import CarrierGateway
class EC2Response( class EC2Response(
AccountAttributes, AccountAttributes,
AmazonDevPay,
AmisResponse, AmisResponse,
AvailabilityZonesAndRegions, AvailabilityZonesAndRegions,
CustomerGateways, CustomerGateways,
@ -65,7 +60,6 @@ class EC2Response(
LaunchTemplates, LaunchTemplates,
Monitoring, Monitoring,
NetworkACLs, NetworkACLs,
PlacementGroups,
ReservedInstances, ReservedInstances,
RouteTables, RouteTables,
SecurityGroups, SecurityGroups,
@ -76,8 +70,6 @@ class EC2Response(
FlowLogs, FlowLogs,
TagResponse, TagResponse,
VirtualPrivateGateways, VirtualPrivateGateways,
VMExport,
VMImport,
VPCs, VPCs,
VPCEndpointServiceConfiguration, VPCEndpointServiceConfiguration,
VPCPeeringConnections, VPCPeeringConnections,
@ -90,15 +82,9 @@ class EC2Response(
IamInstanceProfiles, IamInstanceProfiles,
CarrierGateway, CarrierGateway,
): ):
def __init__(self): def __init__(self) -> None:
super().__init__(service_name="ec2") super().__init__(service_name="ec2")
@property @property
def ec2_backend(self): def should_autoescape(self) -> bool:
from moto.ec2.models import ec2_backends
return ec2_backends[self.current_account][self.region]
@property
def should_autoescape(self):
return True return True

View File

@ -1,18 +1,27 @@
from typing import Any, Dict
from moto.core.responses import BaseResponse from moto.core.responses import BaseResponse
from ..exceptions import EmptyTagSpecError from ..exceptions import EmptyTagSpecError
from ..utils import convert_tag_spec from ..utils import convert_tag_spec
class EC2BaseResponse(BaseResponse): class EC2BaseResponse(BaseResponse):
def _filters_from_querystring(self): @property
def ec2_backend(self) -> Any: # type: ignore[misc]
from moto.ec2.models import ec2_backends
return ec2_backends[self.current_account][self.region]
def _filters_from_querystring(self) -> Dict[str, str]:
# [{"Name": x1, "Value": y1}, ..] # [{"Name": x1, "Value": y1}, ..]
_filters = self._get_multi_param("Filter.") _filters = self._get_multi_param("Filter.")
# return {x1: y1, ...} # return {x1: y1, ...}
return {f["Name"]: f["Value"] for f in _filters} return {f["Name"]: f["Value"] for f in _filters}
def _parse_tag_specification(self): def _parse_tag_specification(self) -> Dict[str, Dict[str, str]]:
# [{"ResourceType": _type, "Tag": [{"Key": k, "Value": v}, ..]}] # [{"ResourceType": _type, "Tag": [{"Key": k, "Value": v}, ..]}]
tag_spec_set = self._get_multi_param("TagSpecification") tag_spec_set = self._get_multi_param("TagSpecification")
if not tag_spec_set:
tag_spec_set = self._get_multi_param("TagSpecifications")
# If we do not pass any Tags, this method will convert this to [_type] instead # If we do not pass any Tags, this method will convert this to [_type] instead
if isinstance(tag_spec_set, list) and any( if isinstance(tag_spec_set, list) and any(
[isinstance(spec, str) for spec in tag_spec_set] [isinstance(spec, str) for spec in tag_spec_set]

View File

@ -2,7 +2,7 @@ from moto.core.responses import BaseResponse
class AccountAttributes(BaseResponse): class AccountAttributes(BaseResponse):
def describe_account_attributes(self): def describe_account_attributes(self) -> str:
template = self.response_template(DESCRIBE_ACCOUNT_ATTRIBUTES_RESULT) template = self.response_template(DESCRIBE_ACCOUNT_ATTRIBUTES_RESULT)
return template.render() return template.render()

View File

@ -1,8 +0,0 @@
from moto.core.responses import BaseResponse
class AmazonDevPay(BaseResponse):
def confirm_product_instance(self):
raise NotImplementedError(
"AmazonDevPay.confirm_product_instance is not yet implemented"
)

View File

@ -2,15 +2,15 @@ from ._base_response import EC2BaseResponse
class AmisResponse(EC2BaseResponse): class AmisResponse(EC2BaseResponse):
def create_image(self): def create_image(self) -> str:
name = self.querystring.get("Name")[0] name = self.querystring.get("Name")[0] # type: ignore[index]
description = self._get_param("Description", if_none="") description = self._get_param("Description", if_none="")
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
tag_specifications = self._get_multi_param("TagSpecification") tag_specifications = self._get_multi_param("TagSpecification")
self.error_on_dryrun() self.error_on_dryrun()
image = self.ec2_backend.create_image( image = self.ec2_backend.create_image( # type: ignore[attr-defined]
instance_id, instance_id,
name, name,
description, description,
@ -19,7 +19,7 @@ class AmisResponse(EC2BaseResponse):
template = self.response_template(CREATE_IMAGE_RESPONSE) template = self.response_template(CREATE_IMAGE_RESPONSE)
return template.render(image=image) return template.render(image=image)
def copy_image(self): def copy_image(self) -> str:
source_image_id = self._get_param("SourceImageId") source_image_id = self._get_param("SourceImageId")
source_region = self._get_param("SourceRegion") source_region = self._get_param("SourceRegion")
name = self._get_param("Name") name = self._get_param("Name")
@ -33,7 +33,7 @@ class AmisResponse(EC2BaseResponse):
template = self.response_template(COPY_IMAGE_RESPONSE) template = self.response_template(COPY_IMAGE_RESPONSE)
return template.render(image=image) return template.render(image=image)
def deregister_image(self): def deregister_image(self) -> str:
ami_id = self._get_param("ImageId") ami_id = self._get_param("ImageId")
self.error_on_dryrun() self.error_on_dryrun()
@ -42,7 +42,7 @@ class AmisResponse(EC2BaseResponse):
template = self.response_template(DEREGISTER_IMAGE_RESPONSE) template = self.response_template(DEREGISTER_IMAGE_RESPONSE)
return template.render(success="true") return template.render(success="true")
def describe_images(self): def describe_images(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
ami_ids = self._get_multi_param("ImageId") ami_ids = self._get_multi_param("ImageId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
@ -54,14 +54,14 @@ class AmisResponse(EC2BaseResponse):
template = self.response_template(DESCRIBE_IMAGES_RESPONSE) template = self.response_template(DESCRIBE_IMAGES_RESPONSE)
return template.render(images=images) return template.render(images=images)
def describe_image_attribute(self): def describe_image_attribute(self) -> str:
ami_id = self._get_param("ImageId") ami_id = self._get_param("ImageId")
groups = self.ec2_backend.get_launch_permission_groups(ami_id) groups = self.ec2_backend.get_launch_permission_groups(ami_id)
users = self.ec2_backend.get_launch_permission_users(ami_id) users = self.ec2_backend.get_launch_permission_users(ami_id)
template = self.response_template(DESCRIBE_IMAGE_ATTRIBUTES_RESPONSE) template = self.response_template(DESCRIBE_IMAGE_ATTRIBUTES_RESPONSE)
return template.render(ami_id=ami_id, groups=groups, users=users) return template.render(ami_id=ami_id, groups=groups, users=users)
def modify_image_attribute(self): def modify_image_attribute(self) -> str:
ami_id = self._get_param("ImageId") ami_id = self._get_param("ImageId")
operation_type = self._get_param("OperationType") operation_type = self._get_param("OperationType")
group = self._get_param("UserGroup.1") group = self._get_param("UserGroup.1")
@ -79,8 +79,8 @@ class AmisResponse(EC2BaseResponse):
) )
return MODIFY_IMAGE_ATTRIBUTE_RESPONSE return MODIFY_IMAGE_ATTRIBUTE_RESPONSE
def register_image(self): def register_image(self) -> str:
name = self.querystring.get("Name")[0] name = self.querystring.get("Name")[0] # type: ignore[index]
description = self._get_param("Description", if_none="") description = self._get_param("Description", if_none="")
self.error_on_dryrun() self.error_on_dryrun()
@ -89,7 +89,7 @@ class AmisResponse(EC2BaseResponse):
template = self.response_template(REGISTER_IMAGE_RESPONSE) template = self.response_template(REGISTER_IMAGE_RESPONSE)
return template.render(image=image) return template.render(image=image)
def reset_image_attribute(self): def reset_image_attribute(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError("AMIs.reset_image_attribute is not yet implemented") raise NotImplementedError("AMIs.reset_image_attribute is not yet implemented")

View File

@ -1,15 +1,15 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
class AvailabilityZonesAndRegions(BaseResponse): class AvailabilityZonesAndRegions(EC2BaseResponse):
def describe_availability_zones(self): def describe_availability_zones(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
zones = self.ec2_backend.describe_availability_zones(filters) zones = self.ec2_backend.describe_availability_zones(filters)
template = self.response_template(DESCRIBE_ZONES_RESPONSE) template = self.response_template(DESCRIBE_ZONES_RESPONSE)
return template.render(zones=zones) return template.render(zones=zones)
def describe_regions(self): def describe_regions(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
region_names = self._get_multi_param("RegionName") region_names = self._get_multi_param("RegionName")
regions = self.ec2_backend.describe_regions(region_names) regions = self.ec2_backend.describe_regions(region_names)

View File

@ -3,10 +3,10 @@ from ._base_response import EC2BaseResponse
class CarrierGateway(EC2BaseResponse): class CarrierGateway(EC2BaseResponse):
def create_carrier_gateway(self): def create_carrier_gateway(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
tags = self._get_multi_param("TagSpecification") tag_param = self._get_multi_param("TagSpecification")
tags = add_tag_specification(tags) tags = add_tag_specification(tag_param)
carrier_gateway = self.ec2_backend.create_carrier_gateway( carrier_gateway = self.ec2_backend.create_carrier_gateway(
vpc_id=vpc_id, tags=tags vpc_id=vpc_id, tags=tags
@ -14,14 +14,14 @@ class CarrierGateway(EC2BaseResponse):
template = self.response_template(CREATE_CARRIER_GATEWAY_RESPONSE) template = self.response_template(CREATE_CARRIER_GATEWAY_RESPONSE)
return template.render(carrier_gateway=carrier_gateway) return template.render(carrier_gateway=carrier_gateway)
def delete_carrier_gateway(self): def delete_carrier_gateway(self) -> str:
carrier_gateway_id = self._get_param("CarrierGatewayId") carrier_gateway_id = self._get_param("CarrierGatewayId")
carrier_gateway = self.ec2_backend.delete_carrier_gateway(carrier_gateway_id) carrier_gateway = self.ec2_backend.delete_carrier_gateway(carrier_gateway_id)
template = self.response_template(DELETE_CARRIER_GATEWAY_RESPONSE) template = self.response_template(DELETE_CARRIER_GATEWAY_RESPONSE)
return template.render(carrier_gateway=carrier_gateway) return template.render(carrier_gateway=carrier_gateway)
def describe_carrier_gateways(self): def describe_carrier_gateways(self) -> str:
carrier_gateway_ids = self._get_multi_param("CarrierGatewayId") carrier_gateway_ids = self._get_multi_param("CarrierGatewayId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()

View File

@ -2,27 +2,24 @@ from ._base_response import EC2BaseResponse
class CustomerGateways(EC2BaseResponse): class CustomerGateways(EC2BaseResponse):
def create_customer_gateway(self): def create_customer_gateway(self) -> str:
gateway_type = self._get_param("Type") gateway_type = self._get_param("Type")
ip_address = self._get_param("IpAddress") or self._get_param("PublicIp") ip_address = self._get_param("IpAddress") or self._get_param("PublicIp")
bgp_asn = self._get_param("BgpAsn") bgp_asn = self._get_param("BgpAsn")
tags = self._get_multi_param("TagSpecification") tags = self._parse_tag_specification().get("customer-gateway", {})
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags}
customer_gateway = self.ec2_backend.create_customer_gateway( customer_gateway = self.ec2_backend.create_customer_gateway(
gateway_type, ip_address=ip_address, bgp_asn=bgp_asn, tags=tags gateway_type, ip_address=ip_address, bgp_asn=bgp_asn, tags=tags
) )
template = self.response_template(CREATE_CUSTOMER_GATEWAY_RESPONSE) template = self.response_template(CREATE_CUSTOMER_GATEWAY_RESPONSE)
return template.render(customer_gateway=customer_gateway) return template.render(customer_gateway=customer_gateway)
def delete_customer_gateway(self): def delete_customer_gateway(self) -> str:
customer_gateway_id = self._get_param("CustomerGatewayId") customer_gateway_id = self._get_param("CustomerGatewayId")
self.ec2_backend.delete_customer_gateway(customer_gateway_id) self.ec2_backend.delete_customer_gateway(customer_gateway_id)
template = self.response_template(DELETE_CUSTOMER_GATEWAY_RESPONSE) template = self.response_template(DELETE_CUSTOMER_GATEWAY_RESPONSE)
return template.render(delete_status="true") return template.render(delete_status="true")
def describe_customer_gateways(self): def describe_customer_gateways(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
customer_gateway_ids = self._get_multi_param("CustomerGatewayId") customer_gateway_ids = self._get_multi_param("CustomerGatewayId")

View File

@ -2,7 +2,7 @@ from ._base_response import EC2BaseResponse
class DHCPOptions(EC2BaseResponse): class DHCPOptions(EC2BaseResponse):
def associate_dhcp_options(self): def associate_dhcp_options(self) -> str:
dhcp_opt_id = self._get_param("DhcpOptionsId") dhcp_opt_id = self._get_param("DhcpOptionsId")
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
@ -14,17 +14,17 @@ class DHCPOptions(EC2BaseResponse):
template = self.response_template(ASSOCIATE_DHCP_OPTIONS_RESPONSE) template = self.response_template(ASSOCIATE_DHCP_OPTIONS_RESPONSE)
return template.render() return template.render()
def create_dhcp_options(self): def create_dhcp_options(self) -> str:
dhcp_config = self._get_multi_param("DhcpConfiguration") provided_config = self._get_multi_param("DhcpConfiguration")
dhcp_config = {f["Key"]: f["Value"] for f in dhcp_config} flat_config = {f["Key"]: f["Value"] for f in provided_config}
# TODO validate we only got the options we know about # TODO validate we only got the options we know about
domain_name_servers = dhcp_config.get("domain-name-servers", None) domain_name_servers = flat_config.get("domain-name-servers", None)
domain_name = dhcp_config.get("domain-name", None) domain_name = flat_config.get("domain-name", None)
ntp_servers = dhcp_config.get("ntp-servers", None) ntp_servers = flat_config.get("ntp-servers", None)
netbios_name_servers = dhcp_config.get("netbios-name-servers", None) netbios_name_servers = flat_config.get("netbios-name-servers", None)
netbios_node_type = dhcp_config.get("netbios-node-type", None) netbios_node_type = flat_config.get("netbios-node-type", None)
dhcp_options_set = self.ec2_backend.create_dhcp_options( dhcp_options_set = self.ec2_backend.create_dhcp_options(
domain_name_servers=domain_name_servers, domain_name_servers=domain_name_servers,
@ -37,13 +37,13 @@ class DHCPOptions(EC2BaseResponse):
template = self.response_template(CREATE_DHCP_OPTIONS_RESPONSE) template = self.response_template(CREATE_DHCP_OPTIONS_RESPONSE)
return template.render(dhcp_options_set=dhcp_options_set) return template.render(dhcp_options_set=dhcp_options_set)
def delete_dhcp_options(self): def delete_dhcp_options(self) -> str:
dhcp_opt_id = self._get_param("DhcpOptionsId") dhcp_opt_id = self._get_param("DhcpOptionsId")
self.ec2_backend.delete_dhcp_options_set(dhcp_opt_id) self.ec2_backend.delete_dhcp_options_set(dhcp_opt_id)
template = self.response_template(DELETE_DHCP_OPTIONS_RESPONSE) template = self.response_template(DELETE_DHCP_OPTIONS_RESPONSE)
return template.render(delete_status="true") return template.render(delete_status="true")
def describe_dhcp_options(self): def describe_dhcp_options(self) -> str:
dhcp_opt_ids = self._get_multi_param("DhcpOptionsId") dhcp_opt_ids = self._get_multi_param("DhcpOptionsId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
dhcp_opts = self.ec2_backend.describe_dhcp_options(dhcp_opt_ids, filters) dhcp_opts = self.ec2_backend.describe_dhcp_options(dhcp_opt_ids, filters)

View File

@ -1,12 +1,12 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
from moto.ec2.utils import add_tag_specification from moto.ec2.utils import add_tag_specification
class EgressOnlyInternetGateway(BaseResponse): class EgressOnlyInternetGateway(EC2BaseResponse):
def create_egress_only_internet_gateway(self): def create_egress_only_internet_gateway(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
tags = self._get_multi_param("TagSpecification") tag_param = self._get_multi_param("TagSpecification")
tags = add_tag_specification(tags) tags = add_tag_specification(tag_param)
egress_only_igw = self.ec2_backend.create_egress_only_internet_gateway( egress_only_igw = self.ec2_backend.create_egress_only_internet_gateway(
vpc_id=vpc_id, tags=tags vpc_id=vpc_id, tags=tags
@ -14,7 +14,7 @@ class EgressOnlyInternetGateway(BaseResponse):
template = self.response_template(CREATE_EGRESS_ONLY_IGW_RESPONSE) template = self.response_template(CREATE_EGRESS_ONLY_IGW_RESPONSE)
return template.render(egress_only_igw=egress_only_igw) return template.render(egress_only_igw=egress_only_igw)
def describe_egress_only_internet_gateways(self): def describe_egress_only_internet_gateways(self) -> str:
egress_only_igw_ids = self._get_multi_param("EgressOnlyInternetGatewayId") egress_only_igw_ids = self._get_multi_param("EgressOnlyInternetGatewayId")
egress_only_igws = self.ec2_backend.describe_egress_only_internet_gateways( egress_only_igws = self.ec2_backend.describe_egress_only_internet_gateways(
egress_only_igw_ids egress_only_igw_ids
@ -22,7 +22,7 @@ class EgressOnlyInternetGateway(BaseResponse):
template = self.response_template(DESCRIBE_EGRESS_ONLY_IGW_RESPONSE) template = self.response_template(DESCRIBE_EGRESS_ONLY_IGW_RESPONSE)
return template.render(egress_only_igws=egress_only_igws) return template.render(egress_only_igws=egress_only_igws)
def delete_egress_only_internet_gateway(self): def delete_egress_only_internet_gateway(self) -> str:
egress_only_igw_id = self._get_param("EgressOnlyInternetGatewayId") egress_only_igw_id = self._get_param("EgressOnlyInternetGatewayId")
self.ec2_backend.delete_egress_only_internet_gateway( self.ec2_backend.delete_egress_only_internet_gateway(
gateway_id=egress_only_igw_id gateway_id=egress_only_igw_id

View File

@ -2,7 +2,7 @@ from ._base_response import EC2BaseResponse
class ElasticBlockStore(EC2BaseResponse): class ElasticBlockStore(EC2BaseResponse):
def attach_volume(self): def attach_volume(self) -> str:
volume_id = self._get_param("VolumeId") volume_id = self._get_param("VolumeId")
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
device_path = self._get_param("Device") device_path = self._get_param("Device")
@ -13,7 +13,7 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(ATTACHED_VOLUME_RESPONSE) template = self.response_template(ATTACHED_VOLUME_RESPONSE)
return template.render(attachment=attachment) return template.render(attachment=attachment)
def copy_snapshot(self): def copy_snapshot(self) -> str:
source_snapshot_id = self._get_param("SourceSnapshotId") source_snapshot_id = self._get_param("SourceSnapshotId")
source_region = self._get_param("SourceRegion") source_region = self._get_param("SourceRegion")
description = self._get_param("Description") description = self._get_param("Description")
@ -29,7 +29,7 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(COPY_SNAPSHOT_RESPONSE) template = self.response_template(COPY_SNAPSHOT_RESPONSE)
return template.render(snapshot=snapshot) return template.render(snapshot=snapshot)
def create_snapshot(self): def create_snapshot(self) -> str:
volume_id = self._get_param("VolumeId") volume_id = self._get_param("VolumeId")
description = self._get_param("Description") description = self._get_param("Description")
tags = self._parse_tag_specification() tags = self._parse_tag_specification()
@ -42,7 +42,7 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(CREATE_SNAPSHOT_RESPONSE) template = self.response_template(CREATE_SNAPSHOT_RESPONSE)
return template.render(snapshot=snapshot) return template.render(snapshot=snapshot)
def create_snapshots(self): def create_snapshots(self) -> str:
params = self._get_params() params = self._get_params()
instance_spec = params.get("InstanceSpecification") instance_spec = params.get("InstanceSpecification")
description = params.get("Description", "") description = params.get("Description", "")
@ -57,7 +57,7 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(CREATE_SNAPSHOTS_RESPONSE) template = self.response_template(CREATE_SNAPSHOTS_RESPONSE)
return template.render(snapshots=snapshots) return template.render(snapshots=snapshots)
def create_volume(self): def create_volume(self) -> str:
size = self._get_param("Size") size = self._get_param("Size")
zone = self._get_param("AvailabilityZone") zone = self._get_param("AvailabilityZone")
snapshot_id = self._get_param("SnapshotId") snapshot_id = self._get_param("SnapshotId")
@ -83,7 +83,7 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(CREATE_VOLUME_RESPONSE) template = self.response_template(CREATE_VOLUME_RESPONSE)
return template.render(volume=volume) return template.render(volume=volume)
def modify_volume(self): def modify_volume(self) -> str:
volume_id = self._get_param("VolumeId") volume_id = self._get_param("VolumeId")
target_size = self._get_param("Size") target_size = self._get_param("Size")
target_volume_type = self._get_param("VolumeType") target_volume_type = self._get_param("VolumeType")
@ -96,7 +96,7 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(MODIFY_VOLUME_RESPONSE) template = self.response_template(MODIFY_VOLUME_RESPONSE)
return template.render(volume=volume) return template.render(volume=volume)
def describe_volumes_modifications(self): def describe_volumes_modifications(self) -> str:
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
volume_ids = self._get_multi_param("VolumeId") volume_ids = self._get_multi_param("VolumeId")
modifications = self.ec2_backend.describe_volumes_modifications( modifications = self.ec2_backend.describe_volumes_modifications(
@ -105,7 +105,7 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(DESCRIBE_VOLUMES_MODIFICATIONS_RESPONSE) template = self.response_template(DESCRIBE_VOLUMES_MODIFICATIONS_RESPONSE)
return template.render(modifications=modifications) return template.render(modifications=modifications)
def delete_snapshot(self): def delete_snapshot(self) -> str:
snapshot_id = self._get_param("SnapshotId") snapshot_id = self._get_param("SnapshotId")
self.error_on_dryrun() self.error_on_dryrun()
@ -113,7 +113,7 @@ class ElasticBlockStore(EC2BaseResponse):
self.ec2_backend.delete_snapshot(snapshot_id) self.ec2_backend.delete_snapshot(snapshot_id)
return DELETE_SNAPSHOT_RESPONSE return DELETE_SNAPSHOT_RESPONSE
def delete_volume(self): def delete_volume(self) -> str:
volume_id = self._get_param("VolumeId") volume_id = self._get_param("VolumeId")
self.error_on_dryrun() self.error_on_dryrun()
@ -121,7 +121,7 @@ class ElasticBlockStore(EC2BaseResponse):
self.ec2_backend.delete_volume(volume_id) self.ec2_backend.delete_volume(volume_id)
return DELETE_VOLUME_RESPONSE return DELETE_VOLUME_RESPONSE
def describe_snapshots(self): def describe_snapshots(self) -> str:
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
snapshot_ids = self._get_multi_param("SnapshotId") snapshot_ids = self._get_multi_param("SnapshotId")
snapshots = self.ec2_backend.describe_snapshots( snapshots = self.ec2_backend.describe_snapshots(
@ -130,7 +130,7 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(DESCRIBE_SNAPSHOTS_RESPONSE) template = self.response_template(DESCRIBE_SNAPSHOTS_RESPONSE)
return template.render(snapshots=snapshots) return template.render(snapshots=snapshots)
def describe_volumes(self): def describe_volumes(self) -> str:
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
volume_ids = self._get_multi_param("VolumeId") volume_ids = self._get_multi_param("VolumeId")
volumes = self.ec2_backend.describe_volumes( volumes = self.ec2_backend.describe_volumes(
@ -139,17 +139,17 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(DESCRIBE_VOLUMES_RESPONSE) template = self.response_template(DESCRIBE_VOLUMES_RESPONSE)
return template.render(volumes=volumes) return template.render(volumes=volumes)
def describe_volume_attribute(self): def describe_volume_attribute(self) -> str:
raise NotImplementedError( raise NotImplementedError(
"ElasticBlockStore.describe_volume_attribute is not yet implemented" "ElasticBlockStore.describe_volume_attribute is not yet implemented"
) )
def describe_volume_status(self): def describe_volume_status(self) -> str:
raise NotImplementedError( raise NotImplementedError(
"ElasticBlockStore.describe_volume_status is not yet implemented" "ElasticBlockStore.describe_volume_status is not yet implemented"
) )
def detach_volume(self): def detach_volume(self) -> str:
volume_id = self._get_param("VolumeId") volume_id = self._get_param("VolumeId")
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
device_path = self._get_param("Device") device_path = self._get_param("Device")
@ -160,28 +160,28 @@ class ElasticBlockStore(EC2BaseResponse):
template = self.response_template(DETATCH_VOLUME_RESPONSE) template = self.response_template(DETATCH_VOLUME_RESPONSE)
return template.render(attachment=attachment) return template.render(attachment=attachment)
def enable_volume_io(self): def enable_volume_io(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"ElasticBlockStore.enable_volume_io is not yet implemented" "ElasticBlockStore.enable_volume_io is not yet implemented"
) )
def import_volume(self): def import_volume(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"ElasticBlockStore.import_volume is not yet implemented" "ElasticBlockStore.import_volume is not yet implemented"
) )
def describe_snapshot_attribute(self): def describe_snapshot_attribute(self) -> str:
snapshot_id = self._get_param("SnapshotId") snapshot_id = self._get_param("SnapshotId")
groups = self.ec2_backend.get_create_volume_permission_groups(snapshot_id) groups = self.ec2_backend.get_create_volume_permission_groups(snapshot_id)
user_ids = self.ec2_backend.get_create_volume_permission_userids(snapshot_id) user_ids = self.ec2_backend.get_create_volume_permission_userids(snapshot_id)
template = self.response_template(DESCRIBE_SNAPSHOT_ATTRIBUTES_RESPONSE) template = self.response_template(DESCRIBE_SNAPSHOT_ATTRIBUTES_RESPONSE)
return template.render(snapshot_id=snapshot_id, groups=groups, userIds=user_ids) return template.render(snapshot_id=snapshot_id, groups=groups, userIds=user_ids)
def modify_snapshot_attribute(self): def modify_snapshot_attribute(self) -> str:
snapshot_id = self._get_param("SnapshotId") snapshot_id = self._get_param("SnapshotId")
operation_type = self._get_param("OperationType") operation_type = self._get_param("OperationType")
groups = self._get_multi_param("UserGroup") groups = self._get_multi_param("UserGroup")
@ -199,14 +199,14 @@ class ElasticBlockStore(EC2BaseResponse):
) )
return MODIFY_SNAPSHOT_ATTRIBUTE_RESPONSE return MODIFY_SNAPSHOT_ATTRIBUTE_RESPONSE
def modify_volume_attribute(self): def modify_volume_attribute(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"ElasticBlockStore.modify_volume_attribute is not yet implemented" "ElasticBlockStore.modify_volume_attribute is not yet implemented"
) )
def reset_snapshot_attribute(self): def reset_snapshot_attribute(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(

View File

@ -3,11 +3,11 @@ from ._base_response import EC2BaseResponse
class ElasticIPAddresses(EC2BaseResponse): class ElasticIPAddresses(EC2BaseResponse):
def allocate_address(self): def allocate_address(self) -> str:
domain = self._get_param("Domain", if_none=None) domain = self._get_param("Domain", if_none=None)
reallocate_address = self._get_param("Address", if_none=None) reallocate_address = self._get_param("Address", if_none=None)
tags = self._get_multi_param("TagSpecification") tag_param = self._get_multi_param("TagSpecification")
tags = add_tag_specification(tags) tags = add_tag_specification(tag_param)
self.error_on_dryrun() self.error_on_dryrun()
@ -20,7 +20,7 @@ class ElasticIPAddresses(EC2BaseResponse):
template = self.response_template(ALLOCATE_ADDRESS_RESPONSE) template = self.response_template(ALLOCATE_ADDRESS_RESPONSE)
return template.render(address=address) return template.render(address=address)
def associate_address(self): def associate_address(self) -> str:
instance = eni = None instance = eni = None
if "InstanceId" in self.querystring: if "InstanceId" in self.querystring:
@ -70,7 +70,7 @@ class ElasticIPAddresses(EC2BaseResponse):
template = self.response_template(ASSOCIATE_ADDRESS_RESPONSE) template = self.response_template(ASSOCIATE_ADDRESS_RESPONSE)
return template.render(address=eip) return template.render(address=eip)
def describe_addresses(self): def describe_addresses(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
allocation_ids = self._get_multi_param("AllocationId") allocation_ids = self._get_multi_param("AllocationId")
public_ips = self._get_multi_param("PublicIp") public_ips = self._get_multi_param("PublicIp")
@ -81,7 +81,7 @@ class ElasticIPAddresses(EC2BaseResponse):
template = self.response_template(DESCRIBE_ADDRESS_RESPONSE) template = self.response_template(DESCRIBE_ADDRESS_RESPONSE)
return template.render(addresses=addresses) return template.render(addresses=addresses)
def disassociate_address(self): def disassociate_address(self) -> str:
if ( if (
"PublicIp" not in self.querystring "PublicIp" not in self.querystring
and "AssociationId" not in self.querystring and "AssociationId" not in self.querystring
@ -102,7 +102,7 @@ class ElasticIPAddresses(EC2BaseResponse):
return self.response_template(DISASSOCIATE_ADDRESS_RESPONSE).render() return self.response_template(DISASSOCIATE_ADDRESS_RESPONSE).render()
def release_address(self): def release_address(self) -> str:
if ( if (
"PublicIp" not in self.querystring "PublicIp" not in self.querystring
and "AllocationId" not in self.querystring and "AllocationId" not in self.querystring

View File

@ -4,7 +4,7 @@ from ._base_response import EC2BaseResponse
class ElasticNetworkInterfaces(EC2BaseResponse): class ElasticNetworkInterfaces(EC2BaseResponse):
def create_network_interface(self): def create_network_interface(self) -> str:
subnet_id = self._get_param("SubnetId") subnet_id = self._get_param("SubnetId")
private_ip_address = self._get_param("PrivateIpAddress") private_ip_address = self._get_param("PrivateIpAddress")
private_ip_addresses = self._get_multi_param("PrivateIpAddresses") private_ip_addresses = self._get_multi_param("PrivateIpAddresses")
@ -14,8 +14,7 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
groups = self._get_multi_param("SecurityGroupId") groups = self._get_multi_param("SecurityGroupId")
subnet = self.ec2_backend.get_subnet(subnet_id) subnet = self.ec2_backend.get_subnet(subnet_id)
description = self._get_param("Description") description = self._get_param("Description")
tags = self._get_multi_param("TagSpecification") tags = add_tag_specification(self._get_multi_param("TagSpecification"))
tags = add_tag_specification(tags)
self.error_on_dryrun() self.error_on_dryrun()
@ -33,7 +32,7 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
template = self.response_template(CREATE_NETWORK_INTERFACE_RESPONSE) template = self.response_template(CREATE_NETWORK_INTERFACE_RESPONSE)
return template.render(eni=eni) return template.render(eni=eni)
def delete_network_interface(self): def delete_network_interface(self) -> str:
eni_id = self._get_param("NetworkInterfaceId") eni_id = self._get_param("NetworkInterfaceId")
self.error_on_dryrun() self.error_on_dryrun()
@ -42,7 +41,7 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
template = self.response_template(DELETE_NETWORK_INTERFACE_RESPONSE) template = self.response_template(DELETE_NETWORK_INTERFACE_RESPONSE)
return template.render() return template.render()
def describe_network_interface_attribute(self): def describe_network_interface_attribute(self) -> str:
eni_id = self._get_param("NetworkInterfaceId") eni_id = self._get_param("NetworkInterfaceId")
attribute = self._get_param("Attribute") attribute = self._get_param("Attribute")
@ -70,7 +69,7 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
raise InvalidParameterValueErrorUnknownAttribute(attribute) raise InvalidParameterValueErrorUnknownAttribute(attribute)
return template.render(eni=eni) return template.render(eni=eni)
def describe_network_interfaces(self): def describe_network_interfaces(self) -> str:
eni_ids = self._get_multi_param("NetworkInterfaceId") eni_ids = self._get_multi_param("NetworkInterfaceId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
@ -80,7 +79,7 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
template = self.response_template(DESCRIBE_NETWORK_INTERFACES_RESPONSE) template = self.response_template(DESCRIBE_NETWORK_INTERFACES_RESPONSE)
return template.render(enis=enis) return template.render(enis=enis)
def attach_network_interface(self): def attach_network_interface(self) -> str:
eni_id = self._get_param("NetworkInterfaceId") eni_id = self._get_param("NetworkInterfaceId")
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
device_index = self._get_param("DeviceIndex") device_index = self._get_param("DeviceIndex")
@ -93,7 +92,7 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
template = self.response_template(ATTACH_NETWORK_INTERFACE_RESPONSE) template = self.response_template(ATTACH_NETWORK_INTERFACE_RESPONSE)
return template.render(attachment_id=attachment_id) return template.render(attachment_id=attachment_id)
def detach_network_interface(self): def detach_network_interface(self) -> str:
attachment_id = self._get_param("AttachmentId") attachment_id = self._get_param("AttachmentId")
self.error_on_dryrun() self.error_on_dryrun()
@ -102,7 +101,7 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
template = self.response_template(DETACH_NETWORK_INTERFACE_RESPONSE) template = self.response_template(DETACH_NETWORK_INTERFACE_RESPONSE)
return template.render() return template.render()
def modify_network_interface_attribute(self): def modify_network_interface_attribute(self) -> str:
eni_id = self._get_param("NetworkInterfaceId") eni_id = self._get_param("NetworkInterfaceId")
group_ids = self._get_multi_param("SecurityGroupId") group_ids = self._get_multi_param("SecurityGroupId")
source_dest_check = get_attribute_value("SourceDestCheck", self.querystring) source_dest_check = get_attribute_value("SourceDestCheck", self.querystring)
@ -115,28 +114,28 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
) )
return MODIFY_NETWORK_INTERFACE_ATTRIBUTE_RESPONSE return MODIFY_NETWORK_INTERFACE_ATTRIBUTE_RESPONSE
def reset_network_interface_attribute(self): def reset_network_interface_attribute(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"ElasticNetworkInterfaces(AmazonVPC).reset_network_interface_attribute is not yet implemented" "ElasticNetworkInterfaces(AmazonVPC).reset_network_interface_attribute is not yet implemented"
) )
def assign_private_ip_addresses(self): def assign_private_ip_addresses(self) -> str:
eni_id = self._get_param("NetworkInterfaceId") eni_id = self._get_param("NetworkInterfaceId")
secondary_ips_count = self._get_int_param("SecondaryPrivateIpAddressCount", 0) secondary_ips_count = self._get_int_param("SecondaryPrivateIpAddressCount", 0)
eni = self.ec2_backend.assign_private_ip_addresses(eni_id, secondary_ips_count) eni = self.ec2_backend.assign_private_ip_addresses(eni_id, secondary_ips_count)
template = self.response_template(ASSIGN_PRIVATE_IP_ADDRESSES) template = self.response_template(ASSIGN_PRIVATE_IP_ADDRESSES)
return template.render(eni=eni) return template.render(eni=eni)
def unassign_private_ip_addresses(self): def unassign_private_ip_addresses(self) -> str:
eni_id = self._get_param("NetworkInterfaceId") eni_id = self._get_param("NetworkInterfaceId")
private_ip_address = self._get_multi_param("PrivateIpAddress") private_ip_address = self._get_multi_param("PrivateIpAddress")
eni = self.ec2_backend.unassign_private_ip_addresses(eni_id, private_ip_address) eni = self.ec2_backend.unassign_private_ip_addresses(eni_id, private_ip_address)
template = self.response_template(UNASSIGN_PRIVATE_IP_ADDRESSES) template = self.response_template(UNASSIGN_PRIVATE_IP_ADDRESSES)
return template.render(eni=eni) return template.render(eni=eni)
def assign_ipv6_addresses(self): def assign_ipv6_addresses(self) -> str:
eni_id = self._get_param("NetworkInterfaceId") eni_id = self._get_param("NetworkInterfaceId")
ipv6_count = self._get_int_param("Ipv6AddressCount", 0) ipv6_count = self._get_int_param("Ipv6AddressCount", 0)
ipv6_addresses = self._get_multi_param("Ipv6Addresses") ipv6_addresses = self._get_multi_param("Ipv6Addresses")
@ -144,7 +143,7 @@ class ElasticNetworkInterfaces(EC2BaseResponse):
template = self.response_template(ASSIGN_IPV6_ADDRESSES) template = self.response_template(ASSIGN_IPV6_ADDRESSES)
return template.render(eni=eni) return template.render(eni=eni)
def unassign_ipv6_addresses(self): def unassign_ipv6_addresses(self) -> str:
eni_id = self._get_param("NetworkInterfaceId") eni_id = self._get_param("NetworkInterfaceId")
ips = self._get_multi_param("Ipv6Addresses") ips = self._get_multi_param("Ipv6Addresses")
eni = self.ec2_backend.unassign_ipv6_addresses(eni_id, ips) eni = self.ec2_backend.unassign_ipv6_addresses(eni_id, ips)

View File

@ -1,22 +1,22 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
class Fleets(BaseResponse): class Fleets(EC2BaseResponse):
def delete_fleets(self): def delete_fleets(self) -> str:
fleet_ids = self._get_multi_param("FleetId.") fleet_ids = self._get_multi_param("FleetId.")
terminate_instances = self._get_param("TerminateInstances") terminate_instances = self._get_param("TerminateInstances")
fleets = self.ec2_backend.delete_fleets(fleet_ids, terminate_instances) fleets = self.ec2_backend.delete_fleets(fleet_ids, terminate_instances)
template = self.response_template(DELETE_FLEETS_TEMPLATE) template = self.response_template(DELETE_FLEETS_TEMPLATE)
return template.render(fleets=fleets) return template.render(fleets=fleets)
def describe_fleet_instances(self): def describe_fleet_instances(self) -> str:
fleet_id = self._get_param("FleetId") fleet_id = self._get_param("FleetId")
instances = self.ec2_backend.describe_fleet_instances(fleet_id) instances = self.ec2_backend.describe_fleet_instances(fleet_id)
template = self.response_template(DESCRIBE_FLEET_INSTANCES_TEMPLATE) template = self.response_template(DESCRIBE_FLEET_INSTANCES_TEMPLATE)
return template.render(fleet_id=fleet_id, instances=instances) return template.render(fleet_id=fleet_id, instances=instances)
def describe_fleets(self): def describe_fleets(self) -> str:
fleet_ids = self._get_multi_param("FleetId.") fleet_ids = self._get_multi_param("FleetId.")
requests = self.ec2_backend.describe_fleets(fleet_ids) requests = self.ec2_backend.describe_fleets(fleet_ids)
@ -24,7 +24,7 @@ class Fleets(BaseResponse):
rend = template.render(requests=requests) rend = template.render(requests=requests)
return rend return rend
def create_fleet(self): def create_fleet(self) -> str:
on_demand_options = self._get_multi_param_dict("OnDemandOptions") on_demand_options = self._get_multi_param_dict("OnDemandOptions")
spot_options = self._get_multi_param_dict("SpotOptions") spot_options = self._get_multi_param_dict("SpotOptions")
target_capacity_specification = self._get_multi_param_dict( target_capacity_specification = self._get_multi_param_dict(

View File

@ -3,7 +3,7 @@ from ._base_response import EC2BaseResponse
class FlowLogs(EC2BaseResponse): class FlowLogs(EC2BaseResponse):
def create_flow_logs(self): def create_flow_logs(self) -> str:
resource_type = self._get_param("ResourceType") resource_type = self._get_param("ResourceType")
resource_ids = self._get_multi_param("ResourceId") resource_ids = self._get_multi_param("ResourceId")
traffic_type = self._get_param("TrafficType") traffic_type = self._get_param("TrafficType")
@ -15,8 +15,7 @@ class FlowLogs(EC2BaseResponse):
max_aggregation_interval = self._get_param("MaxAggregationInterval") max_aggregation_interval = self._get_param("MaxAggregationInterval")
validate_resource_ids(resource_ids) validate_resource_ids(resource_ids)
tags = self._parse_tag_specification() tags = self._parse_tag_specification().get("vpc-flow-log", {})
tags = tags.get("vpc-flow-log", {})
self.error_on_dryrun() self.error_on_dryrun()
@ -36,7 +35,7 @@ class FlowLogs(EC2BaseResponse):
template = self.response_template(CREATE_FLOW_LOGS_RESPONSE) template = self.response_template(CREATE_FLOW_LOGS_RESPONSE)
return template.render(flow_logs=flow_logs, errors=errors) return template.render(flow_logs=flow_logs, errors=errors)
def describe_flow_logs(self): def describe_flow_logs(self) -> str:
flow_log_ids = self._get_multi_param("FlowLogId") flow_log_ids = self._get_multi_param("FlowLogId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
flow_logs = self.ec2_backend.describe_flow_logs(flow_log_ids, filters) flow_logs = self.ec2_backend.describe_flow_logs(flow_log_ids, filters)
@ -46,7 +45,7 @@ class FlowLogs(EC2BaseResponse):
template = self.response_template(DESCRIBE_FLOW_LOGS_RESPONSE) template = self.response_template(DESCRIBE_FLOW_LOGS_RESPONSE)
return template.render(flow_logs=flow_logs) return template.render(flow_logs=flow_logs)
def delete_flow_logs(self): def delete_flow_logs(self) -> str:
flow_log_ids = self._get_multi_param("FlowLogId") flow_log_ids = self._get_multi_param("FlowLogId")
self.error_on_dryrun() self.error_on_dryrun()

View File

@ -1,8 +1,8 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
class General(BaseResponse): class General(EC2BaseResponse):
def get_console_output(self): def get_console_output(self) -> str:
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
if not instance_id: if not instance_id:
# For compatibility with boto. # For compatibility with boto.

View File

@ -2,9 +2,9 @@ from ._base_response import EC2BaseResponse
class HostsResponse(EC2BaseResponse): class HostsResponse(EC2BaseResponse):
def allocate_hosts(self): def allocate_hosts(self) -> str:
params = self._get_params() params = self._get_params()
quantity = int(params.get("Quantity")) quantity = int(params.get("Quantity")) # type: ignore
host_recovery = params.get("HostRecovery") host_recovery = params.get("HostRecovery")
zone = params.get("AvailabilityZone") zone = params.get("AvailabilityZone")
instance_type = params.get("InstanceType") instance_type = params.get("InstanceType")
@ -24,14 +24,14 @@ class HostsResponse(EC2BaseResponse):
template = self.response_template(EC2_ALLOCATE_HOSTS) template = self.response_template(EC2_ALLOCATE_HOSTS)
return template.render(host_ids=host_ids) return template.render(host_ids=host_ids)
def describe_hosts(self): def describe_hosts(self) -> str:
host_ids = list(self._get_params().get("HostId", {}).values()) host_ids = list(self._get_params().get("HostId", {}).values())
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
hosts = self.ec2_backend.describe_hosts(host_ids, filters) hosts = self.ec2_backend.describe_hosts(host_ids, filters)
template = self.response_template(EC2_DESCRIBE_HOSTS) template = self.response_template(EC2_DESCRIBE_HOSTS)
return template.render(account_id=self.current_account, hosts=hosts) return template.render(account_id=self.current_account, hosts=hosts)
def modify_hosts(self): def modify_hosts(self) -> str:
params = self._get_params() params = self._get_params()
host_ids = list(self._get_params().get("HostId", {}).values()) host_ids = list(self._get_params().get("HostId", {}).values())
auto_placement = params.get("AutoPlacement") auto_placement = params.get("AutoPlacement")
@ -44,7 +44,7 @@ class HostsResponse(EC2BaseResponse):
template = self.response_template(EC2_MODIFY_HOSTS) template = self.response_template(EC2_MODIFY_HOSTS)
return template.render(host_ids=host_ids) return template.render(host_ids=host_ids)
def release_hosts(self): def release_hosts(self) -> str:
host_ids = list(self._get_params().get("HostId", {}).values()) host_ids = list(self._get_params().get("HostId", {}).values())
self.ec2_backend.release_hosts(host_ids) self.ec2_backend.release_hosts(host_ids)
template = self.response_template(EC2_RELEASE_HOSTS) template = self.response_template(EC2_RELEASE_HOSTS)

View File

@ -1,8 +1,8 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
class IamInstanceProfiles(BaseResponse): class IamInstanceProfiles(EC2BaseResponse):
def associate_iam_instance_profile(self): def associate_iam_instance_profile(self) -> str:
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
iam_instance_profile_name = self._get_param("IamInstanceProfile.Name") iam_instance_profile_name = self._get_param("IamInstanceProfile.Name")
iam_instance_profile_arn = self._get_param("IamInstanceProfile.Arn") iam_instance_profile_arn = self._get_param("IamInstanceProfile.Arn")
@ -12,7 +12,7 @@ class IamInstanceProfiles(BaseResponse):
template = self.response_template(IAM_INSTANCE_PROFILE_RESPONSE) template = self.response_template(IAM_INSTANCE_PROFILE_RESPONSE)
return template.render(iam_association=iam_association, state="associating") return template.render(iam_association=iam_association, state="associating")
def describe_iam_instance_profile_associations(self): def describe_iam_instance_profile_associations(self) -> str:
association_ids = self._get_multi_param("AssociationId") association_ids = self._get_multi_param("AssociationId")
filters = self._get_object_map("Filter") filters = self._get_object_map("Filter")
max_items = self._get_param("MaxItems") max_items = self._get_param("MaxItems")
@ -26,7 +26,7 @@ class IamInstanceProfiles(BaseResponse):
template = self.response_template(DESCRIBE_IAM_INSTANCE_PROFILE_RESPONSE) template = self.response_template(DESCRIBE_IAM_INSTANCE_PROFILE_RESPONSE)
return template.render(iam_associations=iam_associations, next_token=next_token) return template.render(iam_associations=iam_associations, next_token=next_token)
def disassociate_iam_instance_profile(self): def disassociate_iam_instance_profile(self) -> str:
association_id = self._get_param("AssociationId") association_id = self._get_param("AssociationId")
iam_association = self.ec2_backend.disassociate_iam_instance_profile( iam_association = self.ec2_backend.disassociate_iam_instance_profile(
association_id association_id
@ -34,7 +34,7 @@ class IamInstanceProfiles(BaseResponse):
template = self.response_template(IAM_INSTANCE_PROFILE_RESPONSE) template = self.response_template(IAM_INSTANCE_PROFILE_RESPONSE)
return template.render(iam_association=iam_association, state="disassociating") return template.render(iam_association=iam_association, state="disassociating")
def replace_iam_instance_profile_association(self): def replace_iam_instance_profile_association(self) -> str:
association_id = self._get_param("AssociationId") association_id = self._get_param("AssociationId")
iam_instance_profile_name = self._get_param("IamInstanceProfile.Name") iam_instance_profile_name = self._get_param("IamInstanceProfile.Name")
iam_instance_profile_arn = self._get_param("IamInstanceProfile.Arn") iam_instance_profile_arn = self._get_param("IamInstanceProfile.Arn")

View File

@ -1,3 +1,4 @@
from typing import Any, Dict, List, Optional
from moto.core.utils import camelcase_to_underscores from moto.core.utils import camelcase_to_underscores
from moto.ec2.exceptions import ( from moto.ec2.exceptions import (
MissingParameterError, MissingParameterError,
@ -11,7 +12,7 @@ from ._base_response import EC2BaseResponse
class InstanceResponse(EC2BaseResponse): class InstanceResponse(EC2BaseResponse):
def describe_instances(self): def describe_instances(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
filter_dict = self._filters_from_querystring() filter_dict = self._filters_from_querystring()
instance_ids = self._get_multi_param("InstanceId") instance_ids = self._get_multi_param("InstanceId")
@ -44,7 +45,7 @@ class InstanceResponse(EC2BaseResponse):
.replace("False", "false") .replace("False", "false")
) )
def run_instances(self): def run_instances(self) -> str:
min_count = int(self._get_param("MinCount", if_none="1")) min_count = int(self._get_param("MinCount", if_none="1"))
image_id = self._get_param("ImageId") image_id = self._get_param("ImageId")
owner_id = self._get_param("OwnerId") owner_id = self._get_param("OwnerId")
@ -108,7 +109,7 @@ class InstanceResponse(EC2BaseResponse):
account_id=self.current_account, reservation=new_reservation account_id=self.current_account, reservation=new_reservation
) )
def terminate_instances(self): def terminate_instances(self) -> str:
instance_ids = self._get_multi_param("InstanceId") instance_ids = self._get_multi_param("InstanceId")
self.error_on_dryrun() self.error_on_dryrun()
@ -126,7 +127,7 @@ class InstanceResponse(EC2BaseResponse):
template = self.response_template(EC2_TERMINATE_INSTANCES) template = self.response_template(EC2_TERMINATE_INSTANCES)
return template.render(instances=instances) return template.render(instances=instances)
def reboot_instances(self): def reboot_instances(self) -> str:
instance_ids = self._get_multi_param("InstanceId") instance_ids = self._get_multi_param("InstanceId")
self.error_on_dryrun() self.error_on_dryrun()
@ -135,7 +136,7 @@ class InstanceResponse(EC2BaseResponse):
template = self.response_template(EC2_REBOOT_INSTANCES) template = self.response_template(EC2_REBOOT_INSTANCES)
return template.render(instances=instances) return template.render(instances=instances)
def stop_instances(self): def stop_instances(self) -> str:
instance_ids = self._get_multi_param("InstanceId") instance_ids = self._get_multi_param("InstanceId")
self.error_on_dryrun() self.error_on_dryrun()
@ -144,7 +145,7 @@ class InstanceResponse(EC2BaseResponse):
template = self.response_template(EC2_STOP_INSTANCES) template = self.response_template(EC2_STOP_INSTANCES)
return template.render(instances=instances) return template.render(instances=instances)
def start_instances(self): def start_instances(self) -> str:
instance_ids = self._get_multi_param("InstanceId") instance_ids = self._get_multi_param("InstanceId")
self.error_on_dryrun() self.error_on_dryrun()
@ -152,7 +153,9 @@ class InstanceResponse(EC2BaseResponse):
template = self.response_template(EC2_START_INSTANCES) template = self.response_template(EC2_START_INSTANCES)
return template.render(instances=instances) return template.render(instances=instances)
def _get_list_of_dict_params(self, param_prefix, _dct): def _get_list_of_dict_params(
self, param_prefix: str, _dct: Dict[str, Any]
) -> List[Any]:
""" """
Simplified version of _get_dict_param Simplified version of _get_dict_param
Allows you to pass in a custom dict instead of using self.querystring by default Allows you to pass in a custom dict instead of using self.querystring by default
@ -163,7 +166,7 @@ class InstanceResponse(EC2BaseResponse):
params.append(value) params.append(value)
return params return params
def describe_instance_status(self): def describe_instance_status(self) -> str:
instance_ids = self._get_multi_param("InstanceId") instance_ids = self._get_multi_param("InstanceId")
include_all_instances = self._get_param("IncludeAllInstances") == "true" include_all_instances = self._get_param("IncludeAllInstances") == "true"
filters = self._get_list_prefix("Filter") filters = self._get_list_prefix("Filter")
@ -179,7 +182,7 @@ class InstanceResponse(EC2BaseResponse):
template = self.response_template(EC2_INSTANCE_STATUS) template = self.response_template(EC2_INSTANCE_STATUS)
return template.render(instances=instances) return template.render(instances=instances)
def describe_instance_types(self): def describe_instance_types(self) -> str:
instance_type_filters = self._get_multi_param("InstanceType") instance_type_filters = self._get_multi_param("InstanceType")
filter_dict = self._filters_from_querystring() filter_dict = self._filters_from_querystring()
instance_types = self.ec2_backend.describe_instance_types( instance_types = self.ec2_backend.describe_instance_types(
@ -188,7 +191,7 @@ class InstanceResponse(EC2BaseResponse):
template = self.response_template(EC2_DESCRIBE_INSTANCE_TYPES) template = self.response_template(EC2_DESCRIBE_INSTANCE_TYPES)
return template.render(instance_types=instance_types) return template.render(instance_types=instance_types)
def describe_instance_type_offerings(self): def describe_instance_type_offerings(self) -> str:
location_type_filters = self._get_param("LocationType") location_type_filters = self._get_param("LocationType")
filter_dict = self._filters_from_querystring() filter_dict = self._filters_from_querystring()
offerings = self.ec2_backend.describe_instance_type_offerings( offerings = self.ec2_backend.describe_instance_type_offerings(
@ -197,7 +200,7 @@ class InstanceResponse(EC2BaseResponse):
template = self.response_template(EC2_DESCRIBE_INSTANCE_TYPE_OFFERINGS) template = self.response_template(EC2_DESCRIBE_INSTANCE_TYPE_OFFERINGS)
return template.render(instance_type_offerings=offerings) return template.render(instance_type_offerings=offerings)
def describe_instance_attribute(self): def describe_instance_attribute(self) -> str:
# TODO this and modify below should raise IncorrectInstanceState if # TODO this and modify below should raise IncorrectInstanceState if
# instance not in stopped state # instance not in stopped state
attribute = self._get_param("Attribute") attribute = self._get_param("Attribute")
@ -213,7 +216,7 @@ class InstanceResponse(EC2BaseResponse):
return template.render(instance=instance, attribute=attribute, value=value) return template.render(instance=instance, attribute=attribute, value=value)
def describe_instance_credit_specifications(self): def describe_instance_credit_specifications(self) -> str:
instance_ids = self._get_multi_param("InstanceId") instance_ids = self._get_multi_param("InstanceId")
instance = self.ec2_backend.describe_instance_credit_specifications( instance = self.ec2_backend.describe_instance_credit_specifications(
instance_ids instance_ids
@ -221,7 +224,7 @@ class InstanceResponse(EC2BaseResponse):
template = self.response_template(EC2_DESCRIBE_INSTANCE_CREDIT_SPECIFICATIONS) template = self.response_template(EC2_DESCRIBE_INSTANCE_CREDIT_SPECIFICATIONS)
return template.render(instances=instance) return template.render(instances=instance)
def modify_instance_attribute(self): def modify_instance_attribute(self) -> str:
handlers = [ handlers = [
self._attribute_value_handler, self._attribute_value_handler,
self._dot_value_instance_attribute_handler, self._dot_value_instance_attribute_handler,
@ -241,7 +244,7 @@ class InstanceResponse(EC2BaseResponse):
) )
raise NotImplementedError(msg) raise NotImplementedError(msg)
def _block_device_mapping_handler(self): def _block_device_mapping_handler(self) -> Optional[str]:
""" """
Handles requests which are generated by code similar to: Handles requests which are generated by code similar to:
@ -286,8 +289,9 @@ class InstanceResponse(EC2BaseResponse):
if mapping_counter > 1: if mapping_counter > 1:
return EC2_MODIFY_INSTANCE_ATTRIBUTE return EC2_MODIFY_INSTANCE_ATTRIBUTE
return None
def _dot_value_instance_attribute_handler(self): def _dot_value_instance_attribute_handler(self) -> Optional[str]:
attribute_key = None attribute_key = None
for key, value in self.querystring.items(): for key, value in self.querystring.items():
if ".Value" in key: if ".Value" in key:
@ -295,11 +299,11 @@ class InstanceResponse(EC2BaseResponse):
break break
if not attribute_key: if not attribute_key:
return return None
self.error_on_dryrun() self.error_on_dryrun()
value = self.querystring.get(attribute_key)[0] value = self.querystring.get(attribute_key)[0] # type: ignore
normalized_attribute = camelcase_to_underscores(attribute_key.split(".")[0]) normalized_attribute = camelcase_to_underscores(attribute_key.split(".")[0])
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
self.ec2_backend.modify_instance_attribute( self.ec2_backend.modify_instance_attribute(
@ -307,11 +311,11 @@ class InstanceResponse(EC2BaseResponse):
) )
return EC2_MODIFY_INSTANCE_ATTRIBUTE return EC2_MODIFY_INSTANCE_ATTRIBUTE
def _attribute_value_handler(self): def _attribute_value_handler(self) -> Optional[str]:
attribute_key = self._get_param("Attribute") attribute_key = self._get_param("Attribute")
if attribute_key is None: if attribute_key is None:
return return None
self.error_on_dryrun() self.error_on_dryrun()
@ -323,11 +327,11 @@ class InstanceResponse(EC2BaseResponse):
) )
return EC2_MODIFY_INSTANCE_ATTRIBUTE return EC2_MODIFY_INSTANCE_ATTRIBUTE
def _security_grp_instance_attribute_handler(self): def _security_grp_instance_attribute_handler(self) -> str:
new_security_grp_list = [] new_security_grp_list = []
for key in self.querystring: for key in self.querystring:
if "GroupId." in key: if "GroupId." in key:
new_security_grp_list.append(self.querystring.get(key)[0]) new_security_grp_list.append(self.querystring.get(key)[0]) # type: ignore
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
self.error_on_dryrun() self.error_on_dryrun()
@ -337,12 +341,12 @@ class InstanceResponse(EC2BaseResponse):
) )
return EC2_MODIFY_INSTANCE_ATTRIBUTE return EC2_MODIFY_INSTANCE_ATTRIBUTE
def _parse_block_device_mapping(self): def _parse_block_device_mapping(self) -> List[Dict[str, Any]]:
device_mappings = self._get_list_prefix("BlockDeviceMapping") device_mappings = self._get_list_prefix("BlockDeviceMapping")
mappings = [] mappings = []
for device_mapping in device_mappings: for device_mapping in device_mappings:
self._validate_block_device_mapping(device_mapping) self._validate_block_device_mapping(device_mapping)
device_template = deepcopy(BLOCK_DEVICE_MAPPING_TEMPLATE) device_template: Dict[str, Any] = deepcopy(BLOCK_DEVICE_MAPPING_TEMPLATE)
device_template["VirtualName"] = device_mapping.get("virtual_name") device_template["VirtualName"] = device_mapping.get("virtual_name")
device_template["DeviceName"] = device_mapping.get("device_name") device_template["DeviceName"] = device_mapping.get("device_name")
device_template["Ebs"]["SnapshotId"] = device_mapping.get( device_template["Ebs"]["SnapshotId"] = device_mapping.get(
@ -368,7 +372,7 @@ class InstanceResponse(EC2BaseResponse):
return mappings return mappings
@staticmethod @staticmethod
def _validate_block_device_mapping(device_mapping): def _validate_block_device_mapping(device_mapping: Dict[str, Any]) -> None: # type: ignore[misc]
from botocore import __version__ as botocore_version from botocore import __version__ as botocore_version
@ -393,7 +397,7 @@ class InstanceResponse(EC2BaseResponse):
raise MissingParameterError("size or snapshotId") raise MissingParameterError("size or snapshotId")
@staticmethod @staticmethod
def _convert_to_bool(bool_str): def _convert_to_bool(bool_str: Any) -> bool: # type: ignore[misc]
if isinstance(bool_str, bool): if isinstance(bool_str, bool):
return bool_str return bool_str

View File

@ -2,7 +2,7 @@ from ._base_response import EC2BaseResponse
class InternetGateways(EC2BaseResponse): class InternetGateways(EC2BaseResponse):
def attach_internet_gateway(self): def attach_internet_gateway(self) -> str:
igw_id = self._get_param("InternetGatewayId") igw_id = self._get_param("InternetGatewayId")
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
@ -11,7 +11,7 @@ class InternetGateways(EC2BaseResponse):
self.ec2_backend.attach_internet_gateway(igw_id, vpc_id) self.ec2_backend.attach_internet_gateway(igw_id, vpc_id)
return self.response_template(ATTACH_INTERNET_GATEWAY_RESPONSE).render() return self.response_template(ATTACH_INTERNET_GATEWAY_RESPONSE).render()
def create_internet_gateway(self): def create_internet_gateway(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
tags = self._get_multi_param("TagSpecification", skip_result_conversion=True) tags = self._get_multi_param("TagSpecification", skip_result_conversion=True)
@ -22,14 +22,14 @@ class InternetGateways(EC2BaseResponse):
internet_gateway=igw internet_gateway=igw
) )
def delete_internet_gateway(self): def delete_internet_gateway(self) -> str:
igw_id = self._get_param("InternetGatewayId") igw_id = self._get_param("InternetGatewayId")
self.error_on_dryrun() self.error_on_dryrun()
self.ec2_backend.delete_internet_gateway(igw_id) self.ec2_backend.delete_internet_gateway(igw_id)
return self.response_template(DELETE_INTERNET_GATEWAY_RESPONSE).render() return self.response_template(DELETE_INTERNET_GATEWAY_RESPONSE).render()
def describe_internet_gateways(self): def describe_internet_gateways(self) -> str:
filter_dict = self._filters_from_querystring() filter_dict = self._filters_from_querystring()
if "InternetGatewayId.1" in self.querystring: if "InternetGatewayId.1" in self.querystring:
igw_ids = self._get_multi_param("InternetGatewayId") igw_ids = self._get_multi_param("InternetGatewayId")
@ -42,7 +42,7 @@ class InternetGateways(EC2BaseResponse):
template = self.response_template(DESCRIBE_INTERNET_GATEWAYS_RESPONSE) template = self.response_template(DESCRIBE_INTERNET_GATEWAYS_RESPONSE)
return template.render(internet_gateways=igws) return template.render(internet_gateways=igws)
def detach_internet_gateway(self): def detach_internet_gateway(self) -> str:
# TODO validate no instances with EIPs in VPC before detaching # TODO validate no instances with EIPs in VPC before detaching
# raise else DependencyViolationError() # raise else DependencyViolationError()
igw_id = self._get_param("InternetGatewayId") igw_id = self._get_param("InternetGatewayId")

View File

@ -2,14 +2,14 @@ from moto.core.responses import BaseResponse
class IPAddresses(BaseResponse): class IPAddresses(BaseResponse):
def assign_private_ip_addresses(self): def assign_private_ip_addresses(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"IPAddresses.assign_private_ip_addresses is not yet implemented" "IPAddresses.assign_private_ip_addresses is not yet implemented"
) )
def unassign_private_ip_addresses(self): def unassign_private_ip_addresses(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(

View File

@ -2,28 +2,28 @@ from ._base_response import EC2BaseResponse
class KeyPairs(EC2BaseResponse): class KeyPairs(EC2BaseResponse):
def create_key_pair(self): def create_key_pair(self) -> str:
name = self._get_param("KeyName") name = self._get_param("KeyName")
self.error_on_dryrun() self.error_on_dryrun()
keypair = self.ec2_backend.create_key_pair(name) keypair = self.ec2_backend.create_key_pair(name)
return self.response_template(CREATE_KEY_PAIR_RESPONSE).render(keypair=keypair) return self.response_template(CREATE_KEY_PAIR_RESPONSE).render(keypair=keypair)
def delete_key_pair(self): def delete_key_pair(self) -> str:
name = self._get_param("KeyName") name = self._get_param("KeyName")
self.error_on_dryrun() self.error_on_dryrun()
self.ec2_backend.delete_key_pair(name) self.ec2_backend.delete_key_pair(name)
return self.response_template(DELETE_KEY_PAIR_RESPONSE).render() return self.response_template(DELETE_KEY_PAIR_RESPONSE).render()
def describe_key_pairs(self): def describe_key_pairs(self) -> str:
names = self._get_multi_param("KeyName") names = self._get_multi_param("KeyName")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
keypairs = self.ec2_backend.describe_key_pairs(names, filters) keypairs = self.ec2_backend.describe_key_pairs(names, filters)
template = self.response_template(DESCRIBE_KEY_PAIRS_RESPONSE) template = self.response_template(DESCRIBE_KEY_PAIRS_RESPONSE)
return template.render(keypairs=keypairs) return template.render(keypairs=keypairs)
def import_key_pair(self): def import_key_pair(self) -> str:
name = self._get_param("KeyName") name = self._get_param("KeyName")
material = self._get_param("PublicKeyMaterial") material = self._get_param("PublicKeyMaterial")
self.error_on_dryrun() self.error_on_dryrun()

View File

@ -1,3 +1,4 @@
from typing import Any
from moto.ec2.exceptions import FilterNotImplementedError from moto.ec2.exceptions import FilterNotImplementedError
from moto.moto_api._internal import mock_random from moto.moto_api._internal import mock_random
from ._base_response import EC2BaseResponse from ._base_response import EC2BaseResponse
@ -6,7 +7,7 @@ from xml.etree import ElementTree
from xml.dom import minidom from xml.dom import minidom
def xml_root(name): def xml_root(name: str) -> ElementTree.Element:
root = ElementTree.Element( root = ElementTree.Element(
name, {"xmlns": "http://ec2.amazonaws.com/doc/2016-11-15/"} name, {"xmlns": "http://ec2.amazonaws.com/doc/2016-11-15/"}
) )
@ -16,7 +17,7 @@ def xml_root(name):
return root return root
def xml_serialize(tree, key, value): def xml_serialize(tree: ElementTree.Element, key: str, value: Any) -> None:
name = key[0].lower() + key[1:] name = key[0].lower() + key[1:]
if isinstance(value, list): if isinstance(value, list):
if name[-1] == "s": if name[-1] == "s":
@ -42,14 +43,14 @@ def xml_serialize(tree, key, value):
) )
def pretty_xml(tree): def pretty_xml(tree: ElementTree.Element) -> str:
rough = ElementTree.tostring(tree, "utf-8") rough = ElementTree.tostring(tree, "utf-8")
parsed = minidom.parseString(rough) parsed = minidom.parseString(rough)
return parsed.toprettyxml(indent=" ") return parsed.toprettyxml(indent=" ")
class LaunchTemplates(EC2BaseResponse): class LaunchTemplates(EC2BaseResponse):
def create_launch_template(self): def create_launch_template(self) -> str:
name = self._get_param("LaunchTemplateName") name = self._get_param("LaunchTemplateName")
version_description = self._get_param("VersionDescription") version_description = self._get_param("VersionDescription")
tag_spec = self._parse_tag_specification() tag_spec = self._parse_tag_specification()
@ -96,7 +97,7 @@ class LaunchTemplates(EC2BaseResponse):
return pretty_xml(tree) return pretty_xml(tree)
def create_launch_template_version(self): def create_launch_template_version(self) -> str:
name = self._get_param("LaunchTemplateName") name = self._get_param("LaunchTemplateName")
tmpl_id = self._get_param("LaunchTemplateId") tmpl_id = self._get_param("LaunchTemplateId")
if name: if name:
@ -129,7 +130,7 @@ class LaunchTemplates(EC2BaseResponse):
) )
return pretty_xml(tree) return pretty_xml(tree)
def delete_launch_template(self): def delete_launch_template(self) -> str:
name = self._get_param("LaunchTemplateName") name = self._get_param("LaunchTemplateName")
tid = self._get_param("LaunchTemplateId") tid = self._get_param("LaunchTemplateId")
@ -150,7 +151,7 @@ class LaunchTemplates(EC2BaseResponse):
return pretty_xml(tree) return pretty_xml(tree)
def describe_launch_template_versions(self): def describe_launch_template_versions(self) -> str:
name = self._get_param("LaunchTemplateName") name = self._get_param("LaunchTemplateName")
template_id = self._get_param("LaunchTemplateId") template_id = self._get_param("LaunchTemplateId")
if name: if name:
@ -222,7 +223,7 @@ class LaunchTemplates(EC2BaseResponse):
return pretty_xml(tree) return pretty_xml(tree)
def describe_launch_templates(self): def describe_launch_templates(self) -> str:
max_results = self._get_int_param("MaxResults", 15) max_results = self._get_int_param("MaxResults", 15)
template_names = self._get_multi_param("LaunchTemplateName") template_names = self._get_multi_param("LaunchTemplateName")
template_ids = self._get_multi_param("LaunchTemplateId") template_ids = self._get_multi_param("LaunchTemplateId")

View File

@ -2,12 +2,12 @@ from moto.core.responses import BaseResponse
class Monitoring(BaseResponse): class Monitoring(BaseResponse):
def monitor_instances(self): def monitor_instances(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError("Monitoring.monitor_instances is not yet implemented") raise NotImplementedError("Monitoring.monitor_instances is not yet implemented")
def unmonitor_instances(self): def unmonitor_instances(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(

View File

@ -3,12 +3,11 @@ from ._base_response import EC2BaseResponse
class NatGateways(EC2BaseResponse): class NatGateways(EC2BaseResponse):
def create_nat_gateway(self): def create_nat_gateway(self) -> str:
subnet_id = self._get_param("SubnetId") subnet_id = self._get_param("SubnetId")
allocation_id = self._get_param("AllocationId") allocation_id = self._get_param("AllocationId")
connectivity_type = self._get_param("ConnectivityType") connectivity_type = self._get_param("ConnectivityType")
tags = self._get_multi_param("TagSpecification") tags = add_tag_specification(self._get_multi_param("TagSpecification"))
tags = add_tag_specification(tags)
nat_gateway = self.ec2_backend.create_nat_gateway( nat_gateway = self.ec2_backend.create_nat_gateway(
subnet_id=subnet_id, subnet_id=subnet_id,
@ -19,13 +18,13 @@ class NatGateways(EC2BaseResponse):
template = self.response_template(CREATE_NAT_GATEWAY) template = self.response_template(CREATE_NAT_GATEWAY)
return template.render(nat_gateway=nat_gateway) return template.render(nat_gateway=nat_gateway)
def delete_nat_gateway(self): def delete_nat_gateway(self) -> str:
nat_gateway_id = self._get_param("NatGatewayId") nat_gateway_id = self._get_param("NatGatewayId")
nat_gateway = self.ec2_backend.delete_nat_gateway(nat_gateway_id) nat_gateway = self.ec2_backend.delete_nat_gateway(nat_gateway_id)
template = self.response_template(DELETE_NAT_GATEWAY_RESPONSE) template = self.response_template(DELETE_NAT_GATEWAY_RESPONSE)
return template.render(nat_gateway=nat_gateway) return template.render(nat_gateway=nat_gateway)
def describe_nat_gateways(self): def describe_nat_gateways(self) -> str:
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
nat_gateway_ids = self._get_multi_param("NatGatewayId") nat_gateway_ids = self._get_multi_param("NatGatewayId")
nat_gateways = self.ec2_backend.describe_nat_gateways(filters, nat_gateway_ids) nat_gateways = self.ec2_backend.describe_nat_gateways(filters, nat_gateway_ids)

View File

@ -2,7 +2,7 @@ from ._base_response import EC2BaseResponse
class NetworkACLs(EC2BaseResponse): class NetworkACLs(EC2BaseResponse):
def create_network_acl(self): def create_network_acl(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
tags = self._get_multi_param("TagSpecification") tags = self._get_multi_param("TagSpecification")
if tags: if tags:
@ -11,7 +11,7 @@ class NetworkACLs(EC2BaseResponse):
template = self.response_template(CREATE_NETWORK_ACL_RESPONSE) template = self.response_template(CREATE_NETWORK_ACL_RESPONSE)
return template.render(network_acl=network_acl) return template.render(network_acl=network_acl)
def create_network_acl_entry(self): def create_network_acl_entry(self) -> str:
network_acl_id = self._get_param("NetworkAclId") network_acl_id = self._get_param("NetworkAclId")
rule_number = self._get_param("RuleNumber") rule_number = self._get_param("RuleNumber")
protocol = self._get_param("Protocol") protocol = self._get_param("Protocol")
@ -39,13 +39,13 @@ class NetworkACLs(EC2BaseResponse):
template = self.response_template(CREATE_NETWORK_ACL_ENTRY_RESPONSE) template = self.response_template(CREATE_NETWORK_ACL_ENTRY_RESPONSE)
return template.render(network_acl_entry=network_acl_entry) return template.render(network_acl_entry=network_acl_entry)
def delete_network_acl(self): def delete_network_acl(self) -> str:
network_acl_id = self._get_param("NetworkAclId") network_acl_id = self._get_param("NetworkAclId")
self.ec2_backend.delete_network_acl(network_acl_id) self.ec2_backend.delete_network_acl(network_acl_id)
template = self.response_template(DELETE_NETWORK_ACL_ASSOCIATION) template = self.response_template(DELETE_NETWORK_ACL_ASSOCIATION)
return template.render() return template.render()
def delete_network_acl_entry(self): def delete_network_acl_entry(self) -> str:
network_acl_id = self._get_param("NetworkAclId") network_acl_id = self._get_param("NetworkAclId")
rule_number = self._get_param("RuleNumber") rule_number = self._get_param("RuleNumber")
egress = self._get_param("Egress") egress = self._get_param("Egress")
@ -53,7 +53,7 @@ class NetworkACLs(EC2BaseResponse):
template = self.response_template(DELETE_NETWORK_ACL_ENTRY_RESPONSE) template = self.response_template(DELETE_NETWORK_ACL_ENTRY_RESPONSE)
return template.render() return template.render()
def replace_network_acl_entry(self): def replace_network_acl_entry(self) -> str:
network_acl_id = self._get_param("NetworkAclId") network_acl_id = self._get_param("NetworkAclId")
rule_number = self._get_param("RuleNumber") rule_number = self._get_param("RuleNumber")
protocol = self._get_param("Protocol") protocol = self._get_param("Protocol")
@ -81,14 +81,14 @@ class NetworkACLs(EC2BaseResponse):
template = self.response_template(REPLACE_NETWORK_ACL_ENTRY_RESPONSE) template = self.response_template(REPLACE_NETWORK_ACL_ENTRY_RESPONSE)
return template.render() return template.render()
def describe_network_acls(self): def describe_network_acls(self) -> str:
network_acl_ids = self._get_multi_param("NetworkAclId") network_acl_ids = self._get_multi_param("NetworkAclId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
network_acls = self.ec2_backend.describe_network_acls(network_acl_ids, filters) network_acls = self.ec2_backend.describe_network_acls(network_acl_ids, filters)
template = self.response_template(DESCRIBE_NETWORK_ACL_RESPONSE) template = self.response_template(DESCRIBE_NETWORK_ACL_RESPONSE)
return template.render(network_acls=network_acls) return template.render(network_acls=network_acls)
def replace_network_acl_association(self): def replace_network_acl_association(self) -> str:
association_id = self._get_param("AssociationId") association_id = self._get_param("AssociationId")
network_acl_id = self._get_param("NetworkAclId") network_acl_id = self._get_param("NetworkAclId")

View File

@ -1,22 +0,0 @@
from moto.core.responses import BaseResponse
class PlacementGroups(BaseResponse):
def create_placement_group(self):
self.error_on_dryrun()
raise NotImplementedError(
"PlacementGroups.create_placement_group is not yet implemented"
)
def delete_placement_group(self):
self.error_on_dryrun()
raise NotImplementedError(
"PlacementGroups.delete_placement_group is not yet implemented"
)
def describe_placement_groups(self):
raise NotImplementedError(
"PlacementGroups.describe_placement_groups is not yet implemented"
)

View File

@ -2,36 +2,36 @@ from moto.core.responses import BaseResponse
class ReservedInstances(BaseResponse): class ReservedInstances(BaseResponse):
def cancel_reserved_instances_listing(self): def cancel_reserved_instances_listing(self) -> None:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"ReservedInstances.cancel_reserved_instances_listing is not yet implemented" "ReservedInstances.cancel_reserved_instances_listing is not yet implemented"
) )
def create_reserved_instances_listing(self): def create_reserved_instances_listing(self) -> None:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"ReservedInstances.create_reserved_instances_listing is not yet implemented" "ReservedInstances.create_reserved_instances_listing is not yet implemented"
) )
def describe_reserved_instances(self): def describe_reserved_instances(self) -> None:
raise NotImplementedError( raise NotImplementedError(
"ReservedInstances.describe_reserved_instances is not yet implemented" "ReservedInstances.describe_reserved_instances is not yet implemented"
) )
def describe_reserved_instances_listings(self): def describe_reserved_instances_listings(self) -> None:
raise NotImplementedError( raise NotImplementedError(
"ReservedInstances.describe_reserved_instances_listings is not yet implemented" "ReservedInstances.describe_reserved_instances_listings is not yet implemented"
) )
def describe_reserved_instances_offerings(self): def describe_reserved_instances_offerings(self) -> None:
raise NotImplementedError( raise NotImplementedError(
"ReservedInstances.describe_reserved_instances_offerings is not yet implemented" "ReservedInstances.describe_reserved_instances_offerings is not yet implemented"
) )
def purchase_reserved_instances_offering(self): def purchase_reserved_instances_offering(self) -> None:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(

View File

@ -2,7 +2,7 @@ from ._base_response import EC2BaseResponse
class RouteTables(EC2BaseResponse): class RouteTables(EC2BaseResponse):
def associate_route_table(self): def associate_route_table(self) -> str:
route_table_id = self._get_param("RouteTableId") route_table_id = self._get_param("RouteTableId")
gateway_id = self._get_param("GatewayId") gateway_id = self._get_param("GatewayId")
subnet_id = self._get_param("SubnetId") subnet_id = self._get_param("SubnetId")
@ -12,7 +12,7 @@ class RouteTables(EC2BaseResponse):
template = self.response_template(ASSOCIATE_ROUTE_TABLE_RESPONSE) template = self.response_template(ASSOCIATE_ROUTE_TABLE_RESPONSE)
return template.render(association_id=association_id) return template.render(association_id=association_id)
def create_route(self): def create_route(self) -> str:
route_table_id = self._get_param("RouteTableId") route_table_id = self._get_param("RouteTableId")
destination_cidr_block = self._get_param("DestinationCidrBlock") destination_cidr_block = self._get_param("DestinationCidrBlock")
destination_ipv6_cidr_block = self._get_param("DestinationIpv6CidrBlock") destination_ipv6_cidr_block = self._get_param("DestinationIpv6CidrBlock")
@ -44,7 +44,7 @@ class RouteTables(EC2BaseResponse):
template = self.response_template(CREATE_ROUTE_RESPONSE) template = self.response_template(CREATE_ROUTE_RESPONSE)
return template.render() return template.render()
def create_route_table(self): def create_route_table(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
tags = self._get_multi_param("TagSpecification", skip_result_conversion=True) tags = self._get_multi_param("TagSpecification", skip_result_conversion=True)
if tags: if tags:
@ -53,7 +53,7 @@ class RouteTables(EC2BaseResponse):
template = self.response_template(CREATE_ROUTE_TABLE_RESPONSE) template = self.response_template(CREATE_ROUTE_TABLE_RESPONSE)
return template.render(route_table=route_table) return template.render(route_table=route_table)
def delete_route(self): def delete_route(self) -> str:
route_table_id = self._get_param("RouteTableId") route_table_id = self._get_param("RouteTableId")
destination_cidr_block = self._get_param("DestinationCidrBlock") destination_cidr_block = self._get_param("DestinationCidrBlock")
destination_ipv6_cidr_block = self._get_param("DestinationIpv6CidrBlock") destination_ipv6_cidr_block = self._get_param("DestinationIpv6CidrBlock")
@ -67,26 +67,26 @@ class RouteTables(EC2BaseResponse):
template = self.response_template(DELETE_ROUTE_RESPONSE) template = self.response_template(DELETE_ROUTE_RESPONSE)
return template.render() return template.render()
def delete_route_table(self): def delete_route_table(self) -> str:
route_table_id = self._get_param("RouteTableId") route_table_id = self._get_param("RouteTableId")
self.ec2_backend.delete_route_table(route_table_id) self.ec2_backend.delete_route_table(route_table_id)
template = self.response_template(DELETE_ROUTE_TABLE_RESPONSE) template = self.response_template(DELETE_ROUTE_TABLE_RESPONSE)
return template.render() return template.render()
def describe_route_tables(self): def describe_route_tables(self) -> str:
route_table_ids = self._get_multi_param("RouteTableId") route_table_ids = self._get_multi_param("RouteTableId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
route_tables = self.ec2_backend.describe_route_tables(route_table_ids, filters) route_tables = self.ec2_backend.describe_route_tables(route_table_ids, filters)
template = self.response_template(DESCRIBE_ROUTE_TABLES_RESPONSE) template = self.response_template(DESCRIBE_ROUTE_TABLES_RESPONSE)
return template.render(route_tables=route_tables) return template.render(route_tables=route_tables)
def disassociate_route_table(self): def disassociate_route_table(self) -> str:
association_id = self._get_param("AssociationId") association_id = self._get_param("AssociationId")
self.ec2_backend.disassociate_route_table(association_id) self.ec2_backend.disassociate_route_table(association_id)
template = self.response_template(DISASSOCIATE_ROUTE_TABLE_RESPONSE) template = self.response_template(DISASSOCIATE_ROUTE_TABLE_RESPONSE)
return template.render() return template.render()
def replace_route(self): def replace_route(self) -> str:
route_table_id = self._get_param("RouteTableId") route_table_id = self._get_param("RouteTableId")
destination_cidr_block = self._get_param("DestinationCidrBlock") destination_cidr_block = self._get_param("DestinationCidrBlock")
destination_ipv6_cidr_block = self._get_param("DestinationIpv6CidrBlock") destination_ipv6_cidr_block = self._get_param("DestinationIpv6CidrBlock")
@ -116,7 +116,7 @@ class RouteTables(EC2BaseResponse):
template = self.response_template(REPLACE_ROUTE_RESPONSE) template = self.response_template(REPLACE_ROUTE_RESPONSE)
return template.render() return template.render()
def replace_route_table_association(self): def replace_route_table_association(self) -> str:
route_table_id = self._get_param("RouteTableId") route_table_id = self._get_param("RouteTableId")
association_id = self._get_param("AssociationId") association_id = self._get_param("AssociationId")
new_association_id = self.ec2_backend.replace_route_table_association( new_association_id = self.ec2_backend.replace_route_table_association(

View File

@ -1,19 +1,20 @@
from typing import Any, Dict, List, Tuple
from ._base_response import EC2BaseResponse from ._base_response import EC2BaseResponse
def try_parse_int(value, default=None): def try_parse_int(value: Any, default: Any = None) -> Any:
try: try:
return int(value) return int(value)
except (TypeError, ValueError): except (TypeError, ValueError):
return default return default
def parse_sg_attributes_from_dict(sg_attributes): def parse_sg_attributes_from_dict(sg_attributes: Dict[str, Any]) -> Tuple[Any, ...]:
ip_protocol = sg_attributes.get("IpProtocol", [None])[0] ip_protocol = sg_attributes.get("IpProtocol", [None])[0]
from_port = sg_attributes.get("FromPort", [None])[0] from_port = sg_attributes.get("FromPort", [None])[0]
to_port = sg_attributes.get("ToPort", [None])[0] to_port = sg_attributes.get("ToPort", [None])[0]
ip_ranges = [] ip_ranges: List[Dict[str, Any]] = []
ip_ranges_tree = sg_attributes.get("IpRanges") or {} ip_ranges_tree = sg_attributes.get("IpRanges") or {}
for ip_range_idx in sorted(ip_ranges_tree.keys()): for ip_range_idx in sorted(ip_ranges_tree.keys()):
ip_range = {"CidrIp": ip_ranges_tree[ip_range_idx]["CidrIp"][0]} ip_range = {"CidrIp": ip_ranges_tree[ip_range_idx]["CidrIp"][0]}
@ -22,7 +23,7 @@ def parse_sg_attributes_from_dict(sg_attributes):
ip_ranges.append(ip_range) ip_ranges.append(ip_range)
ip_ranges_tree = sg_attributes.get("Ipv6Ranges") or {} ip_ranges_tree: Dict[str, Any] = sg_attributes.get("Ipv6Ranges") or {} # type: ignore[no-redef]
for ip_range_idx in sorted(ip_ranges_tree.keys()): for ip_range_idx in sorted(ip_ranges_tree.keys()):
ip_range = {"CidrIpv6": ip_ranges_tree[ip_range_idx]["CidrIpv6"][0]} ip_range = {"CidrIpv6": ip_ranges_tree[ip_range_idx]["CidrIpv6"][0]}
if ip_ranges_tree[ip_range_idx].get("Description"): if ip_ranges_tree[ip_range_idx].get("Description"):
@ -31,15 +32,15 @@ def parse_sg_attributes_from_dict(sg_attributes):
ip_ranges.append(ip_range) ip_ranges.append(ip_range)
if "CidrIp" in sg_attributes: if "CidrIp" in sg_attributes:
cidr_ip = sg_attributes.get("CidrIp")[0] cidr_ip = sg_attributes.get("CidrIp")[0] # type: ignore
ip_ranges.append({"CidrIp": cidr_ip}) ip_ranges.append({"CidrIp": cidr_ip})
if "CidrIpv6" in sg_attributes: if "CidrIpv6" in sg_attributes:
cidr_ipv6 = sg_attributes.get("CidrIpv6")[0] cidr_ipv6 = sg_attributes.get("CidrIpv6")[0] # type: ignore
ip_ranges.append({"CidrIpv6": cidr_ipv6}) ip_ranges.append({"CidrIpv6": cidr_ipv6})
source_groups = [] source_groups: List[Dict[str, Any]] = []
groups_tree = sg_attributes.get("Groups") or {} groups_tree: Dict[str, Any] = sg_attributes.get("Groups") or {}
for group_idx in sorted(groups_tree.keys()): for group_idx in sorted(groups_tree.keys()):
group_dict = groups_tree[group_idx] group_dict = groups_tree[group_idx]
source_group = {} source_group = {}
@ -53,8 +54,8 @@ def parse_sg_attributes_from_dict(sg_attributes):
source_group["OwnerId"] = group_dict["OwnerId"][0] source_group["OwnerId"] = group_dict["OwnerId"][0]
source_groups.append(source_group) source_groups.append(source_group)
prefix_list_ids = [] prefix_list_ids: List[Dict[str, Any]] = []
pl_tree = sg_attributes.get("PrefixListIds") or {} pl_tree: Dict[str, Any] = sg_attributes.get("PrefixListIds") or {}
for pl_index in sorted(pl_tree): for pl_index in sorted(pl_tree):
pl_dict = pl_tree.get(pl_index, {}) pl_dict = pl_tree.get(pl_index, {})
pl_item = {} pl_item = {}
@ -68,10 +69,10 @@ def parse_sg_attributes_from_dict(sg_attributes):
class SecurityGroups(EC2BaseResponse): class SecurityGroups(EC2BaseResponse):
def _process_rules_from_querystring(self): def _process_rules_from_querystring(self) -> Any:
group_name_or_id = self._get_param("GroupName") or self._get_param("GroupId") group_name_or_id = self._get_param("GroupName") or self._get_param("GroupId")
querytree = {} querytree: Dict[str, Any] = {}
for key, value in self.querystring.items(): for key, value in self.querystring.items():
key_splitted = key.split(".") key_splitted = key.split(".")
key_splitted = [try_parse_int(e, e) for e in key_splitted] key_splitted = [try_parse_int(e, e) for e in key_splitted]
@ -127,7 +128,7 @@ class SecurityGroups(EC2BaseResponse):
prefix_list_ids, prefix_list_ids,
) )
def authorize_security_group_egress(self): def authorize_security_group_egress(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
for args in self._process_rules_from_querystring(): for args in self._process_rules_from_querystring():
@ -136,7 +137,7 @@ class SecurityGroups(EC2BaseResponse):
template = self.response_template(AUTHORIZE_SECURITY_GROUP_EGRESS_RESPONSE) template = self.response_template(AUTHORIZE_SECURITY_GROUP_EGRESS_RESPONSE)
return template.render(rule=rule, group=group) return template.render(rule=rule, group=group)
def authorize_security_group_ingress(self): def authorize_security_group_ingress(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
for args in self._process_rules_from_querystring(): for args in self._process_rules_from_querystring():
@ -145,14 +146,11 @@ class SecurityGroups(EC2BaseResponse):
template = self.response_template(AUTHORIZE_SECURITY_GROUP_INGRESS_RESPONSE) template = self.response_template(AUTHORIZE_SECURITY_GROUP_INGRESS_RESPONSE)
return template.render(rule=rule, group=group) return template.render(rule=rule, group=group)
def create_security_group(self): def create_security_group(self) -> str:
name = self._get_param("GroupName") name = self._get_param("GroupName")
description = self._get_param("GroupDescription") description = self._get_param("GroupDescription")
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
tags = self._get_multi_param("TagSpecification") tags = self._parse_tag_specification().get("security-group", {})
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags}
self.error_on_dryrun() self.error_on_dryrun()
@ -165,7 +163,7 @@ class SecurityGroups(EC2BaseResponse):
template = self.response_template(CREATE_SECURITY_GROUP_RESPONSE) template = self.response_template(CREATE_SECURITY_GROUP_RESPONSE)
return template.render(group=group) return template.render(group=group)
def delete_security_group(self): def delete_security_group(self) -> str:
# TODO this should raise an error if there are instances in the group. # TODO this should raise an error if there are instances in the group.
# See # See
# http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSecurityGroup.html # http://docs.aws.amazon.com/AWSEC2/latest/APIReference/ApiReference-query-DeleteSecurityGroup.html
@ -182,7 +180,7 @@ class SecurityGroups(EC2BaseResponse):
return DELETE_GROUP_RESPONSE return DELETE_GROUP_RESPONSE
def describe_security_groups(self): def describe_security_groups(self) -> str:
groupnames = self._get_multi_param("GroupName") groupnames = self._get_multi_param("GroupName")
group_ids = self._get_multi_param("GroupId") group_ids = self._get_multi_param("GroupId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
@ -194,7 +192,7 @@ class SecurityGroups(EC2BaseResponse):
template = self.response_template(DESCRIBE_SECURITY_GROUPS_RESPONSE) template = self.response_template(DESCRIBE_SECURITY_GROUPS_RESPONSE)
return template.render(groups=groups) return template.render(groups=groups)
def describe_security_group_rules(self): def describe_security_group_rules(self) -> str:
group_id = self._get_param("GroupId") group_id = self._get_param("GroupId")
filters = self._get_param("Filter") filters = self._get_param("Filter")
@ -204,21 +202,21 @@ class SecurityGroups(EC2BaseResponse):
template = self.response_template(DESCRIBE_SECURITY_GROUP_RULES_RESPONSE) template = self.response_template(DESCRIBE_SECURITY_GROUP_RULES_RESPONSE)
return template.render(rules=rules) return template.render(rules=rules)
def revoke_security_group_egress(self): def revoke_security_group_egress(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
for args in self._process_rules_from_querystring(): for args in self._process_rules_from_querystring():
self.ec2_backend.revoke_security_group_egress(*args) self.ec2_backend.revoke_security_group_egress(*args)
return REVOKE_SECURITY_GROUP_EGRESS_RESPONSE return REVOKE_SECURITY_GROUP_EGRESS_RESPONSE
def revoke_security_group_ingress(self): def revoke_security_group_ingress(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
for args in self._process_rules_from_querystring(): for args in self._process_rules_from_querystring():
self.ec2_backend.revoke_security_group_ingress(*args) self.ec2_backend.revoke_security_group_ingress(*args)
return REVOKE_SECURITY_GROUP_INGRESS_RESPONSE return REVOKE_SECURITY_GROUP_INGRESS_RESPONSE
def update_security_group_rule_descriptions_ingress(self): def update_security_group_rule_descriptions_ingress(self) -> str:
for args in self._process_rules_from_querystring(): for args in self._process_rules_from_querystring():
group = self.ec2_backend.update_security_group_rule_descriptions_ingress( group = self.ec2_backend.update_security_group_rule_descriptions_ingress(
*args *args
@ -226,7 +224,7 @@ class SecurityGroups(EC2BaseResponse):
self.ec2_backend.sg_old_ingress_ruls[group.id] = group.ingress_rules.copy() self.ec2_backend.sg_old_ingress_ruls[group.id] = group.ingress_rules.copy()
return UPDATE_SECURITY_GROUP_RULE_DESCRIPTIONS_INGRESS return UPDATE_SECURITY_GROUP_RULE_DESCRIPTIONS_INGRESS
def update_security_group_rule_descriptions_egress(self): def update_security_group_rule_descriptions_egress(self) -> str:
for args in self._process_rules_from_querystring(): for args in self._process_rules_from_querystring():
group = self.ec2_backend.update_security_group_rule_descriptions_egress( group = self.ec2_backend.update_security_group_rule_descriptions_egress(
*args *args

View File

@ -1,22 +1,22 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
class Settings(BaseResponse): class Settings(EC2BaseResponse):
def disable_ebs_encryption_by_default(self): def disable_ebs_encryption_by_default(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
self.ec2_backend.disable_ebs_encryption_by_default() self.ec2_backend.disable_ebs_encryption_by_default()
template = self.response_template(DISABLE_EBS_ENCRYPTION_BY_DEFAULT_RESPONSE) template = self.response_template(DISABLE_EBS_ENCRYPTION_BY_DEFAULT_RESPONSE)
return template.render(ebsEncryptionByDefault=False).replace("False", "false") return template.render(ebsEncryptionByDefault=False).replace("False", "false")
def enable_ebs_encryption_by_default(self): def enable_ebs_encryption_by_default(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
self.ec2_backend.enable_ebs_encryption_by_default() self.ec2_backend.enable_ebs_encryption_by_default()
template = self.response_template(ENABLED_EBS_ENCRYPTION_BY_DEFAULT_RESPONSE) template = self.response_template(ENABLED_EBS_ENCRYPTION_BY_DEFAULT_RESPONSE)
return template.render(ebsEncryptionByDefault=True).replace("True", "true") return template.render(ebsEncryptionByDefault=True).replace("True", "true")
def get_ebs_encryption_by_default(self): def get_ebs_encryption_by_default(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
result = self.ec2_backend.get_ebs_encryption_by_default() result = self.ec2_backend.get_ebs_encryption_by_default()

View File

@ -1,8 +1,8 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
class SpotFleets(BaseResponse): class SpotFleets(EC2BaseResponse):
def cancel_spot_fleet_requests(self): def cancel_spot_fleet_requests(self) -> str:
spot_fleet_request_ids = self._get_multi_param("SpotFleetRequestId.") spot_fleet_request_ids = self._get_multi_param("SpotFleetRequestId.")
terminate_instances = self._get_bool_param("TerminateInstances") terminate_instances = self._get_bool_param("TerminateInstances")
spot_fleets = self.ec2_backend.cancel_spot_fleet_requests( spot_fleets = self.ec2_backend.cancel_spot_fleet_requests(
@ -11,7 +11,7 @@ class SpotFleets(BaseResponse):
template = self.response_template(CANCEL_SPOT_FLEETS_TEMPLATE) template = self.response_template(CANCEL_SPOT_FLEETS_TEMPLATE)
return template.render(spot_fleets=spot_fleets) return template.render(spot_fleets=spot_fleets)
def describe_spot_fleet_instances(self): def describe_spot_fleet_instances(self) -> str:
spot_fleet_request_id = self._get_param("SpotFleetRequestId") spot_fleet_request_id = self._get_param("SpotFleetRequestId")
spot_requests = self.ec2_backend.describe_spot_fleet_instances( spot_requests = self.ec2_backend.describe_spot_fleet_instances(
@ -22,14 +22,14 @@ class SpotFleets(BaseResponse):
spot_request_id=spot_fleet_request_id, spot_requests=spot_requests spot_request_id=spot_fleet_request_id, spot_requests=spot_requests
) )
def describe_spot_fleet_requests(self): def describe_spot_fleet_requests(self) -> str:
spot_fleet_request_ids = self._get_multi_param("SpotFleetRequestId.") spot_fleet_request_ids = self._get_multi_param("SpotFleetRequestId.")
requests = self.ec2_backend.describe_spot_fleet_requests(spot_fleet_request_ids) requests = self.ec2_backend.describe_spot_fleet_requests(spot_fleet_request_ids)
template = self.response_template(DESCRIBE_SPOT_FLEET_TEMPLATE) template = self.response_template(DESCRIBE_SPOT_FLEET_TEMPLATE)
return template.render(requests=requests) return template.render(requests=requests)
def modify_spot_fleet_request(self): def modify_spot_fleet_request(self) -> str:
spot_fleet_request_id = self._get_param("SpotFleetRequestId") spot_fleet_request_id = self._get_param("SpotFleetRequestId")
target_capacity = self._get_int_param("TargetCapacity") target_capacity = self._get_int_param("TargetCapacity")
terminate_instances = self._get_param( terminate_instances = self._get_param(
@ -40,7 +40,7 @@ class SpotFleets(BaseResponse):
) )
return self.response_template(MODIFY_SPOT_FLEET_REQUEST_TEMPLATE).render() return self.response_template(MODIFY_SPOT_FLEET_REQUEST_TEMPLATE).render()
def request_spot_fleet(self): def request_spot_fleet(self) -> str:
spot_config = self._get_multi_param_dict("SpotFleetRequestConfig") spot_config = self._get_multi_param_dict("SpotFleetRequestConfig")
spot_price = spot_config.get("SpotPrice") spot_price = spot_config.get("SpotPrice")
target_capacity = spot_config["TargetCapacity"] target_capacity = spot_config["TargetCapacity"]

View File

@ -2,7 +2,7 @@ from ._base_response import EC2BaseResponse
class SpotInstances(EC2BaseResponse): class SpotInstances(EC2BaseResponse):
def cancel_spot_instance_requests(self): def cancel_spot_instance_requests(self) -> str:
request_ids = self._get_multi_param("SpotInstanceRequestId") request_ids = self._get_multi_param("SpotInstanceRequestId")
self.error_on_dryrun() self.error_on_dryrun()
@ -11,26 +11,26 @@ class SpotInstances(EC2BaseResponse):
template = self.response_template(CANCEL_SPOT_INSTANCES_TEMPLATE) template = self.response_template(CANCEL_SPOT_INSTANCES_TEMPLATE)
return template.render(requests=requests) return template.render(requests=requests)
def create_spot_datafeed_subscription(self): def create_spot_datafeed_subscription(self) -> None:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"SpotInstances.create_spot_datafeed_subscription is not yet implemented" "SpotInstances.create_spot_datafeed_subscription is not yet implemented"
) )
def delete_spot_datafeed_subscription(self): def delete_spot_datafeed_subscription(self) -> None:
self.error_on_dryrun() self.error_on_dryrun()
raise NotImplementedError( raise NotImplementedError(
"SpotInstances.delete_spot_datafeed_subscription is not yet implemented" "SpotInstances.delete_spot_datafeed_subscription is not yet implemented"
) )
def describe_spot_datafeed_subscription(self): def describe_spot_datafeed_subscription(self) -> None:
raise NotImplementedError( raise NotImplementedError(
"SpotInstances.describe_spot_datafeed_subscription is not yet implemented" "SpotInstances.describe_spot_datafeed_subscription is not yet implemented"
) )
def describe_spot_instance_requests(self): def describe_spot_instance_requests(self) -> str:
spot_instance_ids = self._get_multi_param("SpotInstanceRequestId") spot_instance_ids = self._get_multi_param("SpotInstanceRequestId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
requests = self.ec2_backend.describe_spot_instance_requests( requests = self.ec2_backend.describe_spot_instance_requests(
@ -39,7 +39,7 @@ class SpotInstances(EC2BaseResponse):
template = self.response_template(DESCRIBE_SPOT_INSTANCES_TEMPLATE) template = self.response_template(DESCRIBE_SPOT_INSTANCES_TEMPLATE)
return template.render(requests=requests) return template.render(requests=requests)
def describe_spot_price_history(self): def describe_spot_price_history(self) -> str:
instance_types_filters = self._get_multi_param("InstanceType") instance_types_filters = self._get_multi_param("InstanceType")
filter_dict = self._filters_from_querystring() filter_dict = self._filters_from_querystring()
prices = self.ec2_backend.describe_spot_price_history( prices = self.ec2_backend.describe_spot_price_history(
@ -48,7 +48,7 @@ class SpotInstances(EC2BaseResponse):
template = self.response_template(DESCRIBE_SPOT_PRICE_HISTORY_TEMPLATE) template = self.response_template(DESCRIBE_SPOT_PRICE_HISTORY_TEMPLATE)
return template.render(prices=prices) return template.render(prices=prices)
def request_spot_instances(self): def request_spot_instances(self) -> str:
price = self._get_param("SpotPrice") price = self._get_param("SpotPrice")
image_id = self._get_param("LaunchSpecification.ImageId") image_id = self._get_param("LaunchSpecification.ImageId")
count = self._get_int_param("InstanceCount", 1) count = self._get_int_param("InstanceCount", 1)

View File

@ -5,7 +5,7 @@ from ._base_response import EC2BaseResponse
class Subnets(EC2BaseResponse): class Subnets(EC2BaseResponse):
def create_subnet(self): def create_subnet(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
cidr_block = self._get_param("CidrBlock") cidr_block = self._get_param("CidrBlock")
ipv6_cidr_block = self._get_param("Ipv6CidrBlock") ipv6_cidr_block = self._get_param("Ipv6CidrBlock")
@ -30,13 +30,13 @@ class Subnets(EC2BaseResponse):
template = self.response_template(CREATE_SUBNET_RESPONSE) template = self.response_template(CREATE_SUBNET_RESPONSE)
return template.render(subnet=subnet) return template.render(subnet=subnet)
def delete_subnet(self): def delete_subnet(self) -> str:
subnet_id = self._get_param("SubnetId") subnet_id = self._get_param("SubnetId")
subnet = self.ec2_backend.delete_subnet(subnet_id) subnet = self.ec2_backend.delete_subnet(subnet_id)
template = self.response_template(DELETE_SUBNET_RESPONSE) template = self.response_template(DELETE_SUBNET_RESPONSE)
return template.render(subnet=subnet) return template.render(subnet=subnet)
def describe_subnets(self): def describe_subnets(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
subnet_ids = self._get_multi_param("SubnetId") subnet_ids = self._get_multi_param("SubnetId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
@ -44,19 +44,20 @@ class Subnets(EC2BaseResponse):
template = self.response_template(DESCRIBE_SUBNETS_RESPONSE) template = self.response_template(DESCRIBE_SUBNETS_RESPONSE)
return template.render(subnets=subnets) return template.render(subnets=subnets)
def modify_subnet_attribute(self): def modify_subnet_attribute(self) -> str:
subnet_id = self._get_param("SubnetId") subnet_id = self._get_param("SubnetId")
for attribute in ("MapPublicIpOnLaunch", "AssignIpv6AddressOnCreation"): for attribute in ("MapPublicIpOnLaunch", "AssignIpv6AddressOnCreation"):
if self.querystring.get(f"{attribute}.Value"): if self.querystring.get(f"{attribute}.Value"):
attr_name = camelcase_to_underscores(attribute) attr_name = camelcase_to_underscores(attribute)
attr_value = self.querystring.get(f"{attribute}.Value")[0] attr_value = self.querystring[f"{attribute}.Value"][0]
self.ec2_backend.modify_subnet_attribute( self.ec2_backend.modify_subnet_attribute(
subnet_id, attr_name, attr_value subnet_id, attr_name, attr_value
) )
return MODIFY_SUBNET_ATTRIBUTE_RESPONSE return MODIFY_SUBNET_ATTRIBUTE_RESPONSE
return ""
def associate_subnet_cidr_block(self): def associate_subnet_cidr_block(self) -> str:
ipv6_cidr_block = self._get_param("Ipv6CidrBlock") ipv6_cidr_block = self._get_param("Ipv6CidrBlock")
subnet_id = self._get_param("SubnetId") subnet_id = self._get_param("SubnetId")
@ -66,7 +67,7 @@ class Subnets(EC2BaseResponse):
template = self.response_template(ASSOCIATE_SUBNET_CIDR_BLOCK_RESPONSE) template = self.response_template(ASSOCIATE_SUBNET_CIDR_BLOCK_RESPONSE)
return template.render(subnet_id=subnet_id, association=association) return template.render(subnet_id=subnet_id, association=association)
def disassociate_subnet_cidr_block(self): def disassociate_subnet_cidr_block(self) -> str:
association_id = self._get_param("AssociationId") association_id = self._get_param("AssociationId")
subnet_id, association = self.ec2_backend.disassociate_subnet_cidr_block( subnet_id, association = self.ec2_backend.disassociate_subnet_cidr_block(

View File

@ -4,7 +4,7 @@ from ._base_response import EC2BaseResponse
class TagResponse(EC2BaseResponse): class TagResponse(EC2BaseResponse):
def create_tags(self): def create_tags(self) -> str:
resource_ids = self._get_multi_param("ResourceId") resource_ids = self._get_multi_param("ResourceId")
validate_resource_ids(resource_ids) validate_resource_ids(resource_ids)
self.ec2_backend.do_resources_exist(resource_ids) self.ec2_backend.do_resources_exist(resource_ids)
@ -15,7 +15,7 @@ class TagResponse(EC2BaseResponse):
self.ec2_backend.create_tags(resource_ids, tags) self.ec2_backend.create_tags(resource_ids, tags)
return CREATE_RESPONSE return CREATE_RESPONSE
def delete_tags(self): def delete_tags(self) -> str:
resource_ids = self._get_multi_param("ResourceId") resource_ids = self._get_multi_param("ResourceId")
validate_resource_ids(resource_ids) validate_resource_ids(resource_ids)
tags = tags_from_query_string(self.querystring) tags = tags_from_query_string(self.querystring)
@ -25,7 +25,7 @@ class TagResponse(EC2BaseResponse):
self.ec2_backend.delete_tags(resource_ids, tags) self.ec2_backend.delete_tags(resource_ids, tags)
return DELETE_RESPONSE return DELETE_RESPONSE
def describe_tags(self): def describe_tags(self) -> str:
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
self.error_on_dryrun() self.error_on_dryrun()

View File

@ -3,16 +3,13 @@ from ._base_response import EC2BaseResponse
class TransitGatewayAttachment(EC2BaseResponse): class TransitGatewayAttachment(EC2BaseResponse):
def create_transit_gateway_vpc_attachment(self): def create_transit_gateway_vpc_attachment(self) -> str:
options = self._get_multi_param_dict("Options") options = self._get_multi_param_dict("Options")
subnet_ids = self._get_multi_param("SubnetIds") subnet_ids = self._get_multi_param("SubnetIds")
transit_gateway_id = self._get_param("TransitGatewayId") transit_gateway_id = self._get_param("TransitGatewayId")
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
tags = self._get_multi_param("TagSpecifications") tags = self._parse_tag_specification().get("transit-gateway-route-table", {})
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags}
transit_gateway_attachment = ( transit_gateway_attachment = (
self.ec2_backend.create_transit_gateway_vpc_attachment( self.ec2_backend.create_transit_gateway_vpc_attachment(
@ -26,7 +23,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
template = self.response_template(CREATE_TRANSIT_GATEWAY_VPC_ATTACHMENT) template = self.response_template(CREATE_TRANSIT_GATEWAY_VPC_ATTACHMENT)
return template.render(transit_gateway_attachment=transit_gateway_attachment) return template.render(transit_gateway_attachment=transit_gateway_attachment)
def describe_transit_gateway_vpc_attachments(self): def describe_transit_gateway_vpc_attachments(self) -> str:
transit_gateways_attachment_ids = self._get_multi_param( transit_gateways_attachment_ids = self._get_multi_param(
"TransitGatewayAttachmentIds" "TransitGatewayAttachmentIds"
) )
@ -42,7 +39,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
transit_gateway_vpc_attachments=transit_gateway_vpc_attachments transit_gateway_vpc_attachments=transit_gateway_vpc_attachments
) )
def modify_transit_gateway_vpc_attachment(self): def modify_transit_gateway_vpc_attachment(self) -> str:
add_subnet_ids = self._get_multi_param("AddSubnetIds") add_subnet_ids = self._get_multi_param("AddSubnetIds")
options = self._get_multi_param_dict("Options") options = self._get_multi_param_dict("Options")
remove_subnet_ids = self._get_multi_param("RemoveSubnetIds") remove_subnet_ids = self._get_multi_param("RemoveSubnetIds")
@ -59,7 +56,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
template = self.response_template(MODIFY_TRANSIT_GATEWAY_VPC_ATTACHMENTS) template = self.response_template(MODIFY_TRANSIT_GATEWAY_VPC_ATTACHMENTS)
return template.render(transit_gateway_attachment=transit_gateway_attachment) return template.render(transit_gateway_attachment=transit_gateway_attachment)
def describe_transit_gateway_attachments(self): def describe_transit_gateway_attachments(self) -> str:
transit_gateways_attachment_ids = self._get_multi_param( transit_gateways_attachment_ids = self._get_multi_param(
"TransitGatewayAttachmentIds" "TransitGatewayAttachmentIds"
) )
@ -73,7 +70,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
template = self.response_template(DESCRIBE_TRANSIT_GATEWAY_ATTACHMENTS) template = self.response_template(DESCRIBE_TRANSIT_GATEWAY_ATTACHMENTS)
return template.render(transit_gateway_attachments=transit_gateway_attachments) return template.render(transit_gateway_attachments=transit_gateway_attachments)
def delete_transit_gateway_vpc_attachment(self): def delete_transit_gateway_vpc_attachment(self) -> str:
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId") transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_attachment = ( transit_gateway_attachment = (
self.ec2_backend.delete_transit_gateway_vpc_attachment( self.ec2_backend.delete_transit_gateway_vpc_attachment(
@ -83,7 +80,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
template = self.response_template(DELETE_TRANSIT_GATEWAY_VPC_ATTACHMENTS) template = self.response_template(DELETE_TRANSIT_GATEWAY_VPC_ATTACHMENTS)
return template.render(transit_gateway_attachment=transit_gateway_attachment) return template.render(transit_gateway_attachment=transit_gateway_attachment)
def associate_transit_gateway_route_table(self): def associate_transit_gateway_route_table(self) -> str:
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId") transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
transit_gateway_association = ( transit_gateway_association = (
@ -95,7 +92,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
template = self.response_template(TRANSIT_GATEWAY_ASSOCIATION) template = self.response_template(TRANSIT_GATEWAY_ASSOCIATION)
return template.render(transit_gateway_association=transit_gateway_association) return template.render(transit_gateway_association=transit_gateway_association)
def disassociate_transit_gateway_route_table(self): def disassociate_transit_gateway_route_table(self) -> str:
tgw_attach_id = self._get_param("TransitGatewayAttachmentId") tgw_attach_id = self._get_param("TransitGatewayAttachmentId")
tgw_rt_id = self._get_param("TransitGatewayRouteTableId") tgw_rt_id = self._get_param("TransitGatewayRouteTableId")
@ -105,7 +102,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
template = self.response_template(TRANSIT_GATEWAY_DISASSOCIATION) template = self.response_template(TRANSIT_GATEWAY_DISASSOCIATION)
return template.render(tgw_association=tgw_association) return template.render(tgw_association=tgw_association)
def enable_transit_gateway_route_table_propagation(self): def enable_transit_gateway_route_table_propagation(self) -> str:
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId") transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
transit_gateway_propagation = ( transit_gateway_propagation = (
@ -117,7 +114,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
template = self.response_template(TRANSIT_GATEWAY_PROPAGATION) template = self.response_template(TRANSIT_GATEWAY_PROPAGATION)
return template.render(transit_gateway_propagation=transit_gateway_propagation) return template.render(transit_gateway_propagation=transit_gateway_propagation)
def disable_transit_gateway_route_table_propagation(self): def disable_transit_gateway_route_table_propagation(self) -> str:
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId") transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
transit_gateway_propagation = ( transit_gateway_propagation = (
@ -129,7 +126,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
template = self.response_template(TRANSIT_GATEWAY_PROPAGATION) template = self.response_template(TRANSIT_GATEWAY_PROPAGATION)
return template.render(transit_gateway_propagation=transit_gateway_propagation) return template.render(transit_gateway_propagation=transit_gateway_propagation)
def create_transit_gateway_peering_attachment(self): def create_transit_gateway_peering_attachment(self) -> str:
peer_account_id = self._get_param("PeerAccountId") peer_account_id = self._get_param("PeerAccountId")
peer_region = self._get_param("PeerRegion") peer_region = self._get_param("PeerRegion")
peer_transit_gateway_id = self._get_param("PeerTransitGatewayId") peer_transit_gateway_id = self._get_param("PeerTransitGatewayId")
@ -150,7 +147,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
transit_gateway_peering_attachment=transit_gateway_peering_attachment, transit_gateway_peering_attachment=transit_gateway_peering_attachment,
) )
def describe_transit_gateway_peering_attachments(self): def describe_transit_gateway_peering_attachments(self) -> str:
transit_gateways_attachment_ids = self._get_multi_param( transit_gateways_attachment_ids = self._get_multi_param(
"TransitGatewayAttachmentIds" "TransitGatewayAttachmentIds"
) )
@ -166,7 +163,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
transit_gateway_peering_attachments=transit_gateway_peering_attachments transit_gateway_peering_attachments=transit_gateway_peering_attachments
) )
def accept_transit_gateway_peering_attachment(self): def accept_transit_gateway_peering_attachment(self) -> str:
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId") transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_peering_attachment = ( transit_gateway_peering_attachment = (
self.ec2_backend.accept_transit_gateway_peering_attachment( self.ec2_backend.accept_transit_gateway_peering_attachment(
@ -179,7 +176,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
transit_gateway_peering_attachment=transit_gateway_peering_attachment, transit_gateway_peering_attachment=transit_gateway_peering_attachment,
) )
def delete_transit_gateway_peering_attachment(self): def delete_transit_gateway_peering_attachment(self) -> str:
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId") transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_peering_attachment = ( transit_gateway_peering_attachment = (
self.ec2_backend.delete_transit_gateway_peering_attachment( self.ec2_backend.delete_transit_gateway_peering_attachment(
@ -192,7 +189,7 @@ class TransitGatewayAttachment(EC2BaseResponse):
transit_gateway_peering_attachment=transit_gateway_peering_attachment, transit_gateway_peering_attachment=transit_gateway_peering_attachment,
) )
def reject_transit_gateway_peering_attachment(self): def reject_transit_gateway_peering_attachment(self) -> str:
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId") transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
transit_gateway_peering_attachment = ( transit_gateway_peering_attachment = (
self.ec2_backend.reject_transit_gateway_peering_attachment( self.ec2_backend.reject_transit_gateway_peering_attachment(

View File

@ -3,12 +3,9 @@ from moto.utilities.utils import str2bool
class TransitGatewayRouteTable(EC2BaseResponse): class TransitGatewayRouteTable(EC2BaseResponse):
def create_transit_gateway_route_table(self): def create_transit_gateway_route_table(self) -> str:
transit_gateway_id = self._get_param("TransitGatewayId") transit_gateway_id = self._get_param("TransitGatewayId")
tags = self._get_multi_param("TagSpecifications") tags = self._parse_tag_specification().get("transit-gateway-route-table", {})
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags}
transit_gateway_route_table = ( transit_gateway_route_table = (
self.ec2_backend.create_transit_gateway_route_table( self.ec2_backend.create_transit_gateway_route_table(
@ -18,7 +15,7 @@ class TransitGatewayRouteTable(EC2BaseResponse):
template = self.response_template(CREATE_TRANSIT_GATEWAY_ROUTE_TABLE_RESPONSE) template = self.response_template(CREATE_TRANSIT_GATEWAY_ROUTE_TABLE_RESPONSE)
return template.render(transit_gateway_route_table=transit_gateway_route_table) return template.render(transit_gateway_route_table=transit_gateway_route_table)
def describe_transit_gateway_route_tables(self): def describe_transit_gateway_route_tables(self) -> str:
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
transit_gateway_route_table_ids = ( transit_gateway_route_table_ids = (
self._get_multi_param("TransitGatewayRouteTableIds") or None self._get_multi_param("TransitGatewayRouteTableIds") or None
@ -33,7 +30,7 @@ class TransitGatewayRouteTable(EC2BaseResponse):
transit_gateway_route_tables=transit_gateway_route_tables transit_gateway_route_tables=transit_gateway_route_tables
) )
def delete_transit_gateway_route_table(self): def delete_transit_gateway_route_table(self) -> str:
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
transit_gateway_route_table = ( transit_gateway_route_table = (
self.ec2_backend.delete_transit_gateway_route_table( self.ec2_backend.delete_transit_gateway_route_table(
@ -43,7 +40,7 @@ class TransitGatewayRouteTable(EC2BaseResponse):
template = self.response_template(DELETE_TRANSIT_GATEWAY_ROUTE_TABLE_RESPONSE) template = self.response_template(DELETE_TRANSIT_GATEWAY_ROUTE_TABLE_RESPONSE)
return template.render(transit_gateway_route_table=transit_gateway_route_table) return template.render(transit_gateway_route_table=transit_gateway_route_table)
def create_transit_gateway_route(self): def create_transit_gateway_route(self) -> str:
transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId") transit_gateway_attachment_id = self._get_param("TransitGatewayAttachmentId")
destination_cidr_block = self._get_param("DestinationCidrBlock") destination_cidr_block = self._get_param("DestinationCidrBlock")
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
@ -60,7 +57,7 @@ class TransitGatewayRouteTable(EC2BaseResponse):
destination_cidr_block=destination_cidr_block, destination_cidr_block=destination_cidr_block,
) )
def delete_transit_gateway_route(self): def delete_transit_gateway_route(self) -> str:
destination_cidr_block = self._get_param("DestinationCidrBlock") destination_cidr_block = self._get_param("DestinationCidrBlock")
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
transit_gateway_route_table = self.ec2_backend.delete_transit_gateway_route( transit_gateway_route_table = self.ec2_backend.delete_transit_gateway_route(
@ -75,7 +72,7 @@ class TransitGatewayRouteTable(EC2BaseResponse):
del transit_gateway_route_table.routes[destination_cidr_block] del transit_gateway_route_table.routes[destination_cidr_block]
return rendered_template return rendered_template
def search_transit_gateway_routes(self): def search_transit_gateway_routes(self) -> str:
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
max_results = self._get_param("MaxResults") max_results = self._get_param("MaxResults")
@ -87,7 +84,7 @@ class TransitGatewayRouteTable(EC2BaseResponse):
template = self.response_template(SEARCH_TRANSIT_GATEWAY_ROUTES_RESPONSE) template = self.response_template(SEARCH_TRANSIT_GATEWAY_ROUTES_RESPONSE)
return template.render(transit_gateway_routes=transit_gateway_routes) return template.render(transit_gateway_routes=transit_gateway_routes)
def get_transit_gateway_route_table_associations(self): def get_transit_gateway_route_table_associations(self) -> str:
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
transit_gateway_route_table_associations = ( transit_gateway_route_table_associations = (
@ -102,7 +99,7 @@ class TransitGatewayRouteTable(EC2BaseResponse):
transit_gateway_route_table_associations=transit_gateway_route_table_associations transit_gateway_route_table_associations=transit_gateway_route_table_associations
) )
def get_transit_gateway_route_table_propagations(self): def get_transit_gateway_route_table_propagations(self) -> str:
transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId") transit_gateway_route_table_id = self._get_param("TransitGatewayRouteTableId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
transit_gateway_route_table_propagations = ( transit_gateway_route_table_propagations = (

View File

@ -2,7 +2,7 @@ from ._base_response import EC2BaseResponse
class TransitGateways(EC2BaseResponse): class TransitGateways(EC2BaseResponse):
def create_transit_gateway(self): def create_transit_gateway(self) -> str:
description = self._get_param("Description") or None description = self._get_param("Description") or None
options = self._get_multi_param_dict("Options") options = self._get_multi_param_dict("Options")
tags = self._get_multi_param("TagSpecification") tags = self._get_multi_param("TagSpecification")
@ -32,13 +32,13 @@ class TransitGateways(EC2BaseResponse):
template = self.response_template(CREATE_TRANSIT_GATEWAY_RESPONSE) template = self.response_template(CREATE_TRANSIT_GATEWAY_RESPONSE)
return template.render(transit_gateway=transit_gateway) return template.render(transit_gateway=transit_gateway)
def delete_transit_gateway(self): def delete_transit_gateway(self) -> str:
transit_gateway_id = self._get_param("TransitGatewayId") transit_gateway_id = self._get_param("TransitGatewayId")
transit_gateway = self.ec2_backend.delete_transit_gateway(transit_gateway_id) transit_gateway = self.ec2_backend.delete_transit_gateway(transit_gateway_id)
template = self.response_template(DELETE_TRANSIT_GATEWAY_RESPONSE) template = self.response_template(DELETE_TRANSIT_GATEWAY_RESPONSE)
return template.render(transit_gateway=transit_gateway) return template.render(transit_gateway=transit_gateway)
def describe_transit_gateways(self): def describe_transit_gateways(self) -> str:
transit_gateway_ids = self._get_multi_param("TransitGatewayIds") transit_gateway_ids = self._get_multi_param("TransitGatewayIds")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
transit_gateways = self.ec2_backend.describe_transit_gateways( transit_gateways = self.ec2_backend.describe_transit_gateways(
@ -47,7 +47,7 @@ class TransitGateways(EC2BaseResponse):
template = self.response_template(DESCRIBE_TRANSIT_GATEWAY_RESPONSE) template = self.response_template(DESCRIBE_TRANSIT_GATEWAY_RESPONSE)
return template.render(transit_gateways=transit_gateways) return template.render(transit_gateways=transit_gateways)
def modify_transit_gateway(self): def modify_transit_gateway(self) -> str:
transit_gateway_id = self._get_param("TransitGatewayId") transit_gateway_id = self._get_param("TransitGatewayId")
description = self._get_param("Description") or None description = self._get_param("Description") or None
options = self._get_multi_param_dict("Options") options = self._get_multi_param_dict("Options")

View File

@ -2,21 +2,18 @@ from ._base_response import EC2BaseResponse
class VirtualPrivateGateways(EC2BaseResponse): class VirtualPrivateGateways(EC2BaseResponse):
def attach_vpn_gateway(self): def attach_vpn_gateway(self) -> str:
vpn_gateway_id = self._get_param("VpnGatewayId") vpn_gateway_id = self._get_param("VpnGatewayId")
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
attachment = self.ec2_backend.attach_vpn_gateway(vpn_gateway_id, vpc_id) attachment = self.ec2_backend.attach_vpn_gateway(vpn_gateway_id, vpc_id)
template = self.response_template(ATTACH_VPN_GATEWAY_RESPONSE) template = self.response_template(ATTACH_VPN_GATEWAY_RESPONSE)
return template.render(attachment=attachment) return template.render(attachment=attachment)
def create_vpn_gateway(self): def create_vpn_gateway(self) -> str:
gateway_type = self._get_param("Type") gateway_type = self._get_param("Type")
amazon_side_asn = self._get_param("AmazonSideAsn") amazon_side_asn = self._get_param("AmazonSideAsn")
availability_zone = self._get_param("AvailabilityZone") availability_zone = self._get_param("AvailabilityZone")
tags = self._get_multi_param("TagSpecification") tags = self._parse_tag_specification().get("virtual-private-gateway", {})
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags}
vpn_gateway = self.ec2_backend.create_vpn_gateway( vpn_gateway = self.ec2_backend.create_vpn_gateway(
gateway_type=gateway_type, gateway_type=gateway_type,
amazon_side_asn=amazon_side_asn, amazon_side_asn=amazon_side_asn,
@ -26,20 +23,20 @@ class VirtualPrivateGateways(EC2BaseResponse):
template = self.response_template(CREATE_VPN_GATEWAY_RESPONSE) template = self.response_template(CREATE_VPN_GATEWAY_RESPONSE)
return template.render(vpn_gateway=vpn_gateway) return template.render(vpn_gateway=vpn_gateway)
def delete_vpn_gateway(self): def delete_vpn_gateway(self) -> str:
vpn_gateway_id = self._get_param("VpnGatewayId") vpn_gateway_id = self._get_param("VpnGatewayId")
vpn_gateway = self.ec2_backend.delete_vpn_gateway(vpn_gateway_id) vpn_gateway = self.ec2_backend.delete_vpn_gateway(vpn_gateway_id)
template = self.response_template(DELETE_VPN_GATEWAY_RESPONSE) template = self.response_template(DELETE_VPN_GATEWAY_RESPONSE)
return template.render(vpn_gateway=vpn_gateway) return template.render(vpn_gateway=vpn_gateway)
def describe_vpn_gateways(self): def describe_vpn_gateways(self) -> str:
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
vpn_gw_ids = self._get_multi_param("VpnGatewayId") vpn_gw_ids = self._get_multi_param("VpnGatewayId")
vpn_gateways = self.ec2_backend.describe_vpn_gateways(filters, vpn_gw_ids) vpn_gateways = self.ec2_backend.describe_vpn_gateways(filters, vpn_gw_ids)
template = self.response_template(DESCRIBE_VPN_GATEWAYS_RESPONSE) template = self.response_template(DESCRIBE_VPN_GATEWAYS_RESPONSE)
return template.render(vpn_gateways=vpn_gateways) return template.render(vpn_gateways=vpn_gateways)
def detach_vpn_gateway(self): def detach_vpn_gateway(self) -> str:
vpn_gateway_id = self._get_param("VpnGatewayId") vpn_gateway_id = self._get_param("VpnGatewayId")
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
attachment = self.ec2_backend.detach_vpn_gateway(vpn_gateway_id, vpc_id) attachment = self.ec2_backend.detach_vpn_gateway(vpn_gateway_id, vpc_id)

View File

@ -1,16 +0,0 @@
from moto.core.responses import BaseResponse
class VMExport(BaseResponse):
def cancel_export_task(self):
raise NotImplementedError("VMExport.cancel_export_task is not yet implemented")
def create_instance_export_task(self):
raise NotImplementedError(
"VMExport.create_instance_export_task is not yet implemented"
)
def describe_export_tasks(self):
raise NotImplementedError(
"VMExport.describe_export_tasks is not yet implemented"
)

View File

@ -1,19 +0,0 @@
from moto.core.responses import BaseResponse
class VMImport(BaseResponse):
def cancel_conversion_task(self):
raise NotImplementedError(
"VMImport.cancel_conversion_task is not yet implemented"
)
def describe_conversion_tasks(self):
raise NotImplementedError(
"VMImport.describe_conversion_tasks is not yet implemented"
)
def import_instance(self):
raise NotImplementedError("VMImport.import_instance is not yet implemented")
def import_volume(self):
raise NotImplementedError("VMImport.import_volume is not yet implemented")

View File

@ -1,13 +1,10 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
class VPCPeeringConnections(BaseResponse): class VPCPeeringConnections(EC2BaseResponse):
def create_vpc_peering_connection(self): def create_vpc_peering_connection(self) -> str:
peer_region = self._get_param("PeerRegion") peer_region = self._get_param("PeerRegion")
tags = self._get_multi_param("TagSpecification") tags = self._parse_tag_specification().get("vpc-peering-connection", {})
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags}
if peer_region == self.region or peer_region is None: if peer_region == self.region or peer_region is None:
peer_vpc = self.ec2_backend.get_vpc(self._get_param("PeerVpcId")) peer_vpc = self.ec2_backend.get_vpc(self._get_param("PeerVpcId"))
@ -22,13 +19,13 @@ class VPCPeeringConnections(BaseResponse):
template = self.response_template(CREATE_VPC_PEERING_CONNECTION_RESPONSE) template = self.response_template(CREATE_VPC_PEERING_CONNECTION_RESPONSE)
return template.render(account_id=self.current_account, vpc_pcx=vpc_pcx) return template.render(account_id=self.current_account, vpc_pcx=vpc_pcx)
def delete_vpc_peering_connection(self): def delete_vpc_peering_connection(self) -> str:
vpc_pcx_id = self._get_param("VpcPeeringConnectionId") vpc_pcx_id = self._get_param("VpcPeeringConnectionId")
vpc_pcx = self.ec2_backend.delete_vpc_peering_connection(vpc_pcx_id) vpc_pcx = self.ec2_backend.delete_vpc_peering_connection(vpc_pcx_id)
template = self.response_template(DELETE_VPC_PEERING_CONNECTION_RESPONSE) template = self.response_template(DELETE_VPC_PEERING_CONNECTION_RESPONSE)
return template.render(vpc_pcx=vpc_pcx) return template.render(vpc_pcx=vpc_pcx)
def describe_vpc_peering_connections(self): def describe_vpc_peering_connections(self) -> str:
ids = self._get_multi_param("VpcPeeringConnectionId") ids = self._get_multi_param("VpcPeeringConnectionId")
vpc_pcxs = self.ec2_backend.describe_vpc_peering_connections( vpc_pcxs = self.ec2_backend.describe_vpc_peering_connections(
vpc_peering_ids=ids vpc_peering_ids=ids
@ -36,19 +33,19 @@ class VPCPeeringConnections(BaseResponse):
template = self.response_template(DESCRIBE_VPC_PEERING_CONNECTIONS_RESPONSE) template = self.response_template(DESCRIBE_VPC_PEERING_CONNECTIONS_RESPONSE)
return template.render(account_id=self.current_account, vpc_pcxs=vpc_pcxs) return template.render(account_id=self.current_account, vpc_pcxs=vpc_pcxs)
def accept_vpc_peering_connection(self): def accept_vpc_peering_connection(self) -> str:
vpc_pcx_id = self._get_param("VpcPeeringConnectionId") vpc_pcx_id = self._get_param("VpcPeeringConnectionId")
vpc_pcx = self.ec2_backend.accept_vpc_peering_connection(vpc_pcx_id) vpc_pcx = self.ec2_backend.accept_vpc_peering_connection(vpc_pcx_id)
template = self.response_template(ACCEPT_VPC_PEERING_CONNECTION_RESPONSE) template = self.response_template(ACCEPT_VPC_PEERING_CONNECTION_RESPONSE)
return template.render(account_id=self.current_account, vpc_pcx=vpc_pcx) return template.render(account_id=self.current_account, vpc_pcx=vpc_pcx)
def reject_vpc_peering_connection(self): def reject_vpc_peering_connection(self) -> str:
vpc_pcx_id = self._get_param("VpcPeeringConnectionId") vpc_pcx_id = self._get_param("VpcPeeringConnectionId")
self.ec2_backend.reject_vpc_peering_connection(vpc_pcx_id) self.ec2_backend.reject_vpc_peering_connection(vpc_pcx_id)
template = self.response_template(REJECT_VPC_PEERING_CONNECTION_RESPONSE) template = self.response_template(REJECT_VPC_PEERING_CONNECTION_RESPONSE)
return template.render() return template.render()
def modify_vpc_peering_connection_options(self): def modify_vpc_peering_connection_options(self) -> str:
vpc_pcx_id = self._get_param("VpcPeeringConnectionId") vpc_pcx_id = self._get_param("VpcPeeringConnectionId")
accepter_options = self._get_multi_param_dict( accepter_options = self._get_multi_param_dict(
"AccepterPeeringConnectionOptions" "AccepterPeeringConnectionOptions"

View File

@ -1,10 +1,9 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
from ..exceptions import NoLoadBalancersProvided from ..exceptions import NoLoadBalancersProvided
class VPCEndpointServiceConfiguration(BaseResponse): class VPCEndpointServiceConfiguration(EC2BaseResponse):
def create_vpc_endpoint_service_configuration(self): def create_vpc_endpoint_service_configuration(self) -> str:
gateway_lbs = self._get_multi_param("GatewayLoadBalancerArn") gateway_lbs = self._get_multi_param("GatewayLoadBalancerArn")
network_lbs = self._get_multi_param("NetworkLoadBalancerArn") network_lbs = self._get_multi_param("NetworkLoadBalancerArn")
if not gateway_lbs and not network_lbs: if not gateway_lbs and not network_lbs:
@ -27,7 +26,7 @@ class VPCEndpointServiceConfiguration(BaseResponse):
template = self.response_template(CREATE_VPC_ENDPOINT_SERVICE_CONFIGURATION) template = self.response_template(CREATE_VPC_ENDPOINT_SERVICE_CONFIGURATION)
return template.render(config=config) return template.render(config=config)
def describe_vpc_endpoint_service_configurations(self): def describe_vpc_endpoint_service_configurations(self) -> str:
service_ids = self._get_multi_param("ServiceId") service_ids = self._get_multi_param("ServiceId")
configs = self.ec2_backend.describe_vpc_endpoint_service_configurations( configs = self.ec2_backend.describe_vpc_endpoint_service_configurations(
@ -37,7 +36,7 @@ class VPCEndpointServiceConfiguration(BaseResponse):
template = self.response_template(DESCRIBE_VPC_ENDPOINT_SERVICE_CONFIGURATION) template = self.response_template(DESCRIBE_VPC_ENDPOINT_SERVICE_CONFIGURATION)
return template.render(configs=configs) return template.render(configs=configs)
def delete_vpc_endpoint_service_configurations(self): def delete_vpc_endpoint_service_configurations(self) -> str:
service_ids = self._get_multi_param("ServiceId") service_ids = self._get_multi_param("ServiceId")
missing_configs = self.ec2_backend.delete_vpc_endpoint_service_configurations( missing_configs = self.ec2_backend.delete_vpc_endpoint_service_configurations(
service_ids service_ids
@ -46,7 +45,7 @@ class VPCEndpointServiceConfiguration(BaseResponse):
template = self.response_template(DELETE_VPC_ENDPOINT_SERVICE_CONFIGURATION) template = self.response_template(DELETE_VPC_ENDPOINT_SERVICE_CONFIGURATION)
return template.render(missing=missing_configs) return template.render(missing=missing_configs)
def describe_vpc_endpoint_service_permissions(self): def describe_vpc_endpoint_service_permissions(self) -> str:
service_id = self._get_param("ServiceId") service_id = self._get_param("ServiceId")
principals = self.ec2_backend.describe_vpc_endpoint_service_permissions( principals = self.ec2_backend.describe_vpc_endpoint_service_permissions(
@ -56,7 +55,7 @@ class VPCEndpointServiceConfiguration(BaseResponse):
template = self.response_template(DESCRIBE_VPC_ENDPOINT_SERVICE_PERMISSIONS) template = self.response_template(DESCRIBE_VPC_ENDPOINT_SERVICE_PERMISSIONS)
return template.render(principals=principals) return template.render(principals=principals)
def modify_vpc_endpoint_service_configuration(self): def modify_vpc_endpoint_service_configuration(self) -> str:
service_id = self._get_param("ServiceId") service_id = self._get_param("ServiceId")
private_dns_name = self._get_param("PrivateDnsName") private_dns_name = self._get_param("PrivateDnsName")
acceptance_required = self._get_param("AcceptanceRequired") acceptance_required = self._get_param("AcceptanceRequired")
@ -77,7 +76,7 @@ class VPCEndpointServiceConfiguration(BaseResponse):
return MODIFY_VPC_ENDPOINT_SERVICE_CONFIGURATION return MODIFY_VPC_ENDPOINT_SERVICE_CONFIGURATION
def modify_vpc_endpoint_service_permissions(self): def modify_vpc_endpoint_service_permissions(self) -> str:
service_id = self._get_param("ServiceId") service_id = self._get_param("ServiceId")
add_principals = self._get_multi_param("AddAllowedPrincipals") add_principals = self._get_multi_param("AddAllowedPrincipals")
remove_principals = self._get_multi_param("RemoveAllowedPrincipals") remove_principals = self._get_multi_param("RemoveAllowedPrincipals")

View File

@ -4,20 +4,20 @@ from ._base_response import EC2BaseResponse
class VPCs(EC2BaseResponse): class VPCs(EC2BaseResponse):
def _get_doc_date(self): def _get_doc_date(self) -> str:
return ( return (
"2013-10-15" "2013-10-15"
if "Boto/" in self.headers.get("user-agent", "") if "Boto/" in self.headers.get("user-agent", "")
else "2016-11-15" else "2016-11-15"
) )
def create_default_vpc(self): def create_default_vpc(self) -> str:
vpc = self.ec2_backend.create_default_vpc() vpc = self.ec2_backend.create_default_vpc()
doc_date = self._get_doc_date() doc_date = self._get_doc_date()
template = self.response_template(CREATE_VPC_RESPONSE) template = self.response_template(CREATE_VPC_RESPONSE)
return template.render(vpc=vpc, doc_date=doc_date) return template.render(vpc=vpc, doc_date=doc_date)
def create_vpc(self): def create_vpc(self) -> str:
cidr_block = self._get_param("CidrBlock") cidr_block = self._get_param("CidrBlock")
tags = self._get_multi_param("TagSpecification") tags = self._get_multi_param("TagSpecification")
instance_tenancy = self._get_param("InstanceTenancy", if_none="default") instance_tenancy = self._get_param("InstanceTenancy", if_none="default")
@ -43,13 +43,13 @@ class VPCs(EC2BaseResponse):
template = self.response_template(CREATE_VPC_RESPONSE) template = self.response_template(CREATE_VPC_RESPONSE)
return template.render(vpc=vpc, doc_date=doc_date) return template.render(vpc=vpc, doc_date=doc_date)
def delete_vpc(self): def delete_vpc(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
vpc = self.ec2_backend.delete_vpc(vpc_id) vpc = self.ec2_backend.delete_vpc(vpc_id)
template = self.response_template(DELETE_VPC_RESPONSE) template = self.response_template(DELETE_VPC_RESPONSE)
return template.render(vpc=vpc) return template.render(vpc=vpc)
def describe_vpcs(self): def describe_vpcs(self) -> str:
self.error_on_dryrun() self.error_on_dryrun()
vpc_ids = self._get_multi_param("VpcId") vpc_ids = self._get_multi_param("VpcId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
@ -62,13 +62,13 @@ class VPCs(EC2BaseResponse):
template = self.response_template(DESCRIBE_VPCS_RESPONSE) template = self.response_template(DESCRIBE_VPCS_RESPONSE)
return template.render(vpcs=vpcs, doc_date=doc_date, region=self.region) return template.render(vpcs=vpcs, doc_date=doc_date, region=self.region)
def modify_vpc_tenancy(self): def modify_vpc_tenancy(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
tenancy = self._get_param("InstanceTenancy") tenancy = self._get_param("InstanceTenancy")
self.ec2_backend.modify_vpc_tenancy(vpc_id, tenancy) self.ec2_backend.modify_vpc_tenancy(vpc_id, tenancy)
return self.response_template(MODIFY_VPC_TENANCY_RESPONSE).render() return self.response_template(MODIFY_VPC_TENANCY_RESPONSE).render()
def describe_vpc_attribute(self): def describe_vpc_attribute(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
attribute = self._get_param("Attribute") attribute = self._get_param("Attribute")
attr_name = camelcase_to_underscores(attribute) attr_name = camelcase_to_underscores(attribute)
@ -76,7 +76,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(DESCRIBE_VPC_ATTRIBUTE_RESPONSE) template = self.response_template(DESCRIBE_VPC_ATTRIBUTE_RESPONSE)
return template.render(vpc_id=vpc_id, attribute=attribute, value=value) return template.render(vpc_id=vpc_id, attribute=attribute, value=value)
def describe_vpc_classic_link_dns_support(self): def describe_vpc_classic_link_dns_support(self) -> str:
vpc_ids = self._get_multi_param("VpcIds") vpc_ids = self._get_multi_param("VpcIds")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
vpcs = self.ec2_backend.describe_vpcs(vpc_ids=vpc_ids, filters=filters) vpcs = self.ec2_backend.describe_vpcs(vpc_ids=vpc_ids, filters=filters)
@ -86,7 +86,7 @@ class VPCs(EC2BaseResponse):
) )
return template.render(vpcs=vpcs, doc_date=doc_date) return template.render(vpcs=vpcs, doc_date=doc_date)
def enable_vpc_classic_link_dns_support(self): def enable_vpc_classic_link_dns_support(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
classic_link_dns_supported = ( classic_link_dns_supported = (
self.ec2_backend.enable_vpc_classic_link_dns_support(vpc_id=vpc_id) self.ec2_backend.enable_vpc_classic_link_dns_support(vpc_id=vpc_id)
@ -97,7 +97,7 @@ class VPCs(EC2BaseResponse):
classic_link_dns_supported=classic_link_dns_supported, doc_date=doc_date classic_link_dns_supported=classic_link_dns_supported, doc_date=doc_date
) )
def disable_vpc_classic_link_dns_support(self): def disable_vpc_classic_link_dns_support(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
classic_link_dns_supported = ( classic_link_dns_supported = (
self.ec2_backend.disable_vpc_classic_link_dns_support(vpc_id=vpc_id) self.ec2_backend.disable_vpc_classic_link_dns_support(vpc_id=vpc_id)
@ -108,7 +108,7 @@ class VPCs(EC2BaseResponse):
classic_link_dns_supported=classic_link_dns_supported, doc_date=doc_date classic_link_dns_supported=classic_link_dns_supported, doc_date=doc_date
) )
def describe_vpc_classic_link(self): def describe_vpc_classic_link(self) -> str:
vpc_ids = self._get_multi_param("VpcId") vpc_ids = self._get_multi_param("VpcId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
vpcs = self.ec2_backend.describe_vpcs(vpc_ids=vpc_ids, filters=filters) vpcs = self.ec2_backend.describe_vpcs(vpc_ids=vpc_ids, filters=filters)
@ -116,7 +116,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(DESCRIBE_VPC_CLASSIC_LINK_RESPONSE) template = self.response_template(DESCRIBE_VPC_CLASSIC_LINK_RESPONSE)
return template.render(vpcs=vpcs, doc_date=doc_date) return template.render(vpcs=vpcs, doc_date=doc_date)
def enable_vpc_classic_link(self): def enable_vpc_classic_link(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
classic_link_enabled = self.ec2_backend.enable_vpc_classic_link(vpc_id=vpc_id) classic_link_enabled = self.ec2_backend.enable_vpc_classic_link(vpc_id=vpc_id)
doc_date = self._get_doc_date() doc_date = self._get_doc_date()
@ -125,7 +125,7 @@ class VPCs(EC2BaseResponse):
classic_link_enabled=classic_link_enabled, doc_date=doc_date classic_link_enabled=classic_link_enabled, doc_date=doc_date
) )
def disable_vpc_classic_link(self): def disable_vpc_classic_link(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
classic_link_enabled = self.ec2_backend.disable_vpc_classic_link(vpc_id=vpc_id) classic_link_enabled = self.ec2_backend.disable_vpc_classic_link(vpc_id=vpc_id)
doc_date = self._get_doc_date() doc_date = self._get_doc_date()
@ -134,7 +134,7 @@ class VPCs(EC2BaseResponse):
classic_link_enabled=classic_link_enabled, doc_date=doc_date classic_link_enabled=classic_link_enabled, doc_date=doc_date
) )
def modify_vpc_attribute(self): def modify_vpc_attribute(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
for attribute in ( for attribute in (
"EnableDnsSupport", "EnableDnsSupport",
@ -143,12 +143,12 @@ class VPCs(EC2BaseResponse):
): ):
if self.querystring.get(f"{attribute}.Value"): if self.querystring.get(f"{attribute}.Value"):
attr_name = camelcase_to_underscores(attribute) attr_name = camelcase_to_underscores(attribute)
attr_value = self.querystring.get(f"{attribute}.Value")[0] attr_value = self.querystring[f"{attribute}.Value"][0]
self.ec2_backend.modify_vpc_attribute(vpc_id, attr_name, attr_value) self.ec2_backend.modify_vpc_attribute(vpc_id, attr_name, attr_value)
return MODIFY_VPC_ATTRIBUTE_RESPONSE return MODIFY_VPC_ATTRIBUTE_RESPONSE
return None return ""
def associate_vpc_cidr_block(self): def associate_vpc_cidr_block(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
amazon_provided_ipv6_cidr_blocks = self._get_param( amazon_provided_ipv6_cidr_blocks = self._get_param(
"AmazonProvidedIpv6CidrBlock" "AmazonProvidedIpv6CidrBlock"
@ -175,7 +175,7 @@ class VPCs(EC2BaseResponse):
cidr_block_state="associating", cidr_block_state="associating",
) )
def disassociate_vpc_cidr_block(self): def disassociate_vpc_cidr_block(self) -> str:
association_id = self._get_param("AssociationId") association_id = self._get_param("AssociationId")
value = self.ec2_backend.disassociate_vpc_cidr_block(association_id) value = self.ec2_backend.disassociate_vpc_cidr_block(association_id)
if "::" in value.get("cidr_block", ""): if "::" in value.get("cidr_block", ""):
@ -190,7 +190,7 @@ class VPCs(EC2BaseResponse):
cidr_block_state="disassociating", cidr_block_state="disassociating",
) )
def create_vpc_endpoint(self): def create_vpc_endpoint(self) -> str:
vpc_id = self._get_param("VpcId") vpc_id = self._get_param("VpcId")
service_name = self._get_param("ServiceName") service_name = self._get_param("ServiceName")
route_table_ids = self._get_multi_param("RouteTableId") route_table_ids = self._get_multi_param("RouteTableId")
@ -198,11 +198,10 @@ class VPCs(EC2BaseResponse):
endpoint_type = self._get_param("VpcEndpointType") endpoint_type = self._get_param("VpcEndpointType")
policy_document = self._get_param("PolicyDocument") policy_document = self._get_param("PolicyDocument")
client_token = self._get_param("ClientToken") client_token = self._get_param("ClientToken")
tags = self._get_multi_param("TagSpecification")
private_dns_enabled = self._get_bool_param("PrivateDnsEnabled", if_none=True) private_dns_enabled = self._get_bool_param("PrivateDnsEnabled", if_none=True)
security_group_ids = self._get_multi_param("SecurityGroupId") security_group_ids = self._get_multi_param("SecurityGroupId")
tags = add_tag_specification(tags) tags = add_tag_specification(self._get_multi_param("TagSpecification"))
vpc_end_point = self.ec2_backend.create_vpc_endpoint( vpc_end_point = self.ec2_backend.create_vpc_endpoint(
vpc_id=vpc_id, vpc_id=vpc_id,
service_name=service_name, service_name=service_name,
@ -218,7 +217,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(CREATE_VPC_END_POINT) template = self.response_template(CREATE_VPC_END_POINT)
return template.render(vpc_end_point=vpc_end_point) return template.render(vpc_end_point=vpc_end_point)
def modify_vpc_endpoint(self): def modify_vpc_endpoint(self) -> str:
vpc_id = self._get_param("VpcEndpointId") vpc_id = self._get_param("VpcEndpointId")
add_subnets = self._get_multi_param("AddSubnetId") add_subnets = self._get_multi_param("AddSubnetId")
add_route_tables = self._get_multi_param("AddRouteTableId") add_route_tables = self._get_multi_param("AddRouteTableId")
@ -234,7 +233,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(MODIFY_VPC_END_POINT) template = self.response_template(MODIFY_VPC_END_POINT)
return template.render() return template.render()
def describe_vpc_endpoint_services(self): def describe_vpc_endpoint_services(self) -> str:
vpc_end_point_services = self.ec2_backend.describe_vpc_endpoint_services( vpc_end_point_services = self.ec2_backend.describe_vpc_endpoint_services(
service_names=self._get_multi_param("ServiceName"), service_names=self._get_multi_param("ServiceName"),
filters=self._get_multi_param("Filter"), filters=self._get_multi_param("Filter"),
@ -245,7 +244,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(DESCRIBE_VPC_ENDPOINT_SERVICES_RESPONSE) template = self.response_template(DESCRIBE_VPC_ENDPOINT_SERVICES_RESPONSE)
return template.render(vpc_end_points=vpc_end_point_services) return template.render(vpc_end_points=vpc_end_point_services)
def describe_vpc_endpoints(self): def describe_vpc_endpoints(self) -> str:
vpc_end_points_ids = self._get_multi_param("VpcEndpointId") vpc_end_points_ids = self._get_multi_param("VpcEndpointId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
vpc_end_points = self.ec2_backend.describe_vpc_endpoints( vpc_end_points = self.ec2_backend.describe_vpc_endpoints(
@ -256,21 +255,18 @@ class VPCs(EC2BaseResponse):
vpc_end_points=vpc_end_points, account_id=self.current_account vpc_end_points=vpc_end_points, account_id=self.current_account
) )
def delete_vpc_endpoints(self): def delete_vpc_endpoints(self) -> str:
vpc_end_points_ids = self._get_multi_param("VpcEndpointId") vpc_end_points_ids = self._get_multi_param("VpcEndpointId")
self.ec2_backend.delete_vpc_endpoints(vpce_ids=vpc_end_points_ids) self.ec2_backend.delete_vpc_endpoints(vpce_ids=vpc_end_points_ids)
return self.response_template(DELETE_VPC_ENDPOINT_RESPONSE).render() return self.response_template(DELETE_VPC_ENDPOINT_RESPONSE).render()
def create_managed_prefix_list(self): def create_managed_prefix_list(self) -> str:
address_family = self._get_param("AddressFamily") address_family = self._get_param("AddressFamily")
max_entries = self._get_param("MaxEntries") max_entries = self._get_param("MaxEntries")
prefix_list_name = self._get_param("PrefixListName") prefix_list_name = self._get_param("PrefixListName")
entry = self._get_multi_param("Entry") entry = self._get_multi_param("Entry")
tags = self._get_multi_param("TagSpecification") tags = self._parse_tag_specification().get("prefix-list", {})
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags}
managed_prefix_list = self.ec2_backend.create_managed_prefix_list( managed_prefix_list = self.ec2_backend.create_managed_prefix_list(
address_family=address_family, address_family=address_family,
@ -282,7 +278,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(CREATE_MANAGED_PREFIX_LIST) template = self.response_template(CREATE_MANAGED_PREFIX_LIST)
return template.render(managed_prefix_list=managed_prefix_list) return template.render(managed_prefix_list=managed_prefix_list)
def describe_managed_prefix_lists(self): def describe_managed_prefix_lists(self) -> str:
prefix_list_ids = self._get_multi_param("PrefixListId") prefix_list_ids = self._get_multi_param("PrefixListId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
managed_prefix_lists = self.ec2_backend.describe_managed_prefix_lists( managed_prefix_lists = self.ec2_backend.describe_managed_prefix_lists(
@ -291,7 +287,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(DESCRIBE_MANAGED_PREFIX_LIST) template = self.response_template(DESCRIBE_MANAGED_PREFIX_LIST)
return template.render(managed_prefix_lists=managed_prefix_lists) return template.render(managed_prefix_lists=managed_prefix_lists)
def get_managed_prefix_list_entries(self): def get_managed_prefix_list_entries(self) -> str:
prefix_list_id = self._get_param("PrefixListId") prefix_list_id = self._get_param("PrefixListId")
target_version = self._get_param("TargetVersion") target_version = self._get_param("TargetVersion")
managed_prefix_list = self.ec2_backend.get_managed_prefix_list_entries( managed_prefix_list = self.ec2_backend.get_managed_prefix_list_entries(
@ -310,7 +306,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(GET_MANAGED_PREFIX_LIST_ENTRIES) template = self.response_template(GET_MANAGED_PREFIX_LIST_ENTRIES)
return template.render(entries=entries) return template.render(entries=entries)
def delete_managed_prefix_list(self): def delete_managed_prefix_list(self) -> str:
prefix_list_id = self._get_param("PrefixListId") prefix_list_id = self._get_param("PrefixListId")
managed_prefix_list = self.ec2_backend.delete_managed_prefix_list( managed_prefix_list = self.ec2_backend.delete_managed_prefix_list(
prefix_list_id prefix_list_id
@ -318,7 +314,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(DELETE_MANAGED_PREFIX_LIST) template = self.response_template(DELETE_MANAGED_PREFIX_LIST)
return template.render(managed_prefix_list=managed_prefix_list) return template.render(managed_prefix_list=managed_prefix_list)
def describe_prefix_lists(self): def describe_prefix_lists(self) -> str:
prefix_list_ids = self._get_multi_param("PrefixListId") prefix_list_ids = self._get_multi_param("PrefixListId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
managed_pls = self.ec2_backend.describe_managed_prefix_lists( managed_pls = self.ec2_backend.describe_managed_prefix_lists(
@ -327,7 +323,7 @@ class VPCs(EC2BaseResponse):
template = self.response_template(DESCRIBE_PREFIX_LIST) template = self.response_template(DESCRIBE_PREFIX_LIST)
return template.render(managed_pls=managed_pls) return template.render(managed_pls=managed_pls)
def modify_managed_prefix_list(self): def modify_managed_prefix_list(self) -> str:
add_entry = self._get_multi_param("AddEntry") add_entry = self._get_multi_param("AddEntry")
prefix_list_id = self._get_param("PrefixListId") prefix_list_id = self._get_param("PrefixListId")
current_version = self._get_param("CurrentVersion") current_version = self._get_param("CurrentVersion")

View File

@ -4,7 +4,7 @@ from xml.sax.saxutils import escape
class VPNConnections(EC2BaseResponse): class VPNConnections(EC2BaseResponse):
def create_vpn_connection(self): def create_vpn_connection(self) -> str:
vpn_conn_type = self._get_param("Type") vpn_conn_type = self._get_param("Type")
cgw_id = self._get_param("CustomerGatewayId") cgw_id = self._get_param("CustomerGatewayId")
vgw_id = self._get_param("VpnGatewayId") vgw_id = self._get_param("VpnGatewayId")
@ -26,7 +26,7 @@ class VPNConnections(EC2BaseResponse):
template = self.response_template(CREATE_VPN_CONNECTION_RESPONSE) template = self.response_template(CREATE_VPN_CONNECTION_RESPONSE)
return template.render(vpn_connection=vpn_connection) return template.render(vpn_connection=vpn_connection)
def delete_vpn_connection(self): def delete_vpn_connection(self) -> str:
vpn_connection_id = self._get_param("VpnConnectionId") vpn_connection_id = self._get_param("VpnConnectionId")
vpn_connection = self.ec2_backend.delete_vpn_connection(vpn_connection_id) vpn_connection = self.ec2_backend.delete_vpn_connection(vpn_connection_id)
if vpn_connection.transit_gateway_id: if vpn_connection.transit_gateway_id:
@ -39,7 +39,7 @@ class VPNConnections(EC2BaseResponse):
template = self.response_template(DELETE_VPN_CONNECTION_RESPONSE) template = self.response_template(DELETE_VPN_CONNECTION_RESPONSE)
return template.render(vpn_connection=vpn_connection) return template.render(vpn_connection=vpn_connection)
def describe_vpn_connections(self): def describe_vpn_connections(self) -> str:
vpn_connection_ids = self._get_multi_param("VpnConnectionId") vpn_connection_ids = self._get_multi_param("VpnConnectionId")
filters = self._filters_from_querystring() filters = self._filters_from_querystring()
vpn_connections = self.ec2_backend.describe_vpn_connections( vpn_connections = self.ec2_backend.describe_vpn_connections(

View File

@ -1,20 +1,20 @@
from moto.core.responses import BaseResponse from ._base_response import EC2BaseResponse
from moto.ec2.utils import utc_date_and_time from moto.ec2.utils import utc_date_and_time
class Windows(BaseResponse): class Windows(EC2BaseResponse):
def bundle_instance(self): def bundle_instance(self) -> str:
raise NotImplementedError("Windows.bundle_instance is not yet implemented") raise NotImplementedError("Windows.bundle_instance is not yet implemented")
def cancel_bundle_task(self): def cancel_bundle_task(self) -> str:
raise NotImplementedError("Windows.cancel_bundle_task is not yet implemented") raise NotImplementedError("Windows.cancel_bundle_task is not yet implemented")
def describe_bundle_tasks(self): def describe_bundle_tasks(self) -> str:
raise NotImplementedError( raise NotImplementedError(
"Windows.describe_bundle_tasks is not yet implemented" "Windows.describe_bundle_tasks is not yet implemented"
) )
def get_password_data(self): def get_password_data(self) -> str:
instance_id = self._get_param("InstanceId") instance_id = self._get_param("InstanceId")
password_data = self.ec2_backend.get_password_data(instance_id) password_data = self.ec2_backend.get_password_data(instance_id)
template = self.response_template(GET_PASSWORD_DATA_RESPONSE) template = self.response_template(GET_PASSWORD_DATA_RESPONSE)

View File

@ -7,7 +7,7 @@ from datetime import datetime
from cryptography.hazmat.primitives import serialization from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.backends import default_backend from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives.asymmetric import rsa from cryptography.hazmat.primitives.asymmetric import rsa
from typing import Any, Dict, List, TypeVar, Tuple, Optional from typing import Any, Dict, List, Set, TypeVar, Tuple, Optional, Union
from moto.iam import iam_backends from moto.iam import iam_backends
from moto.moto_api._internal import mock_random as random from moto.moto_api._internal import mock_random as random
@ -64,11 +64,11 @@ EC2_PREFIX_TO_RESOURCE = dict((v, k) for (k, v) in EC2_RESOURCE_TO_PREFIX.items(
HEX_CHARS = list(str(x) for x in range(10)) + ["a", "b", "c", "d", "e", "f"] HEX_CHARS = list(str(x) for x in range(10)) + ["a", "b", "c", "d", "e", "f"]
def random_resource_id(size=8): def random_resource_id(size: int = 8) -> str:
return "".join(random.choice(HEX_CHARS) for _ in range(size)) return "".join(random.choice(HEX_CHARS) for _ in range(size))
def random_id(prefix="", size=8): def random_id(prefix: str = "", size: int = 8) -> str:
return f"{prefix}-{random_resource_id(size)}" return f"{prefix}-{random_resource_id(size)}"
@ -244,7 +244,7 @@ def random_dedicated_host_id() -> str:
return random_id(prefix=EC2_RESOURCE_TO_PREFIX["dedicated_host"], size=17) return random_id(prefix=EC2_RESOURCE_TO_PREFIX["dedicated_host"], size=17)
def random_private_ip(cidr: str = None, ipv6: bool = False) -> str: def random_private_ip(cidr: Optional[str] = None, ipv6: bool = False) -> str:
# prefix - ula.prefixlen : get number of remaing length for the IP. # prefix - ula.prefixlen : get number of remaing length for the IP.
# prefix will be 32 for IPv4 and 128 for IPv6. # prefix will be 32 for IPv4 and 128 for IPv6.
# random.getrandbits() will generate remaining bits for IPv6 or Ipv4 in decimal format # random.getrandbits() will generate remaining bits for IPv6 or Ipv4 in decimal format
@ -252,7 +252,7 @@ def random_private_ip(cidr: str = None, ipv6: bool = False) -> str:
if ipv6: if ipv6:
ula = ipaddress.IPv6Network(cidr) ula = ipaddress.IPv6Network(cidr)
return str(ula.network_address + (random.getrandbits(128 - ula.prefixlen))) return str(ula.network_address + (random.getrandbits(128 - ula.prefixlen)))
ula = ipaddress.IPv4Network(cidr) ula = ipaddress.IPv4Network(cidr) # type: ignore[assignment]
return str(ula.network_address + (random.getrandbits(32 - ula.prefixlen))) return str(ula.network_address + (random.getrandbits(32 - ula.prefixlen)))
if ipv6: if ipv6:
return f"2001::cafe:{random.getrandbits(16)}x/64" return f"2001::cafe:{random.getrandbits(16)}x/64"
@ -285,7 +285,7 @@ def generate_route_id(
cidr_block: Optional[str], cidr_block: Optional[str],
ipv6_cidr_block: Optional[str] = None, ipv6_cidr_block: Optional[str] = None,
prefix_list: Optional[str] = None, prefix_list: Optional[str] = None,
): ) -> str:
if ipv6_cidr_block and not cidr_block: if ipv6_cidr_block and not cidr_block:
cidr_block = ipv6_cidr_block cidr_block = ipv6_cidr_block
if prefix_list and not cidr_block: if prefix_list and not cidr_block:
@ -315,7 +315,9 @@ def split_route_id(route_id: str) -> Tuple[str, str]:
return values[0], values[1] return values[0], values[1]
def get_attribute_value(parameter, querystring_dict): def get_attribute_value(
parameter: str, querystring_dict: Dict[str, List[str]]
) -> Union[None, bool, str]:
for key, value in querystring_dict.items(): for key, value in querystring_dict.items():
match = re.search(rf"{parameter}.Value", key) match = re.search(rf"{parameter}.Value", key)
if match: if match:
@ -325,7 +327,7 @@ def get_attribute_value(parameter, querystring_dict):
return None return None
def get_object_value(obj, attr): def get_object_value(obj: Any, attr: str) -> Any:
keys = attr.split(".") keys = attr.split(".")
val = obj val = obj
for key in keys: for key in keys:
@ -353,25 +355,25 @@ def is_tag_filter(filter_name: str) -> bool:
) )
def get_obj_tag(obj, filter_name): def get_obj_tag(obj: Any, filter_name: str) -> Optional[str]:
tag_name = filter_name.replace("tag:", "", 1) tag_name = filter_name.replace("tag:", "", 1)
tags = dict((tag["key"], tag["value"]) for tag in obj.get_tags()) tags = dict((tag["key"], tag["value"]) for tag in obj.get_tags())
return tags.get(tag_name) return tags.get(tag_name)
def get_obj_tag_names(obj): def get_obj_tag_names(obj: Any) -> Set[str]:
tags = set((tag["key"] for tag in obj.get_tags())) tags = set((tag["key"] for tag in obj.get_tags()))
return tags return tags
def get_obj_tag_values(obj, key=None): def get_obj_tag_values(obj: Any, key: Optional[str] = None) -> Set[str]:
tags = set( tags = set(
(tag["value"] for tag in obj.get_tags() if tag["key"] == key or key is None) (tag["value"] for tag in obj.get_tags() if tag["key"] == key or key is None)
) )
return tags return tags
def add_tag_specification(tags): def add_tag_specification(tags: Any) -> Dict[str, str]:
tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags tags = tags[0] if isinstance(tags, list) and len(tags) == 1 else tags
tags = (tags or {}).get("Tag", []) tags = (tags or {}).get("Tag", [])
tags = {t["Key"]: t["Value"] for t in tags} tags = {t["Key"]: t["Value"] for t in tags}
@ -388,7 +390,7 @@ def tag_filter_matches(obj: Any, filter_name: str, filter_values: List[str]) ->
key = filter_name[4:] key = filter_name[4:]
tag_values = get_obj_tag_values(obj, key=key) tag_values = get_obj_tag_values(obj, key=key)
else: else:
tag_values = [get_obj_tag(obj, filter_name) or ""] tag_values = [get_obj_tag(obj, filter_name) or ""] # type: ignore[assignment]
for tag_value in tag_values: for tag_value in tag_values:
if any(regex.match(tag_value) for regex in regex_filters): if any(regex.match(tag_value) for regex in regex_filters):
@ -421,7 +423,7 @@ filter_dict_attribute_mapping = {
} }
def passes_filter_dict(instance, filter_dict): def passes_filter_dict(instance: Any, filter_dict: Dict[str, Any]) -> bool:
for filter_name, filter_values in filter_dict.items(): for filter_name, filter_values in filter_dict.items():
if filter_name in filter_dict_attribute_mapping: if filter_name in filter_dict_attribute_mapping:
instance_attr = filter_dict_attribute_mapping[filter_name] instance_attr = filter_dict_attribute_mapping[filter_name]
@ -440,7 +442,7 @@ def passes_filter_dict(instance, filter_dict):
return True return True
def instance_value_in_filter_values(instance_value, filter_values): def instance_value_in_filter_values(instance_value: Any, filter_values: Any) -> bool:
if isinstance(instance_value, list): if isinstance(instance_value, list):
if not set(filter_values).intersection(set(instance_value)): if not set(filter_values).intersection(set(instance_value)):
return False return False
@ -458,11 +460,11 @@ def filter_reservations(
result = [] result = []
for reservation in reservations: for reservation in reservations:
new_instances = [] new_instances = []
for instance in reservation.instances: for instance in reservation.instances: # type: ignore[attr-defined]
if passes_filter_dict(instance, filter_dict): if passes_filter_dict(instance, filter_dict):
new_instances.append(instance) new_instances.append(instance)
if new_instances: if new_instances:
reservation.instances = new_instances reservation.instances = new_instances # type: ignore[attr-defined]
result.append(reservation) result.append(reservation)
return result return result
@ -474,7 +476,7 @@ filter_dict_igw_mapping = {
} }
def passes_igw_filter_dict(igw, filter_dict): def passes_igw_filter_dict(igw: Any, filter_dict: Dict[str, Any]) -> bool:
for filter_name, filter_values in filter_dict.items(): for filter_name, filter_values in filter_dict.items():
if filter_name in filter_dict_igw_mapping: if filter_name in filter_dict_igw_mapping:
igw_attr = filter_dict_igw_mapping[filter_name] igw_attr = filter_dict_igw_mapping[filter_name]
@ -501,7 +503,7 @@ def filter_internet_gateways(
return result return result
def is_filter_matching(obj, _filter, filter_value): def is_filter_matching(obj: Any, _filter: str, filter_value: Any) -> bool:
value = obj.get_filter_value(_filter) value = obj.get_filter_value(_filter)
if filter_value is None: if filter_value is None:
@ -583,7 +585,7 @@ def get_prefix(resource_id: str) -> str:
resource_id_prefix = EC2_RESOURCE_TO_PREFIX["reserved-instance"] resource_id_prefix = EC2_RESOURCE_TO_PREFIX["reserved-instance"]
else: else:
# We should probably raise an error here, to make it more obvious this is not yet supported # We should probably raise an error here, to make it more obvious this is not yet supported
return None return None # type: ignore[return-value]
return resource_id_prefix return resource_id_prefix
@ -609,7 +611,7 @@ def is_valid_ipv6_cidr(cird: str) -> bool:
return cidr_pattern_re.match(cird) is not None return cidr_pattern_re.match(cird) is not None
def generate_instance_identity_document(instance): def generate_instance_identity_document(instance: Any) -> Dict[str, Any]:
""" """
http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instance-identity-documents.html
@ -681,12 +683,12 @@ def filter_iam_instance_profile_associations(
filter_passed = True filter_passed = True
if filter_dict.get("instance-id"): if filter_dict.get("instance-id"):
if ( if (
iam_instance_association.instance.id iam_instance_association.instance.id # type: ignore[attr-defined]
not in filter_dict.get("instance-id").values() not in filter_dict.get("instance-id").values()
): ):
filter_passed = False filter_passed = False
if filter_dict.get("state"): if filter_dict.get("state"):
if iam_instance_association.state not in filter_dict.get("state").values(): if iam_instance_association.state not in filter_dict.get("state").values(): # type: ignore[attr-defined]
filter_passed = False filter_passed = False
if filter_passed: if filter_passed:
result.append(iam_instance_association) result.append(iam_instance_association)
@ -732,7 +734,7 @@ def describe_tag_filter(
if match: if match:
tag_key_name = match.group(1) tag_key_name = match.group(1)
need_delete = True need_delete = True
for tag in instance.get_tags(): for tag in instance.get_tags(): # type: ignore[attr-defined]
if tag.get("key") == tag_key_name and tag.get( if tag.get("key") == tag_key_name and tag.get(
"value" "value"
) in filters.get(key): ) in filters.get(key):
@ -746,7 +748,9 @@ def describe_tag_filter(
return result return result
def gen_moto_amis(described_images, drop_images_missing_keys=True): def gen_moto_amis(
described_images: List[Dict[str, Any]], drop_images_missing_keys: bool = True
) -> List[Dict[str, Any]]:
"""Convert `boto3.EC2.Client.describe_images` output to form acceptable to `MOTO_AMIS_PATH` """Convert `boto3.EC2.Client.describe_images` output to form acceptable to `MOTO_AMIS_PATH`
Parameters Parameters
@ -804,7 +808,7 @@ def convert_tag_spec(
# IN: [{"ResourceType": _type, "Tag": [{"Key": k, "Value": v}, ..]}] # IN: [{"ResourceType": _type, "Tag": [{"Key": k, "Value": v}, ..]}]
# (or) [{"ResourceType": _type, "Tags": [{"Key": k, "Value": v}, ..]}] <-- special cfn case # (or) [{"ResourceType": _type, "Tags": [{"Key": k, "Value": v}, ..]}] <-- special cfn case
# OUT: {_type: {k: v, ..}} # OUT: {_type: {k: v, ..}}
tags = {} tags: Dict[str, Dict[str, str]] = {}
for tag_spec in tag_spec_set: for tag_spec in tag_spec_set:
if tag_spec["ResourceType"] not in tags: if tag_spec["ResourceType"] not in tags:
tags[tag_spec["ResourceType"]] = {} tags[tag_spec["ResourceType"]] = {}

View File

@ -3,14 +3,15 @@ import hashlib
import pkgutil import pkgutil
from collections.abc import MutableMapping from collections.abc import MutableMapping
from typing import Any, Dict, List, TypeVar, Tuple from typing import Any, Dict, List, TypeVar, Tuple, Optional
def str2bool(v): def str2bool(v: Any) -> Optional[bool]:
if v in ("yes", True, "true", "True", "TRUE", "t", "1"): if v in ("yes", True, "true", "True", "TRUE", "t", "1"):
return True return True
elif v in ("no", False, "false", "False", "FALSE", "f", "0"): elif v in ("no", False, "false", "False", "FALSE", "f", "0"):
return False return False
return None
def load_resource(package: str, resource: str) -> Dict[str, Any]: def load_resource(package: str, resource: str) -> Dict[str, Any]:

View File

@ -229,7 +229,7 @@ disable = W,C,R,E
enable = anomalous-backslash-in-string, arguments-renamed, dangerous-default-value, deprecated-module, function-redefined, import-self, redefined-builtin, redefined-outer-name, reimported, pointless-statement, super-with-arguments, unused-argument, unused-import, unused-variable, useless-else-on-loop, wildcard-import enable = anomalous-backslash-in-string, arguments-renamed, dangerous-default-value, deprecated-module, function-redefined, import-self, redefined-builtin, redefined-outer-name, reimported, pointless-statement, super-with-arguments, unused-argument, unused-import, unused-variable, useless-else-on-loop, wildcard-import
[mypy] [mypy]
files= moto/a*,moto/b*,moto/c*,moto/d*,moto/ebs/,moto/ec2/models/**/*.py,moto/moto_api files= moto/a*,moto/b*,moto/c*,moto/d*,moto/ebs/,moto/ec2/,moto/moto_api
show_column_numbers=True show_column_numbers=True
show_error_codes = True show_error_codes = True
disable_error_code=abstract disable_error_code=abstract

View File

@ -32,7 +32,7 @@ def test_create_with_tags():
MaxEntries=2, MaxEntries=2,
AddressFamily="?", AddressFamily="?",
TagSpecifications=[ TagSpecifications=[
{"ResourceType": "", "Tags": [{"Key": "key1", "Value": "val1"}]} {"ResourceType": "prefix-list", "Tags": [{"Key": "key1", "Value": "val1"}]}
], ],
)["PrefixList"] )["PrefixList"]
prefix_list.should.have.key("PrefixListId").match("pl-[a-z0-9]+") prefix_list.should.have.key("PrefixListId").match("pl-[a-z0-9]+")