From 33d374526303f9b3b686402a2074963dd027fa65 Mon Sep 17 00:00:00 2001 From: Bert Blommers Date: Fri, 22 Mar 2024 07:38:57 -0100 Subject: [PATCH] EC2: Add additional VPC Endpoint Services (#7509) --- moto/acm/models.py | 9 - moto/applicationautoscaling/models.py | 9 - moto/athena/models.py | 9 - moto/autoscaling/models.py | 11 - moto/awslambda/models.py | 9 - moto/cloudwatch/models.py | 9 - moto/codecommit/models.py | 9 - moto/config/models.py | 9 - moto/datasync/models.py | 9 - moto/dms/models.py | 9 - moto/ds/models.py | 9 - moto/ec2/models/__init__.py | 11 - moto/ec2/models/vpcs.py | 309 ++++++++++++++++-- moto/ecs/models.py | 9 - moto/elasticbeanstalk/models.py | 11 - moto/elbv2/models.py | 9 - moto/emr/models.py | 9 - moto/events/models.py | 9 - moto/glue/models.py | 9 - moto/kms/models.py | 9 - moto/logs/models.py | 9 - moto/rds/models.py | 11 - moto/redshift/models.py | 11 - moto/redshiftdata/models.py | 9 + moto/secretsmanager/models.py | 9 - moto/sns/models.py | 9 - moto/sqs/models.py | 9 - moto/ssm/models.py | 11 - moto/sts/models.py | 9 - moto/transcribe/models.py | 11 - moto/xray/models.py | 9 - .../test_ec2_vpc_endpoint_services.py | 10 + 32 files changed, 297 insertions(+), 306 deletions(-) diff --git a/moto/acm/models.py b/moto/acm/models.py index 585d99530..1889ff36c 100644 --- a/moto/acm/models.py +++ b/moto/acm/models.py @@ -409,15 +409,6 @@ class AWSCertificateManagerBackend(BaseBackend): self._certificates: Dict[str, CertBundle] = {} self._idempotency_tokens: Dict[str, Any] = {} - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "acm-pca" - ) - def set_certificate_in_use_by(self, arn: str, load_balancer_name: str) -> None: if arn not in self._certificates: raise CertificateNotFound(arn=arn, account_id=self.account_id) diff --git a/moto/applicationautoscaling/models.py b/moto/applicationautoscaling/models.py index 50ce4c58f..41e7f2dda 100644 --- a/moto/applicationautoscaling/models.py +++ b/moto/applicationautoscaling/models.py @@ -73,15 +73,6 @@ class ApplicationAutoscalingBackend(BaseBackend): self.policies: Dict[str, FakeApplicationAutoscalingPolicy] = {} self.scheduled_actions: List[FakeScheduledAction] = list() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "application-autoscaling" - ) - def describe_scalable_targets( self, namespace: str, r_ids: Union[None, List[str]], dimension: Union[None, str] ) -> List["FakeScalableTarget"]: diff --git a/moto/athena/models.py b/moto/athena/models.py index 38d4449db..327405c4f 100644 --- a/moto/athena/models.py +++ b/moto/athena/models.py @@ -173,15 +173,6 @@ class AthenaBackend(BaseBackend): name="primary", description="", configuration=dict(), tags=[] ) - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "athena" - ) - def create_work_group( self, name: str, diff --git a/moto/autoscaling/models.py b/moto/autoscaling/models.py index 5d03c85bf..5f22a7727 100644 --- a/moto/autoscaling/models.py +++ b/moto/autoscaling/models.py @@ -882,17 +882,6 @@ class AutoScalingBackend(BaseBackend): self.elb_backend: ELBBackend = elb_backends[self.account_id][region_name] self.elbv2_backend: ELBv2Backend = elbv2_backends[self.account_id][region_name] - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, Any]]: # type: ignore[misc] - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "autoscaling" - ) + BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "autoscaling-plans" - ) - def create_launch_configuration( self, name: str, diff --git a/moto/awslambda/models.py b/moto/awslambda/models.py index bba211abc..37e9c4c1f 100644 --- a/moto/awslambda/models.py +++ b/moto/awslambda/models.py @@ -1893,15 +1893,6 @@ class LambdaBackend(BaseBackend): self._event_source_mappings: Dict[str, EventSourceMapping] = {} self._layers = LayerStorage() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "lambda" - ) - def create_alias( self, name: str, diff --git a/moto/cloudwatch/models.py b/moto/cloudwatch/models.py index 9a8da6fa8..60a5dd03f 100644 --- a/moto/cloudwatch/models.py +++ b/moto/cloudwatch/models.py @@ -442,15 +442,6 @@ class CloudWatchBackend(BaseBackend): self.paged_metric_data: Dict[str, List[MetricDatumBase]] = {} self.tagger = TaggingService() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "monitoring" - ) - @property # Retrieve a list of all OOTB metrics that are provided by metrics providers # Computed on the fly diff --git a/moto/codecommit/models.py b/moto/codecommit/models.py index 3f87569ef..49eb5391e 100644 --- a/moto/codecommit/models.py +++ b/moto/codecommit/models.py @@ -40,15 +40,6 @@ class CodeCommitBackend(BaseBackend): super().__init__(region_name, account_id) self.repositories: Dict[str, CodeCommit] = {} - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "codecommit" - ) - def create_repository( self, repository_name: str, repository_description: str ) -> Dict[str, str]: diff --git a/moto/config/models.py b/moto/config/models.py index aaea0dc4e..171e6d4fc 100644 --- a/moto/config/models.py +++ b/moto/config/models.py @@ -917,15 +917,6 @@ class ConfigBackend(BaseBackend): self.config_schema: Optional[AWSServiceSpec] = None self.retention_configuration: Optional[RetentionConfiguration] = None - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, Any]]: # type: ignore[misc] - """List of dicts representing default VPC endpoints for this service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "config" - ) - def _validate_resource_types(self, resource_list: List[str]) -> None: if not self.config_schema: self.config_schema = AWSServiceSpec( diff --git a/moto/datasync/models.py b/moto/datasync/models.py index a5d0437a8..3834c65a7 100644 --- a/moto/datasync/models.py +++ b/moto/datasync/models.py @@ -103,15 +103,6 @@ class DataSyncBackend(BaseBackend): self.tasks: Dict[str, Task] = OrderedDict() self.task_executions: Dict[str, TaskExecution] = OrderedDict() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, Any]]: # type: ignore[misc] - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "datasync" - ) - def create_location( self, location_uri: str, typ: str, metadata: Dict[str, Any] ) -> str: diff --git a/moto/dms/models.py b/moto/dms/models.py index 82d8965b0..13d31adfe 100644 --- a/moto/dms/models.py +++ b/moto/dms/models.py @@ -18,15 +18,6 @@ class DatabaseMigrationServiceBackend(BaseBackend): super().__init__(region_name, account_id) self.replication_tasks: Dict[str, "FakeReplicationTask"] = {} - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, Any]]: # type: ignore[misc] - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "dms" - ) - def create_replication_task( self, replication_task_identifier: str, diff --git a/moto/ds/models.py b/moto/ds/models.py index 0dd46d45c..ec1945e38 100644 --- a/moto/ds/models.py +++ b/moto/ds/models.py @@ -200,15 +200,6 @@ class DirectoryServiceBackend(BaseBackend): self.directories: Dict[str, Directory] = {} self.tagger = TaggingService() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """List of dicts representing default VPC endpoints for this service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "ds" - ) - def _verify_subnets(self, region: str, vpc_settings: Dict[str, Any]) -> None: """Verify subnets are valid, else raise an exception. diff --git a/moto/ec2/models/__init__.py b/moto/ec2/models/__init__.py index d474f9050..9f96a95e9 100644 --- a/moto/ec2/models/__init__.py +++ b/moto/ec2/models/__init__.py @@ -163,17 +163,6 @@ class EC2Backend( self.create_subnet(vpc.id, cidr_block, availability_zone=az_name) ip[2] += 16 # type: ignore - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, Any]]: # type: ignore[misc] - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "ec2" - ) + BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "ec2messages" - ) - # Use this to generate a proper error template response when in a response # handler. def raise_error(self, code: str, message: str) -> None: diff --git a/moto/ec2/models/vpcs.py b/moto/ec2/models/vpcs.py index d20b5490b..d4d856614 100644 --- a/moto/ec2/models/vpcs.py +++ b/moto/ec2/models/vpcs.py @@ -6,6 +6,7 @@ from collections import defaultdict from operator import itemgetter from typing import Any, Dict, List, Optional +from moto.core.base_backend import BaseBackend from moto.core.common_models import CloudFormationModel from ..exceptions import ( @@ -37,52 +38,290 @@ from ..utils import ( from .availability_zones_and_regions import RegionsAndZonesBackend from .core import TaggedEC2Resource -# We used to load the entirety of Moto into memory, and check every module if it's supported -# But having a fixed list is much more performant -# Maintaining it is more difficult, but the contents of this list does not change very often +# List of Moto services that exposes a non-standard EndpointService config IMPLEMENTED_ENDPOINT_SERVICES = [ - "acm", - "applicationautoscaling", - "athena", - "autoscaling", - "awslambda", "cloudformation", - "cloudwatch", - "codecommit", "codepipeline", - "config", - "datasync", - "dms", - "ds", "dynamodb", - "ec2", "ecr", - "ecs", - "elasticbeanstalk", - "elbv2", - "emr", - "events", "firehose", - "glue", "iot", "kinesis", - "kms", - "logs", - "rds", - "redshift", + "redshiftdata", "route53resolver", "s3", "sagemaker", +] +# List of names used by AWS that are implemented by our services +COVERED_ENDPOINT_SERVICES = IMPLEMENTED_ENDPOINT_SERVICES + [ + "ecr.api", + "ecr.dkr", + "iot.data", + "kinesis-firehose", + "kinesis-streams", + "redshift-data", + "sagemaker.api", +] +# All endpoints offered by AWS +# We expose a sensible default for these services, if we don't implement a service-specific non-standard +AWS_ENDPOINT_SERVICES = [ + "access-analyzer", + "account", + "acm-pca", + "airflow.api", + "airflow.env", + "airflow.ops", + "analytics-omics", + "app-integrations", + "appconfig", + "appconfigdata", + "application-autoscaling", + "appmesh", + "appmesh-envoy-management", + "apprunner", + "apprunner.requests", + "appstream.api", + "appstream.streaming", + "appsync-api", + "aps", + "aps-workspaces", + "athena", + "auditmanager", + "autoscaling", + "autoscaling-plans", + "awsconnector", + "b2bi", + "backup", + "backup-gateway", + "batch", + "bedrock", + "bedrock-agent", + "bedrock-agent-runtime", + "bedrock-runtime", + "billingconductor", + "braket", + "cases", + "cassandra", + "cassandra-fips", + "cleanrooms", + "cloudcontrolapi", + "cloudcontrolapi-fips", + "clouddirectory", + "cloudformation", + "cloudhsmv2", + "cloudtrail", + "codeartifact.api", + "codeartifact.repositories", + "codebuild", + "codebuild-fips", + "codecommit", + "codecommit-fips", + "codedeploy", + "codedeploy-commands-secure", + "codeguru-profiler", + "codeguru-reviewer", + "codepipeline", + "codestar-connections.api", + "codewhisperer", + "comprehend", + "comprehendmedical", + "config", + "connect-campaigns", + "console", + "control-storage-omics", + "data-servicediscovery", + "data-servicediscovery-fips", + "databrew", + "dataexchange", + "datasync", + "datazone", + "deviceadvisor.iot", + "devops-guru", + "dms", + "dms-fips", + "drs", + "ds", + "dynamodb", + "ebs", + "ec2", + "ec2messages", + "ecr.api", + "ecr.dkr", + "ecs", + "ecs-agent", + "ecs-telemetry", + "eks", + "eks-auth", + "elastic-inference.runtime", + "elasticache", + "elasticache-fips", + "elasticbeanstalk", + "elasticbeanstalk-health", + "elasticfilesystem", + "elasticfilesystem-fips", + "elasticloadbalancing", + "elasticmapreduce", + "email-smtp", + "emr-containers", + "emr-serverless", + "emrwal.prod", + "entityresolution", + "events", + "evidently", + "evidently-dataplane", + "execute-api", + "finspace", + "finspace-api", + "fis", + "forecast", + "forecast-fips", + "forecastquery", + "forecastquery-fips", + "frauddetector", + "fsx", + "fsx-fips", + "git-codecommit", + "git-codecommit-fips", + "glue", + "grafana", + "grafana-workspace", + "greengrass", + "groundstation", + "guardduty-data", + "guardduty-data-fips", + "healthlake", + "identitystore", + "imagebuilder", + "inspector2", + "iot.credentials", + "iot.data", + "iot.fleethub.api", + "iotfleetwise", + "iotroborunner", + "iotsitewise.api", + "iotsitewise.data", + "iottwinmaker.api", + "iottwinmaker.data", + "iotwireless.api", + "kendra", + "kinesis-firehose", + "kinesis-streams", + "kms", + "kms-fips", + "lakeformation", + "lambda", + "license-manager", + "license-manager-fips", + "license-manager-user-subscriptions", + "logs", + "lookoutequipment", + "lookoutmetrics", + "lookoutvision", + "lorawan.cups", + "lorawan.lns", + "m2", + "macie2", + "managedblockchain-query", + "managedblockchain.bitcoin.mainnet", + "managedblockchain.bitcoin.testnet", + "mediaconnect", + "medical-imaging", + "memory-db", + "memorydb-fips", + "mgn", + "migrationhub-orchestrator", + "models-v2-lex", + "monitoring", + "neptune-graph", + "networkmonitor", + "nimble", + "organizations", + "organizations-fips", + "panorama", + "payment-cryptography.controlplane", + "payment-cryptography.dataplane", + "pca-connector-ad", + "personalize", + "personalize-events", + "personalize-runtime", + "pinpoint", + "pinpoint-sms-voice-v2", + "polly", + "private-networks", + "profile", + "proton", + "qldb.session", + "rds", + "rds-data", + "redshift", + "redshift-data", + "redshift-fips", + "refactor-spaces", + "rekognition", + "rekognition-fips", + "robomaker", + "rolesanywhere", + "rum", + "rum-dataplane", + "runtime-medical-imaging", + "runtime-v2-lex", + "s3", + "s3", + "s3-outposts", + "s3express", + "sagemaker.api", + "sagemaker.featurestore-runtime", + "sagemaker.metrics", + "sagemaker.runtime", + "sagemaker.runtime-fips", + "scn", "secretsmanager", + "securityhub", + "servicecatalog", + "servicecatalog-appregistry", + "servicediscovery", + "servicediscovery-fips", + "signin", + "simspaceweaver", + "snow-device-management", "sns", "sqs", "ssm", + "ssm-contacts", + "ssm-incidents", + "ssmmessages", + "states", + "storage-omics", + "storagegateway", + "streaming-rekognition", + "streaming-rekognition-fips", "sts", + "swf", + "swf-fips", + "sync-states", + "synthetics", + "tags-omics", + "textract", + "textract-fips", + "thinclient.api", + "timestream-influxdb", + "tnb", "transcribe", + "transcribestreaming", + "transfer", + "transfer.server", + "translate", + "trustedadvisor", + "verifiedpermissions", + "voiceid", + "vpc-lattice", + "wisdom", + "workflows-omics", + "workspaces", "xray", ] MAX_NUMBER_OF_ENDPOINT_SERVICES_RESULTS = 1000 -DEFAULT_VPC_ENDPOINT_SERVICES: List[Dict[str, str]] = [] +DEFAULT_VPC_ENDPOINT_SERVICES: Dict[str, List[Dict[str, str]]] = {} ENDPOINT_SERVICE_COLLECTION_LOCK = threading.Lock() @@ -772,9 +1011,10 @@ class VPCBackend: ) -> List[Dict[str, str]]: """Return list of default services using list of backends.""" with ENDPOINT_SERVICE_COLLECTION_LOCK: - if DEFAULT_VPC_ENDPOINT_SERVICES: - return DEFAULT_VPC_ENDPOINT_SERVICES + if region in DEFAULT_VPC_ENDPOINT_SERVICES: + return DEFAULT_VPC_ENDPOINT_SERVICES[region] + DEFAULT_VPC_ENDPOINT_SERVICES[region] = [] zones = [ zone.name for zones in RegionsAndZonesBackend.zones.values() @@ -792,15 +1032,22 @@ class VPCBackend: region, zones ) if service: - DEFAULT_VPC_ENDPOINT_SERVICES.extend(service) + DEFAULT_VPC_ENDPOINT_SERVICES[region].extend(service) if "global" in account_backend: service = account_backend["global"].default_vpc_endpoint_service( region, zones ) if service: - DEFAULT_VPC_ENDPOINT_SERVICES.extend(service) - return DEFAULT_VPC_ENDPOINT_SERVICES + DEFAULT_VPC_ENDPOINT_SERVICES[region].extend(service) + + # Return sensible defaults, for services that do not offer a custom implementation + for aws_service in AWS_ENDPOINT_SERVICES: + if aws_service not in COVERED_ENDPOINT_SERVICES: + service_configs = BaseBackend.default_vpc_endpoint_service_factory(region, zones, aws_service) + DEFAULT_VPC_ENDPOINT_SERVICES[region].extend(service_configs) + + return DEFAULT_VPC_ENDPOINT_SERVICES[region] @staticmethod def _matches_service_by_tags( diff --git a/moto/ecs/models.py b/moto/ecs/models.py index 3e06e3c82..a48f390dd 100644 --- a/moto/ecs/models.py +++ b/moto/ecs/models.py @@ -962,15 +962,6 @@ class EC2ContainerServiceBackend(BaseBackend): self.services: Dict[str, Service] = {} self.container_instances: Dict[str, Dict[str, ContainerInstance]] = {} - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, Any]]: # type: ignore[misc] - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "ecs" - ) - def _get_cluster(self, name: str) -> Cluster: # short name or full ARN of the cluster cluster_name = name.split("/")[-1] diff --git a/moto/elasticbeanstalk/models.py b/moto/elasticbeanstalk/models.py index e2a92f105..13fcb2cde 100644 --- a/moto/elasticbeanstalk/models.py +++ b/moto/elasticbeanstalk/models.py @@ -84,17 +84,6 @@ class EBBackend(BaseBackend): super().__init__(region_name, account_id) self.applications: Dict[str, FakeApplication] = dict() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "elasticbeanstalk" - ) + BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "elasticbeanstalk-health" - ) - def create_application(self, application_name: str) -> FakeApplication: if application_name in self.applications: raise InvalidParameterValueError( diff --git a/moto/elbv2/models.py b/moto/elbv2/models.py index 4a52abddd..011b5592a 100644 --- a/moto/elbv2/models.py +++ b/moto/elbv2/models.py @@ -722,15 +722,6 @@ class ELBv2Backend(BaseBackend): self.load_balancers: Dict[str, FakeLoadBalancer] = OrderedDict() self.tagging_service = TaggingService() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "elasticloadbalancing" - ) - @property def ec2_backend(self) -> Any: # type: ignore[misc] """ diff --git a/moto/emr/models.py b/moto/emr/models.py index cc7beb3aa..536a26d0d 100644 --- a/moto/emr/models.py +++ b/moto/emr/models.py @@ -556,15 +556,6 @@ class ElasticMapReduceBackend(BaseBackend): self.instance_groups: Dict[str, FakeInstanceGroup] = {} self.security_configurations: Dict[str, FakeSecurityConfiguration] = {} - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "elasticmapreduce" - ) - @property def ec2_backend(self) -> Any: # type: ignore[misc] """ diff --git a/moto/events/models.py b/moto/events/models.py index 10f0904e0..251a06353 100644 --- a/moto/events/models.py +++ b/moto/events/models.py @@ -1026,15 +1026,6 @@ class EventsBackend(BaseBackend): self.partner_event_sources: Dict[str, PartnerEventSource] = {} self.approved_parent_event_bus_names: List[str] = [] - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "events" - ) - def _add_default_event_bus(self) -> None: self.event_buses["default"] = EventBus( self.account_id, self.region_name, "default" diff --git a/moto/glue/models.py b/moto/glue/models.py index 74155237b..e6780dbbc 100644 --- a/moto/glue/models.py +++ b/moto/glue/models.py @@ -113,15 +113,6 @@ class GlueBackend(BaseBackend): self.num_schemas = 0 self.num_schema_versions = 0 - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "glue" - ) - def create_database( self, database_name: str, diff --git a/moto/kms/models.py b/moto/kms/models.py index d12d9834a..8f8c50f32 100644 --- a/moto/kms/models.py +++ b/moto/kms/models.py @@ -260,15 +260,6 @@ class KmsBackend(BaseBackend): self.key_to_aliases: Dict[str, Set[str]] = defaultdict(set) self.tagger = TaggingService(key_name="TagKey", value_name="TagValue") - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "kms" - ) - def _generate_default_keys(self, alias_name: str) -> Optional[str]: """Creates default kms keys""" if alias_name in RESERVED_ALIASES: diff --git a/moto/logs/models.py b/moto/logs/models.py index b2057d18a..6a07de367 100644 --- a/moto/logs/models.py +++ b/moto/logs/models.py @@ -766,15 +766,6 @@ class LogsBackend(BaseBackend): self.tagger = TaggingService() self.export_tasks: Dict[str, ExportTask] = dict() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "logs" - ) - def create_log_group( self, log_group_name: str, tags: Dict[str, str], **kwargs: Any ) -> LogGroup: diff --git a/moto/rds/models.py b/moto/rds/models.py index 8125b544d..bf151de9b 100644 --- a/moto/rds/models.py +++ b/moto/rds/models.py @@ -1736,17 +1736,6 @@ class RDSBackend(BaseBackend): ] return self._db_cluster_options - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "rds" - ) + BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "rds-data" - ) - def create_db_instance(self, db_kwargs: Dict[str, Any]) -> Database: database_id = db_kwargs["db_instance_identifier"] self._validate_db_identifier(database_id) diff --git a/moto/redshift/models.py b/moto/redshift/models.py index 5f66e77cc..a885b1145 100644 --- a/moto/redshift/models.py +++ b/moto/redshift/models.py @@ -595,17 +595,6 @@ class RedshiftBackend(BaseBackend): } self.snapshot_copy_grants: Dict[str, SnapshotCopyGrant] = {} - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "redshift" - ) + BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "redshift-data", policy_supported=False - ) - def enable_snapshot_copy(self, **kwargs: Any) -> Cluster: cluster_identifier = kwargs["cluster_identifier"] cluster = self.clusters[cluster_identifier] diff --git a/moto/redshiftdata/models.py b/moto/redshiftdata/models.py index 61e689d0f..b5a64dad2 100644 --- a/moto/redshiftdata/models.py +++ b/moto/redshiftdata/models.py @@ -117,6 +117,15 @@ class RedshiftDataAPIServiceBackend(BaseBackend): super().__init__(region_name, account_id) self.statements: Dict[str, Statement] = {} + @staticmethod + def default_vpc_endpoint_service( + service_region: str, zones: List[str] + ) -> List[Dict[str, str]]: + """Default VPC endpoint service.""" + return BaseBackend.default_vpc_endpoint_service_factory( + service_region, zones, "redshift-data", policy_supported=False + ) + def cancel_statement(self, statement_id: str) -> None: _validate_uuid(statement_id) diff --git a/moto/secretsmanager/models.py b/moto/secretsmanager/models.py index e1be5a0c8..95f1c1b65 100644 --- a/moto/secretsmanager/models.py +++ b/moto/secretsmanager/models.py @@ -361,15 +361,6 @@ class SecretsManagerBackend(BaseBackend): super().__init__(region_name, account_id) self.secrets = SecretsStore() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint services.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "secretsmanager" - ) - def _is_valid_identifier(self, identifier: str) -> bool: return identifier in self.secrets diff --git a/moto/sns/models.py b/moto/sns/models.py index 481599150..d1539a21a 100644 --- a/moto/sns/models.py +++ b/moto/sns/models.py @@ -409,15 +409,6 @@ class SNSBackend(BaseBackend): "+447700900907", ] - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """List of dicts representing default VPC endpoints for this service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "sns" - ) - def get_sms_attributes(self, filter_list: Set[str]) -> Dict[str, str]: if len(filter_list) > 0: return {k: v for k, v in self.sms_attributes.items() if k in filter_list} diff --git a/moto/sqs/models.py b/moto/sqs/models.py index 66860fe49..3b6f3efb6 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -679,15 +679,6 @@ class SQSBackend(BaseBackend): super().__init__(region_name, account_id) self.queues: Dict[str, Queue] = {} - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "sqs" - ) - def create_queue( self, name: str, tags: Optional[Dict[str, str]] = None, **kwargs: Any ) -> Queue: diff --git a/moto/ssm/models.py b/moto/ssm/models.py index 7395cbff3..be084dc6a 100644 --- a/moto/ssm/models.py +++ b/moto/ssm/models.py @@ -1188,17 +1188,6 @@ class SimpleSystemManagerBackend(BaseBackend): self.windows: Dict[str, FakeMaintenanceWindow] = dict() self.baselines: Dict[str, FakePatchBaseline] = dict() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint services.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "ssm" - ) + BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "ssmmessages" - ) - def _generate_document_information( self, ssm_document: Document, document_format: str ) -> Dict[str, Any]: diff --git a/moto/sts/models.py b/moto/sts/models.py index 4a237551a..1ff40ae00 100644 --- a/moto/sts/models.py +++ b/moto/sts/models.py @@ -81,15 +81,6 @@ class STSBackend(BaseBackend): super().__init__(region_name, account_id) self.assumed_roles: List[AssumedRole] = [] - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "sts" - ) - def get_session_token(self, duration: int) -> Token: return Token(duration=duration) diff --git a/moto/transcribe/models.py b/moto/transcribe/models.py index fb81d894f..d4e1c2e68 100644 --- a/moto/transcribe/models.py +++ b/moto/transcribe/models.py @@ -480,17 +480,6 @@ class TranscribeBackend(BaseBackend): self.medical_vocabularies: Dict[str, FakeMedicalVocabulary] = {} self.vocabularies: Dict[str, FakeVocabulary] = {} - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint services.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "transcribe" - ) + BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "transcribestreaming" - ) - def start_transcription_job( self, transcription_job_name: str, diff --git a/moto/xray/models.py b/moto/xray/models.py index 46a5f7c07..f0f49cfdb 100644 --- a/moto/xray/models.py +++ b/moto/xray/models.py @@ -250,15 +250,6 @@ class XRayBackend(BaseBackend): self._telemetry_records: List[TelemetryRecords] = [] self._segment_collection = SegmentCollection() - @staticmethod - def default_vpc_endpoint_service( - service_region: str, zones: List[str] - ) -> List[Dict[str, str]]: - """Default VPC endpoint service.""" - return BaseBackend.default_vpc_endpoint_service_factory( - service_region, zones, "xray" - ) - def add_telemetry_records(self, src: Any) -> None: self._telemetry_records.append(TelemetryRecords.from_json(src)) diff --git a/tests/test_core/test_ec2_vpc_endpoint_services.py b/tests/test_core/test_ec2_vpc_endpoint_services.py index 00936092e..58ad37bd5 100644 --- a/tests/test_core/test_ec2_vpc_endpoint_services.py +++ b/tests/test_core/test_ec2_vpc_endpoint_services.py @@ -51,6 +51,16 @@ def test_describe_vpc_endpoint_services_bad_args() -> None: assert "The token 'foo' is invalid" in err["Message"] +@mock_aws +def test_describe_vpc_endpoint_services_unimplemented_service() -> None: + """Verify exceptions are raised for bad arguments.""" + ec2 = boto3.client("ec2", region_name="us-east-1") + + service_name = "com.amazonaws.us-east-1.bedrock-agent-runtime" + resp = ec2.describe_vpc_endpoint_services(ServiceNames=[service_name]) + assert resp["ServiceNames"] == [service_name] + + @mock_aws def test_describe_vpc_default_endpoint_services() -> None: """Test successfull calls as well as the next_token arg."""