Feature: Mock region (#4699)

This commit is contained in:
Bert Blommers 2021-12-24 20:02:45 -01:00 committed by GitHub
parent b4724784ae
commit cf87e75d6e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
99 changed files with 319 additions and 824 deletions

View File

@ -18,3 +18,15 @@ Why am I getting RUST errors when installing Moto?
Moto has a dependency on the pip-module `cryptography`. As of Cryptography >= 3.4, this module requires Rust as a dependency. :raw-html:`<br />` Moto has a dependency on the pip-module `cryptography`. As of Cryptography >= 3.4, this module requires Rust as a dependency. :raw-html:`<br />`
Most OS/platforms will support the installation of Rust, but if you're getting any errors related to this, see the cryptography documentation for more information: https://cryptography.io/en/latest/installation/#rust Most OS/platforms will support the installation of Rust, but if you're getting any errors related to this, see the cryptography documentation for more information: https://cryptography.io/en/latest/installation/#rust
Can I mock the default AWS region?
#########################
By default, Moto only allows valid regions, supporting the same regions that AWS supports.
If you want to mock the default region, as an additional layer of protection against accidentally touching your real AWS environment, you can disable this validation:
.. sourcecode:: python
os.environ["MOTO_ALLOW_NONEXISTENT_REGION"] = True
os.environ["AWS_DEFAULT_REGION"] = "antarctica"

View File

@ -228,6 +228,7 @@ Here is an example:
os.environ['AWS_SECRET_ACCESS_KEY'] = 'testing' os.environ['AWS_SECRET_ACCESS_KEY'] = 'testing'
os.environ['AWS_SECURITY_TOKEN'] = 'testing' os.environ['AWS_SECURITY_TOKEN'] = 'testing'
os.environ['AWS_SESSION_TOKEN'] = 'testing' os.environ['AWS_SESSION_TOKEN'] = 'testing'
os.environ['AWS_DEFAULT_REGION'] = 'us-east-1'
@pytest.fixture(scope='function') @pytest.fixture(scope='function')
def s3(aws_credentials): def s3(aws_credentials):

View File

@ -3,7 +3,7 @@ import re
import datetime import datetime
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.exceptions import AWSError from moto.core.exceptions import AWSError
from moto.ec2 import ec2_backends from moto.core.utils import BackendDict
from moto import settings from moto import settings
from .utils import make_arn_for_certificate from .utils import make_arn_for_certificate
@ -559,6 +559,4 @@ class AWSCertificateManagerBackend(BaseBackend):
return certificate, certificate_chain, private_key return certificate, certificate_chain, private_key
acm_backends = {} acm_backends = BackendDict(AWSCertificateManagerBackend, "ec2")
for region, ec2_backend in ec2_backends.items():
acm_backends[region] = AWSCertificateManagerBackend(region)

View File

@ -8,8 +8,6 @@ from copy import copy
import time import time
from boto3.session import Session
try: try:
from urlparse import urlparse from urlparse import urlparse
except ImportError: except ImportError:
@ -17,7 +15,7 @@ except ImportError:
import responses import responses
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel, CloudFormationModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel, CloudFormationModel
from .utils import create_id, to_path from .utils import create_id, to_path
from moto.core.utils import path_url from moto.core.utils import path_url, BackendDict
from .integration_parsers.aws_parser import TypeAwsParser from .integration_parsers.aws_parser import TypeAwsParser
from .integration_parsers.http_parser import TypeHttpParser from .integration_parsers.http_parser import TypeHttpParser
from .integration_parsers.unknown_parser import TypeUnknownParser from .integration_parsers.unknown_parser import TypeUnknownParser
@ -1819,14 +1817,4 @@ class APIGatewayBackend(BaseBackend):
self.base_path_mappings[domain_name].pop(base_path) self.base_path_mappings[domain_name].pop(base_path)
apigateway_backends = {} apigateway_backends = BackendDict(APIGatewayBackend, "apigateway")
for region_name in Session().get_available_regions("apigateway"):
apigateway_backends[region_name] = APIGatewayBackend(region_name)
for region_name in Session().get_available_regions(
"apigateway", partition_name="aws-us-gov"
):
apigateway_backends[region_name] = APIGatewayBackend(region_name)
for region_name in Session().get_available_regions(
"apigateway", partition_name="aws-cn"
):
apigateway_backends[region_name] = APIGatewayBackend(region_name)

View File

@ -1,5 +1,4 @@
from .models import applicationautoscaling_backends from .models import applicationautoscaling_backends
from ..core.models import base_decorator from ..core.models import base_decorator
applicationautoscaling_backend = applicationautoscaling_backends["us-east-1"]
mock_applicationautoscaling = base_decorator(applicationautoscaling_backends) mock_applicationautoscaling = base_decorator(applicationautoscaling_backends)

View File

@ -1,4 +1,5 @@
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from moto.ecs import ecs_backends from moto.ecs import ecs_backends
from .exceptions import AWSValidationException from .exceptions import AWSValidationException
from collections import OrderedDict from collections import OrderedDict
@ -58,18 +59,17 @@ class ScalableDimensionValueSet(Enum):
class ApplicationAutoscalingBackend(BaseBackend): class ApplicationAutoscalingBackend(BaseBackend):
def __init__(self, region, ecs): def __init__(self, region):
super().__init__() super().__init__()
self.region = region self.region = region
self.ecs_backend = ecs self.ecs_backend = ecs_backends[region]
self.targets = OrderedDict() self.targets = OrderedDict()
self.policies = {} self.policies = {}
def reset(self): def reset(self):
region = self.region region = self.region
ecs = self.ecs_backend
self.__dict__ = {} self.__dict__ = {}
self.__init__(region, ecs) self.__init__(region)
@staticmethod @staticmethod
def default_vpc_endpoint_service(service_region, zones): def default_vpc_endpoint_service(service_region, zones):
@ -356,8 +356,4 @@ class FakeApplicationAutoscalingPolicy(BaseModel):
) )
applicationautoscaling_backends = {} applicationautoscaling_backends = BackendDict(ApplicationAutoscalingBackend, "ec2")
for region_name, ecs_backend in ecs_backends.items():
applicationautoscaling_backends[region_name] = ApplicationAutoscalingBackend(
region_name, ecs_backend
)

View File

@ -1,7 +1,7 @@
import time import time
from boto3 import Session
from moto.core import BaseBackend, BaseModel, ACCOUNT_ID from moto.core import BaseBackend, BaseModel, ACCOUNT_ID
from moto.core.utils import BackendDict
from uuid import uuid4 from uuid import uuid4
@ -143,10 +143,4 @@ class AthenaBackend(BaseBackend):
return self.named_queries[query_id] if query_id in self.named_queries else None return self.named_queries[query_id] if query_id in self.named_queries else None
athena_backends = {} athena_backends = BackendDict(AthenaBackend, "athena")
for region in Session().get_available_regions("athena"):
athena_backends[region] = AthenaBackend(region)
for region in Session().get_available_regions("athena", partition_name="aws-us-gov"):
athena_backends[region] = AthenaBackend(region)
for region in Session().get_available_regions("athena", partition_name="aws-cn"):
athena_backends[region] = AthenaBackend(region)

View File

@ -10,7 +10,7 @@ from moto.ec2.exceptions import InvalidInstanceIdError
from collections import OrderedDict from collections import OrderedDict
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel, CloudFormationModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import camelcase_to_underscores from moto.core.utils import camelcase_to_underscores, BackendDict
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
from moto.elb import elb_backends from moto.elb import elb_backends
from moto.elbv2 import elbv2_backends from moto.elbv2 import elbv2_backends
@ -633,22 +633,20 @@ class FakeAutoScalingGroup(CloudFormationModel):
class AutoScalingBackend(BaseBackend): class AutoScalingBackend(BaseBackend):
def __init__(self, ec2_backend, elb_backend, elbv2_backend): def __init__(self, region_name):
self.autoscaling_groups = OrderedDict() self.autoscaling_groups = OrderedDict()
self.launch_configurations = OrderedDict() self.launch_configurations = OrderedDict()
self.policies = {} self.policies = {}
self.lifecycle_hooks = {} self.lifecycle_hooks = {}
self.ec2_backend = ec2_backend self.ec2_backend = ec2_backends[region_name]
self.elb_backend = elb_backend self.elb_backend = elb_backends[region_name]
self.elbv2_backend = elbv2_backend self.elbv2_backend = elbv2_backends[region_name]
self.region = self.elbv2_backend.region_name self.region = region_name
def reset(self): def reset(self):
ec2_backend = self.ec2_backend region = self.region
elb_backend = self.elb_backend
elbv2_backend = self.elbv2_backend
self.__dict__ = {} self.__dict__ = {}
self.__init__(ec2_backend, elb_backend, elbv2_backend) self.__init__(region)
@staticmethod @staticmethod
def default_vpc_endpoint_service(service_region, zones): def default_vpc_endpoint_service(service_region, zones):
@ -1245,8 +1243,4 @@ class AutoScalingBackend(BaseBackend):
return tags return tags
autoscaling_backends = {} autoscaling_backends = BackendDict(AutoScalingBackend, "ec2")
for region, ec2_backend in ec2_backends.items():
autoscaling_backends[region] = AutoScalingBackend(
ec2_backend, elb_backends[region], elbv2_backends[region]
)

View File

@ -22,14 +22,12 @@ import threading
import weakref import weakref
import requests.exceptions import requests.exceptions
from boto3 import Session
from moto.awslambda.policy import Policy from moto.awslambda.policy import Policy
from moto.core import BaseBackend, CloudFormationModel from moto.core import BaseBackend, CloudFormationModel
from moto.core.exceptions import RESTError from moto.core.exceptions import RESTError
from moto.iam.models import iam_backend from moto.iam.models import iam_backend
from moto.iam.exceptions import IAMNotFoundException from moto.iam.exceptions import IAMNotFoundException
from moto.core.utils import unix_time_millis from moto.core.utils import unix_time_millis, BackendDict
from moto.s3.models import s3_backend from moto.s3.models import s3_backend
from moto.logs.models import logs_backends from moto.logs.models import logs_backends
from moto.s3.exceptions import MissingBucket, MissingKey from moto.s3.exceptions import MissingBucket, MissingKey
@ -1451,10 +1449,4 @@ def do_validate_s3():
return os.environ.get("VALIDATE_LAMBDA_S3", "") in ["", "1", "true"] return os.environ.get("VALIDATE_LAMBDA_S3", "") in ["", "1", "true"]
lambda_backends = {} lambda_backends = BackendDict(LambdaBackend, "lambda")
for region in Session().get_available_regions("lambda"):
lambda_backends[region] = LambdaBackend(region)
for region in Session().get_available_regions("lambda", partition_name="aws-us-gov"):
lambda_backends[region] = LambdaBackend(region)
for region in Session().get_available_regions("lambda", partition_name="aws-cn"):
lambda_backends[region] = LambdaBackend(region)

View File

@ -7,7 +7,6 @@ import logging
import docker import docker
import threading import threading
import dateutil.parser import dateutil.parser
from boto3 import Session
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.iam import iam_backends from moto.iam import iam_backends
@ -26,7 +25,7 @@ from moto.ec2.exceptions import InvalidSubnetIdError
from moto.ec2.models import INSTANCE_TYPES as EC2_INSTANCE_TYPES from moto.ec2.models import INSTANCE_TYPES as EC2_INSTANCE_TYPES
from moto.iam.exceptions import IAMNotFoundException from moto.iam.exceptions import IAMNotFoundException
from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID
from moto.core.utils import unix_time_millis from moto.core.utils import unix_time_millis, BackendDict
from moto.utilities.docker_utilities import DockerModel from moto.utilities.docker_utilities import DockerModel
from ..utilities.tagging_service import TaggingService from ..utilities.tagging_service import TaggingService
@ -1476,10 +1475,4 @@ class BatchBackend(BaseBackend):
job.terminate(reason) job.terminate(reason)
batch_backends = {} batch_backends = BackendDict(BatchBackend, "batch")
for region in Session().get_available_regions("batch"):
batch_backends[region] = BatchBackend(region)
for region in Session().get_available_regions("batch", partition_name="aws-us-gov"):
batch_backends[region] = BatchBackend(region)
for region in Session().get_available_regions("batch", partition_name="aws-cn"):
batch_backends[region] = BatchBackend(region)

View File

@ -3,7 +3,6 @@ import json
import yaml import yaml
import uuid import uuid
from boto3 import Session
from collections import OrderedDict from collections import OrderedDict
from yaml.parser import ParserError # pylint:disable=c-extension-no-member from yaml.parser import ParserError # pylint:disable=c-extension-no-member
from yaml.scanner import ScannerError # pylint:disable=c-extension-no-member from yaml.scanner import ScannerError # pylint:disable=c-extension-no-member
@ -13,6 +12,7 @@ from moto.core.models import ACCOUNT_ID
from moto.core.utils import ( from moto.core.utils import (
iso_8601_datetime_with_milliseconds, iso_8601_datetime_with_milliseconds,
iso_8601_datetime_without_milliseconds, iso_8601_datetime_without_milliseconds,
BackendDict,
) )
from moto.sns.models import sns_backends from moto.sns.models import sns_backends
@ -518,7 +518,7 @@ def filter_stacks(all_stacks, status_filter):
class CloudFormationBackend(BaseBackend): class CloudFormationBackend(BaseBackend):
def __init__(self): def __init__(self, region=None):
self.stacks = OrderedDict() self.stacks = OrderedDict()
self.stacksets = OrderedDict() self.stacksets = OrderedDict()
self.deleted_stacks = {} self.deleted_stacks = {}
@ -896,14 +896,4 @@ class CloudFormationBackend(BaseBackend):
) )
cloudformation_backends = {} cloudformation_backends = BackendDict(CloudFormationBackend, "cloudformation")
for region in Session().get_available_regions("cloudformation"):
cloudformation_backends[region] = CloudFormationBackend()
for region in Session().get_available_regions(
"cloudformation", partition_name="aws-us-gov"
):
cloudformation_backends[region] = CloudFormationBackend()
for region in Session().get_available_regions(
"cloudformation", partition_name="aws-cn"
):
cloudformation_backends[region] = CloudFormationBackend()

View File

@ -1,10 +1,9 @@
import re import re
import time import time
from boto3 import Session
from datetime import datetime from datetime import datetime
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import iso_8601_datetime_without_milliseconds from moto.core.utils import iso_8601_datetime_without_milliseconds, BackendDict
from .exceptions import ( from .exceptions import (
S3BucketDoesNotExistException, S3BucketDoesNotExistException,
InsufficientSnsTopicPolicyException, InsufficientSnsTopicPolicyException,
@ -261,14 +260,4 @@ class CloudTrailBackend(BaseBackend):
self.__init__(region_name) self.__init__(region_name)
cloudtrail_backends = {} cloudtrail_backends = BackendDict(CloudTrailBackend, "cloudtrail")
for available_region in Session().get_available_regions("cloudtrail"):
cloudtrail_backends[available_region] = CloudTrailBackend(available_region)
for available_region in Session().get_available_regions(
"cloudtrail", partition_name="aws-us-gov"
):
cloudtrail_backends[available_region] = CloudTrailBackend(available_region)
for available_region in Session().get_available_regions(
"cloudtrail", partition_name="aws-cn"
):
cloudtrail_backends[available_region] = CloudTrailBackend(available_region)

View File

@ -1,6 +1,5 @@
from .models import cloudwatch_backends from .models import cloudwatch_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator, deprecated_base_decorator
cloudwatch_backend = cloudwatch_backends["us-east-1"]
mock_cloudwatch = base_decorator(cloudwatch_backends) mock_cloudwatch = base_decorator(cloudwatch_backends)
mock_cloudwatch_deprecated = deprecated_base_decorator(cloudwatch_backends) mock_cloudwatch_deprecated = deprecated_base_decorator(cloudwatch_backends)

View File

@ -1,7 +1,5 @@
import json import json
from boto3 import Session
from moto.core import ( from moto.core import (
BaseBackend, BaseBackend,
BaseModel, BaseModel,
@ -10,6 +8,7 @@ from moto.core import (
from moto.core.utils import ( from moto.core.utils import (
iso_8601_datetime_without_milliseconds, iso_8601_datetime_without_milliseconds,
iso_8601_datetime_with_nanoseconds, iso_8601_datetime_with_nanoseconds,
BackendDict,
) )
from datetime import datetime, timedelta from datetime import datetime, timedelta
from dateutil.tz import tzutc from dateutil.tz import tzutc
@ -680,12 +679,4 @@ class CloudWatchBackend(BaseBackend):
return None, metrics return None, metrics
cloudwatch_backends = {} cloudwatch_backends = BackendDict(CloudWatchBackend, "cloudwatch")
for region in Session().get_available_regions("cloudwatch"):
cloudwatch_backends[region] = CloudWatchBackend(region)
for region in Session().get_available_regions(
"cloudwatch", partition_name="aws-us-gov"
):
cloudwatch_backends[region] = CloudWatchBackend(region)
for region in Session().get_available_regions("cloudwatch", partition_name="aws-cn"):
cloudwatch_backends[region] = CloudWatchBackend(region)

View File

@ -1,6 +1,5 @@
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import iso_8601_datetime_with_milliseconds from moto.core.utils import iso_8601_datetime_with_milliseconds, BackendDict
from datetime import datetime from datetime import datetime
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from .exceptions import RepositoryDoesNotExistException, RepositoryNameExistsException from .exceptions import RepositoryDoesNotExistException, RepositoryNameExistsException
@ -33,7 +32,7 @@ class CodeCommit(BaseModel):
class CodeCommitBackend(BaseBackend): class CodeCommitBackend(BaseBackend):
def __init__(self): def __init__(self, region=None):
self.repositories = {} self.repositories = {}
@staticmethod @staticmethod
@ -71,6 +70,4 @@ class CodeCommitBackend(BaseBackend):
return None return None
codecommit_backends = {} codecommit_backends = BackendDict(CodeCommitBackend, "codecommit")
for region in Session().get_available_regions("codecommit"):
codecommit_backends[region] = CodeCommitBackend()

View File

@ -1,8 +1,7 @@
import json import json
from datetime import datetime from datetime import datetime
from boto3 import Session from moto.core.utils import iso_8601_datetime_with_milliseconds, BackendDict
from moto.core.utils import iso_8601_datetime_with_milliseconds
from moto.iam.exceptions import IAMNotFoundException from moto.iam.exceptions import IAMNotFoundException
@ -68,7 +67,7 @@ class CodePipeline(BaseModel):
class CodePipelineBackend(BaseBackend): class CodePipelineBackend(BaseBackend):
def __init__(self): def __init__(self, region=None):
self.pipelines = {} self.pipelines = {}
@staticmethod @staticmethod
@ -212,12 +211,4 @@ class CodePipelineBackend(BaseBackend):
pipeline.tags.pop(key, None) pipeline.tags.pop(key, None)
codepipeline_backends = {} codepipeline_backends = BackendDict(CodePipelineBackend, "codepipeline")
for region in Session().get_available_regions("codepipeline"):
codepipeline_backends[region] = CodePipelineBackend()
for region in Session().get_available_regions(
"codepipeline", partition_name="aws-us-gov"
):
codepipeline_backends[region] = CodePipelineBackend()
for region in Session().get_available_regions("codepipeline", partition_name="aws-cn"):
codepipeline_backends[region] = CodePipelineBackend()

View File

@ -1,6 +1,5 @@
from .models import cognitoidentity_backends from .models import cognitoidentity_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator, deprecated_base_decorator
cognitoidentity_backend = cognitoidentity_backends["us-east-1"]
mock_cognitoidentity = base_decorator(cognitoidentity_backends) mock_cognitoidentity = base_decorator(cognitoidentity_backends)
mock_cognitoidentity_deprecated = deprecated_base_decorator(cognitoidentity_backends) mock_cognitoidentity_deprecated = deprecated_base_decorator(cognitoidentity_backends)

View File

@ -2,11 +2,9 @@ import datetime
import json import json
import re import re
from boto3 import Session
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import iso_8601_datetime_with_milliseconds from moto.core.utils import iso_8601_datetime_with_milliseconds, BackendDict
from .exceptions import InvalidNameException, ResourceNotFoundError from .exceptions import InvalidNameException, ResourceNotFoundError
from .utils import get_random_identity_id from .utils import get_random_identity_id
@ -190,14 +188,4 @@ class CognitoIdentityBackend(BaseBackend):
return response return response
cognitoidentity_backends = {} cognitoidentity_backends = BackendDict(CognitoIdentityBackend, "cognito-identity")
for region in Session().get_available_regions("cognito-identity"):
cognitoidentity_backends[region] = CognitoIdentityBackend(region)
for region in Session().get_available_regions(
"cognito-identity", partition_name="aws-us-gov"
):
cognitoidentity_backends[region] = CognitoIdentityBackend(region)
for region in Session().get_available_regions(
"cognito-identity", partition_name="aws-cn"
):
cognitoidentity_backends[region] = CognitoIdentityBackend(region)

View File

@ -6,11 +6,11 @@ import time
import uuid import uuid
import enum import enum
import random import random
from boto3 import Session
from jose import jws from jose import jws
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID
from moto.core.utils import BackendDict
from .exceptions import ( from .exceptions import (
GroupExistsException, GroupExistsException,
NotAuthorizedError, NotAuthorizedError,
@ -1592,15 +1592,7 @@ class CognitoIdpBackend(BaseBackend):
user_pool.add_custom_attributes(custom_attributes) user_pool.add_custom_attributes(custom_attributes)
cognitoidp_backends = {} cognitoidp_backends = BackendDict(CognitoIdpBackend, "cognito-idp")
for region in Session().get_available_regions("cognito-idp"):
cognitoidp_backends[region] = CognitoIdpBackend(region)
for region in Session().get_available_regions(
"cognito-idp", partition_name="aws-us-gov"
):
cognitoidp_backends[region] = CognitoIdpBackend(region)
for region in Session().get_available_regions("cognito-idp", partition_name="aws-cn"):
cognitoidp_backends[region] = CognitoIdpBackend(region)
# Hack to help moto-server process requests on localhost, where the region isn't # Hack to help moto-server process requests on localhost, where the region isn't

View File

@ -7,8 +7,6 @@ import string
from datetime import datetime from datetime import datetime
from boto3 import Session
from moto.config.exceptions import ( from moto.config.exceptions import (
InvalidResourceTypeException, InvalidResourceTypeException,
InvalidDeliveryFrequency, InvalidDeliveryFrequency,
@ -54,6 +52,7 @@ from moto.config.exceptions import (
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID from moto.core import ACCOUNT_ID as DEFAULT_ACCOUNT_ID
from moto.core.responses import AWSServiceSpec from moto.core.responses import AWSServiceSpec
from moto.core.utils import BackendDict
from moto.iam.config import role_config_query, policy_config_query from moto.iam.config import role_config_query, policy_config_query
from moto.s3.config import s3_account_public_access_block_query, s3_config_query from moto.s3.config import s3_account_public_access_block_query, s3_config_query
from moto.utilities.utils import load_resource from moto.utilities.utils import load_resource
@ -845,7 +844,7 @@ class ConfigRule(ConfigEmptyDictable):
class ConfigBackend(BaseBackend): class ConfigBackend(BaseBackend):
def __init__(self): def __init__(self, region=None):
self.recorders = {} self.recorders = {}
self.delivery_channels = {} self.delivery_channels = {}
self.config_aggregators = {} self.config_aggregators = {}
@ -1924,14 +1923,4 @@ class ConfigBackend(BaseBackend):
self.config_rules.pop(rule_name) self.config_rules.pop(rule_name)
config_backends = {} config_backends = BackendDict(ConfigBackend, "config")
for available_region in Session().get_available_regions("config"):
config_backends[available_region] = ConfigBackend()
for available_region in Session().get_available_regions(
"config", partition_name="aws-us-gov"
):
config_backends[available_region] = ConfigBackend()
for available_region in Session().get_available_regions(
"config", partition_name="aws-cn"
):
config_backends[available_region] = ConfigBackend()

View File

@ -53,6 +53,13 @@ class BaseMockAWS:
"instance_metadata": instance_metadata_backend, "instance_metadata": instance_metadata_backend,
"moto_api": moto_api_backend, "moto_api": moto_api_backend,
} }
if "us-east-1" in self.backends:
# We only need to know the URL for a single region
# They will be the same everywhere
self.backends_for_urls["us-east-1"] = self.backends["us-east-1"]
else:
# If us-east-1 is not available, it's probably a global service
# Global services will only have a single region anyway
self.backends_for_urls.update(self.backends) self.backends_for_urls.update(self.backends)
self.backends_for_urls.update(default_backends) self.backends_for_urls.update(default_backends)

View File

@ -7,6 +7,8 @@ import random
import re import re
import string import string
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from boto3 import Session
from moto.settings import allow_unknown_region
from urllib.parse import urlparse from urllib.parse import urlparse
@ -418,3 +420,27 @@ def aws_api_matches(pattern, string):
return True return True
else: else:
return False return False
class BackendDict(dict):
def __init__(self, fn, service_name):
self.fn = fn
sess = Session()
self.regions = list(sess.get_available_regions(service_name))
self.regions.extend(
sess.get_available_regions(service_name, partition_name="aws-us-gov")
)
self.regions.extend(
sess.get_available_regions(service_name, partition_name="aws-cn")
)
def __contains__(self, item):
return item in self.regions or item in self.keys()
def __getitem__(self, item):
# Create the backend for a specific region
if item in self.regions and item not in self.keys():
super().__setitem__(item, self.fn(item))
if item not in self.regions and allow_unknown_region():
super().__setitem__(item, self.fn(item))
return super().__getitem__(item)

View File

@ -1,6 +1,5 @@
from .models import datapipeline_backends from .models import datapipeline_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator, deprecated_base_decorator
datapipeline_backend = datapipeline_backends["us-east-1"]
mock_datapipeline = base_decorator(datapipeline_backends) mock_datapipeline = base_decorator(datapipeline_backends)
mock_datapipeline_deprecated = deprecated_base_decorator(datapipeline_backends) mock_datapipeline_deprecated = deprecated_base_decorator(datapipeline_backends)

View File

@ -1,8 +1,8 @@
import datetime import datetime
from boto3 import Session
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import BackendDict
from .utils import get_random_pipeline_id, remove_capitalization_of_dict_keys from .utils import get_random_pipeline_id, remove_capitalization_of_dict_keys
@ -102,7 +102,7 @@ class Pipeline(CloudFormationModel):
class DataPipelineBackend(BaseBackend): class DataPipelineBackend(BaseBackend):
def __init__(self): def __init__(self, region=None):
self.pipelines = OrderedDict() self.pipelines = OrderedDict()
def create_pipeline(self, name, unique_id, **kwargs): def create_pipeline(self, name, unique_id, **kwargs):
@ -149,12 +149,4 @@ class DataPipelineBackend(BaseBackend):
pipeline.activate() pipeline.activate()
datapipeline_backends = {} datapipeline_backends = BackendDict(DataPipelineBackend, "datapipeline")
for region in Session().get_available_regions("datapipeline"):
datapipeline_backends[region] = DataPipelineBackend()
for region in Session().get_available_regions(
"datapipeline", partition_name="aws-us-gov"
):
datapipeline_backends[region] = DataPipelineBackend()
for region in Session().get_available_regions("datapipeline", partition_name="aws-cn"):
datapipeline_backends[region] = DataPipelineBackend(region)

View File

@ -1,7 +1,6 @@
from boto3 import Session
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .exceptions import InvalidRequestException from .exceptions import InvalidRequestException
@ -233,10 +232,4 @@ class DataSyncBackend(BaseBackend):
) )
datasync_backends = {} datasync_backends = BackendDict(DataSyncBackend, "datasync")
for region in Session().get_available_regions("datasync"):
datasync_backends[region] = DataSyncBackend(region)
for region in Session().get_available_regions("datasync", partition_name="aws-us-gov"):
datasync_backends[region] = DataSyncBackend(region)
for region in Session().get_available_regions("datasync", partition_name="aws-cn"):
datasync_backends[region] = DataSyncBackend(region)

View File

@ -1,8 +1,8 @@
import json import json
from boto3 import Session
from datetime import datetime from datetime import datetime
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .exceptions import ( from .exceptions import (
InvalidResourceStateFault, InvalidResourceStateFault,
@ -195,10 +195,4 @@ class FakeReplicationTask(BaseModel):
return self return self
dms_backends = {} dms_backends = BackendDict(DatabaseMigrationServiceBackend, "dms")
for region in Session().get_available_regions("dms"):
dms_backends[region] = DatabaseMigrationServiceBackend()
for region in Session().get_available_regions("dms", partition_name="aws-us-gov"):
dms_backends[region] = DatabaseMigrationServiceBackend()
for region in Session().get_available_regions("dms", partition_name="aws-cn"):
dms_backends[region] = DatabaseMigrationServiceBackend()

View File

@ -1,10 +1,8 @@
"""DirectoryServiceBackend class with methods for supported APIs.""" """DirectoryServiceBackend class with methods for supported APIs."""
from datetime import datetime, timezone from datetime import datetime, timezone
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import get_random_hex from moto.core.utils import get_random_hex, BackendDict
from moto.ds.exceptions import ( from moto.ds.exceptions import (
ClientException, ClientException,
DirectoryLimitExceededException, DirectoryLimitExceededException,
@ -510,12 +508,4 @@ class DirectoryServiceBackend(BaseBackend):
return self.tagger.list_tags_for_resource(resource_id).get("Tags") return self.tagger.list_tags_for_resource(resource_id).get("Tags")
ds_backends = {} ds_backends = BackendDict(fn=DirectoryServiceBackend, service_name="ds")
for available_region in Session().get_available_regions("ds"):
ds_backends[available_region] = DirectoryServiceBackend(available_region)
for available_region in Session().get_available_regions(
"ds", partition_name="aws-us-gov"
):
ds_backends[available_region] = DirectoryServiceBackend(available_region)
for available_region in Session().get_available_regions("ds", partition_name="aws-cn"):
ds_backends[available_region] = DirectoryServiceBackend(available_region)

View File

@ -6,11 +6,10 @@ import json
import re import re
import uuid import uuid
from boto3 import Session
from collections import OrderedDict from collections import OrderedDict
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import unix_time, unix_time_millis from moto.core.utils import unix_time, unix_time_millis, BackendDict
from moto.core.exceptions import JsonRESTError from moto.core.exceptions import JsonRESTError
from moto.dynamodb2.comparisons import get_filter_expression from moto.dynamodb2.comparisons import get_filter_expression
from moto.dynamodb2.comparisons import get_expected from moto.dynamodb2.comparisons import get_expected
@ -1127,7 +1126,6 @@ class DynamoDBBackend(BaseBackend):
def reset(self): def reset(self):
region_name = self.region_name region_name = self.region_name
self.__dict__ = {} self.__dict__ = {}
self.__init__(region_name) self.__init__(region_name)
@ -1762,10 +1760,4 @@ class DynamoDBBackend(BaseBackend):
pass pass
dynamodb_backends = {} dynamodb_backends = BackendDict(DynamoDBBackend, "dynamodb")
for region in Session().get_available_regions("dynamodb"):
dynamodb_backends[region] = DynamoDBBackend(region)
for region in Session().get_available_regions("dynamodb", partition_name="aws-us-gov"):
dynamodb_backends[region] = DynamoDBBackend(region)
for region in Session().get_available_regions("dynamodb", partition_name="aws-cn"):
dynamodb_backends[region] = DynamoDBBackend(region)

View File

@ -2,9 +2,8 @@ import os
import json import json
import base64 import base64
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from moto.dynamodb2.models import dynamodb_backends, DynamoJsonEncoder from moto.dynamodb2.models import dynamodb_backends, DynamoJsonEncoder
@ -138,14 +137,4 @@ class DynamoDBStreamsBackend(BaseBackend):
return json.dumps(shard_iterator.get(limit), cls=DynamoJsonEncoder) return json.dumps(shard_iterator.get(limit), cls=DynamoJsonEncoder)
dynamodbstreams_backends = {} dynamodbstreams_backends = BackendDict(DynamoDBStreamsBackend, "dynamodbstreams")
for region in Session().get_available_regions("dynamodbstreams"):
dynamodbstreams_backends[region] = DynamoDBStreamsBackend(region)
for region in Session().get_available_regions(
"dynamodbstreams", partition_name="aws-us-gov"
):
dynamodbstreams_backends[region] = DynamoDBStreamsBackend(region)
for region in Session().get_available_regions(
"dynamodbstreams", partition_name="aws-cn"
):
dynamodbstreams_backends[region] = DynamoDBStreamsBackend(region)

View File

@ -22,6 +22,7 @@ from moto.core.utils import (
iso_8601_datetime_with_milliseconds, iso_8601_datetime_with_milliseconds,
camelcase_to_underscores, camelcase_to_underscores,
aws_api_matches, aws_api_matches,
BackendDict,
) )
from moto.kms import kms_backends from moto.kms import kms_backends
from moto.packages.boto.ec2.blockdevicemapping import ( from moto.packages.boto.ec2.blockdevicemapping import (
@ -8760,6 +8761,4 @@ class EC2Backend(
return True return True
ec2_backends = { ec2_backends = BackendDict(EC2Backend, "ec2")
region.name: EC2Backend(region.name) for region in RegionsAndZonesBackend.regions
}

View File

@ -1,19 +1,16 @@
from boto3 import Session
import json import json
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.utils import BackendDict
class Ec2InstanceConnectBackend(BaseBackend): class Ec2InstanceConnectBackend(BaseBackend):
def __init__(self, region=None):
pass
def send_ssh_public_key(self): def send_ssh_public_key(self):
return json.dumps( return json.dumps(
{"RequestId": "example-2a47-4c91-9700-e37e85162cb6", "Success": True} {"RequestId": "example-2a47-4c91-9700-e37e85162cb6", "Success": True}
) )
ec2instanceconnect_backends = {} ec2instanceconnect_backends = BackendDict(Ec2InstanceConnectBackend, "ec2")
for region in Session().get_available_regions("ec2"):
ec2instanceconnect_backends[region] = Ec2InstanceConnectBackend()
for region in Session().get_available_regions("ec2", partition_name="aws-us-gov"):
ec2instanceconnect_backends[region] = Ec2InstanceConnectBackend()
for region in Session().get_available_regions("ec2", partition_name="aws-cn"):
ec2instanceconnect_backends[region] = Ec2InstanceConnectBackend()

View File

@ -10,8 +10,7 @@ from typing import Dict, List
from botocore.exceptions import ParamValidationError from botocore.exceptions import ParamValidationError
from moto.core import BaseBackend, BaseModel, CloudFormationModel, ACCOUNT_ID from moto.core import BaseBackend, BaseModel, CloudFormationModel, ACCOUNT_ID
from moto.core.utils import iso_8601_datetime_without_milliseconds from moto.core.utils import iso_8601_datetime_without_milliseconds, BackendDict
from moto.ec2 import ec2_backends
from moto.ecr.exceptions import ( from moto.ecr.exceptions import (
ImageNotFoundException, ImageNotFoundException,
RepositoryNotFoundException, RepositoryNotFoundException,
@ -951,6 +950,4 @@ class ECRBackend(BaseBackend):
} }
ecr_backends = {} ecr_backends = BackendDict(ECRBackend, "ec2")
for region, ec2_backend in ec2_backends.items():
ecr_backends[region] = ECRBackend(region)

View File

@ -5,12 +5,16 @@ from datetime import datetime
from random import random, randint from random import random, randint
import pytz import pytz
from boto3 import Session
from moto import settings from moto import settings
from moto.core import BaseBackend, BaseModel, CloudFormationModel, ACCOUNT_ID from moto.core import BaseBackend, BaseModel, CloudFormationModel, ACCOUNT_ID
from moto.core.exceptions import JsonRESTError from moto.core.exceptions import JsonRESTError
from moto.core.utils import unix_time, pascal_to_camelcase, remap_nested_keys from moto.core.utils import (
unix_time,
pascal_to_camelcase,
remap_nested_keys,
BackendDict,
)
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
from moto.utilities.tagging_service import TaggingService from moto.utilities.tagging_service import TaggingService
from .exceptions import ( from .exceptions import (
@ -1780,10 +1784,4 @@ class EC2ContainerServiceBackend(BaseBackend):
return False return False
ecs_backends = {} ecs_backends = BackendDict(EC2ContainerServiceBackend, "ecs")
for region in Session().get_available_regions("ecs"):
ecs_backends[region] = EC2ContainerServiceBackend(region)
for region in Session().get_available_regions("ecs", partition_name="aws-us-gov"):
ecs_backends[region] = EC2ContainerServiceBackend(region)
for region in Session().get_available_regions("ecs", partition_name="aws-cn"):
ecs_backends[region] = EC2ContainerServiceBackend(region)

View File

@ -9,13 +9,12 @@ import time
from copy import deepcopy from copy import deepcopy
from hashlib import md5 from hashlib import md5
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend, CloudFormationModel from moto.core import ACCOUNT_ID, BaseBackend, CloudFormationModel
from moto.core.utils import ( from moto.core.utils import (
camelcase_to_underscores, camelcase_to_underscores,
get_random_hex, get_random_hex,
underscores_to_camelcase, underscores_to_camelcase,
BackendDict,
) )
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
from moto.ec2.exceptions import InvalidSubnetIdError from moto.ec2.exceptions import InvalidSubnetIdError
@ -531,10 +530,4 @@ class EFSBackend(BaseBackend):
return backup_policy return backup_policy
efs_backends = {} efs_backends = BackendDict(EFSBackend, "efs")
for region in Session().get_available_regions("efs"):
efs_backends[region] = EFSBackend(region)
for region in Session().get_available_regions("efs", partition_name="aws-us-gov"):
efs_backends[region] = EFSBackend(region)
for region in Session().get_available_regions("efs", partition_name="aws-cn"):
efs_backends[region] = EFSBackend(region)

View File

@ -1,10 +1,8 @@
from datetime import datetime from datetime import datetime
from uuid import uuid4 from uuid import uuid4
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend from moto.core import ACCOUNT_ID, BaseBackend
from moto.core.utils import iso_8601_datetime_without_milliseconds from moto.core.utils import iso_8601_datetime_without_milliseconds, BackendDict
from ..utilities.utils import random_string from ..utilities.utils import random_string
from .exceptions import ( from .exceptions import (
@ -715,10 +713,4 @@ def _validate_fargate_profile_selectors(selectors):
raise_exception(message=FARGATE_PROFILE_TOO_MANY_LABELS) raise_exception(message=FARGATE_PROFILE_TOO_MANY_LABELS)
eks_backends = {} eks_backends = BackendDict(EKSBackend, "eks")
for region in Session().get_available_regions("eks"):
eks_backends[region] = EKSBackend(region)
for region in Session().get_available_regions("eks", partition_name="aws-us-gov"):
eks_backends[region] = EKSBackend(region)
for region in Session().get_available_regions("eks", partition_name="aws-cn"):
eks_backends[region] = EKSBackend(region)

View File

@ -1,6 +1,5 @@
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .exceptions import UserAlreadyExists, UserNotFound from .exceptions import UserAlreadyExists, UserNotFound
@ -93,14 +92,4 @@ class ElastiCacheBackend(BaseBackend):
return self.users.values() return self.users.values()
elasticache_backends = {} elasticache_backends = BackendDict(ElastiCacheBackend, "elasticache")
for available_region in Session().get_available_regions("elasticache"):
elasticache_backends[available_region] = ElastiCacheBackend(available_region)
for available_region in Session().get_available_regions(
"elasticache", partition_name="aws-us-gov"
):
elasticache_backends[available_region] = ElastiCacheBackend(available_region)
for available_region in Session().get_available_regions(
"elasticache", partition_name="aws-cn"
):
elasticache_backends[available_region] = ElastiCacheBackend(available_region)

View File

@ -1,8 +1,7 @@
import weakref import weakref
from boto3 import Session
from moto.core import BaseBackend, BaseModel, ACCOUNT_ID from moto.core import BaseBackend, BaseModel, ACCOUNT_ID
from moto.core.utils import BackendDict
from .exceptions import InvalidParameterValueError, ResourceNotFoundException from .exceptions import InvalidParameterValueError, ResourceNotFoundException
from .utils import make_arn from .utils import make_arn
@ -146,14 +145,4 @@ class EBBackend(BaseBackend):
raise KeyError() raise KeyError()
eb_backends = {} eb_backends = BackendDict(EBBackend, "elasticbeanstalk")
for region in Session().get_available_regions("elasticbeanstalk"):
eb_backends[region] = EBBackend(region)
for region in Session().get_available_regions(
"elasticbeanstalk", partition_name="aws-us-gov"
):
eb_backends[region] = EBBackend(region)
for region in Session().get_available_regions(
"elasticbeanstalk", partition_name="aws-cn"
):
eb_backends[region] = EBBackend(region)

View File

@ -1,5 +1,4 @@
from .models import elastictranscoder_backends from .models import elastictranscoder_backends
from ..core.models import base_decorator from ..core.models import base_decorator
elastictranscoder_backend = elastictranscoder_backends["us-east-1"]
mock_elastictranscoder = base_decorator(elastictranscoder_backends) mock_elastictranscoder = base_decorator(elastictranscoder_backends)

View File

@ -1,5 +1,5 @@
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import BackendDict
import random import random
import string import string
@ -122,14 +122,4 @@ class ElasticTranscoderBackend(BaseBackend):
self.pipelines.pop(pipeline_id) self.pipelines.pop(pipeline_id)
elastictranscoder_backends = {} elastictranscoder_backends = BackendDict(ElasticTranscoderBackend, "elastictranscoder")
for region in Session().get_available_regions("elastictranscoder"):
elastictranscoder_backends[region] = ElasticTranscoderBackend(region)
for region in Session().get_available_regions(
"elastictranscoder", partition_name="aws-us-gov"
):
elastictranscoder_backends[region] = ElasticTranscoderBackend(region)
for region in Session().get_available_regions(
"elastictranscoder", partition_name="aws-cn"
):
elastictranscoder_backends[region] = ElasticTranscoderBackend(region)

View File

@ -12,6 +12,7 @@ from moto.packages.boto.ec2.elb.attributes import (
from moto.packages.boto.ec2.elb.policies import Policies, OtherPolicy from moto.packages.boto.ec2.elb.policies import Policies, OtherPolicy
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import BackendDict
from moto.ec2.models import ec2_backends from moto.ec2.models import ec2_backends
from .exceptions import ( from .exceptions import (
BadHealthCheckDefinition, BadHealthCheckDefinition,
@ -542,6 +543,5 @@ class ELBBackend(BaseBackend):
raise CertificateNotFoundException() raise CertificateNotFoundException()
elb_backends = {} # Use the same regions as EC2
for region in ec2_backends.keys(): elb_backends = BackendDict(ELBBackend, "ec2")
elb_backends[region] = ELBBackend(region)

View File

@ -8,6 +8,7 @@ from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import ( from moto.core.utils import (
iso_8601_datetime_with_milliseconds, iso_8601_datetime_with_milliseconds,
get_random_hex, get_random_hex,
BackendDict,
) )
from moto.ec2.models import ec2_backends from moto.ec2.models import ec2_backends
from moto.acm.models import acm_backends from moto.acm.models import acm_backends
@ -1458,6 +1459,4 @@ Member must satisfy regular expression pattern: {}".format(
target_group.deregister_terminated_instances(instance_ids) target_group.deregister_terminated_instances(instance_ids)
elbv2_backends = {} elbv2_backends = BackendDict(ELBv2Backend, "ec2")
for region in ec2_backends.keys():
elbv2_backends[region] = ELBv2Backend(region)

View File

@ -4,9 +4,9 @@ from datetime import timedelta
import warnings import warnings
import pytz import pytz
from boto3 import Session
from dateutil.parser import parse as dtparse from dateutil.parser import parse as dtparse
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import BackendDict
from moto.emr.exceptions import ( from moto.emr.exceptions import (
InvalidRequestException, InvalidRequestException,
ValidationException, ValidationException,
@ -711,10 +711,4 @@ class ElasticMapReduceBackend(BaseBackend):
del self.security_configurations[name] del self.security_configurations[name]
emr_backends = {} emr_backends = BackendDict(ElasticMapReduceBackend, "emr")
for region in Session().get_available_regions("emr"):
emr_backends[region] = ElasticMapReduceBackend(region)
for region in Session().get_available_regions("emr", partition_name="aws-us-gov"):
emr_backends[region] = ElasticMapReduceBackend(region)
for region in Session().get_available_regions("emr", partition_name="aws-cn"):
emr_backends[region] = ElasticMapReduceBackend(region)

View File

@ -3,5 +3,4 @@ from .models import emrcontainers_backends
from ..core.models import base_decorator from ..core.models import base_decorator
REGION = "us-east-1" REGION = "us-east-1"
emrcontainers_backend = emrcontainers_backends["us-east-1"]
mock_emrcontainers = base_decorator(emrcontainers_backends) mock_emrcontainers = base_decorator(emrcontainers_backends)

View File

@ -1,10 +1,9 @@
"""EMRContainersBackend class with methods for supported APIs.""" """EMRContainersBackend class with methods for supported APIs."""
import re import re
from datetime import datetime from datetime import datetime
from boto3 import Session
from moto.core import BaseBackend, BaseModel, ACCOUNT_ID from moto.core import BaseBackend, BaseModel, ACCOUNT_ID
from moto.core.utils import iso_8601_datetime_without_milliseconds from moto.core.utils import iso_8601_datetime_without_milliseconds, BackendDict
from .utils import random_cluster_id, random_job_id, get_partition, paginated_list from .utils import random_cluster_id, random_job_id, get_partition, paginated_list
from .exceptions import ResourceNotFoundException from .exceptions import ResourceNotFoundException
@ -374,14 +373,4 @@ class EMRContainersBackend(BaseBackend):
return self.jobs[id].to_dict() return self.jobs[id].to_dict()
emrcontainers_backends = {} emrcontainers_backends = BackendDict(EMRContainersBackend, "emr-containers")
for available_region in Session().get_available_regions("emr-containers"):
emrcontainers_backends[available_region] = EMRContainersBackend(available_region)
for available_region in Session().get_available_regions(
"emr-containers", partition_name="aws-us-gov"
):
emrcontainers_backends[available_region] = EMRContainersBackend(available_region)
for available_region in Session().get_available_regions(
"emr-containers", partition_name="aws-cn"
):
emrcontainers_backends[available_region] = EMRContainersBackend(available_region)

View File

@ -1,7 +1,5 @@
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import get_random_hex from moto.core.utils import get_random_hex, BackendDict
from .exceptions import DomainNotFound from .exceptions import DomainNotFound
@ -149,12 +147,4 @@ class ElasticsearchServiceBackend(BaseBackend):
return [{"DomainName": domain.domain_name} for domain in self.domains.values()] return [{"DomainName": domain.domain_name} for domain in self.domains.values()]
es_backends = {} es_backends = BackendDict(ElasticsearchServiceBackend, "es")
for available_region in Session().get_available_regions("es"):
es_backends[available_region] = ElasticsearchServiceBackend(available_region)
for available_region in Session().get_available_regions(
"es", partition_name="aws-us-gov"
):
es_backends[available_region] = ElasticsearchServiceBackend(available_region)
for available_region in Session().get_available_regions("es", partition_name="aws-cn"):
es_backends[available_region] = ElasticsearchServiceBackend(available_region)

View File

@ -10,8 +10,6 @@ from enum import Enum, unique
from json import JSONDecodeError from json import JSONDecodeError
from operator import lt, le, eq, ge, gt from operator import lt, le, eq, ge, gt
from boto3 import Session
from collections import OrderedDict from collections import OrderedDict
from moto.core.exceptions import JsonRESTError from moto.core.exceptions import JsonRESTError
from moto.core import ACCOUNT_ID, BaseBackend, CloudFormationModel, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, CloudFormationModel, BaseModel
@ -19,6 +17,7 @@ from moto.core.utils import (
unix_time, unix_time,
unix_time_millis, unix_time_millis,
iso_8601_datetime_without_milliseconds, iso_8601_datetime_without_milliseconds,
BackendDict,
) )
from moto.events.exceptions import ( from moto.events.exceptions import (
ValidationException, ValidationException,
@ -1806,10 +1805,4 @@ class EventsBackend(BaseBackend):
return {} return {}
events_backends = {} events_backends = BackendDict(EventsBackend, "events")
for region in Session().get_available_regions("events"):
events_backends[region] = EventsBackend(region)
for region in Session().get_available_regions("events", partition_name="aws-us-gov"):
events_backends[region] = EventsBackend(region)
for region in Session().get_available_regions("events", partition_name="aws-cn"):
events_backends[region] = EventsBackend(region)

View File

@ -26,10 +26,9 @@ import warnings
import requests import requests
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.core.utils import BackendDict
from moto.firehose.exceptions import ( from moto.firehose.exceptions import (
ConcurrentModificationException, ConcurrentModificationException,
InvalidArgumentException, InvalidArgumentException,
@ -672,14 +671,4 @@ class FirehoseBackend(BaseBackend):
) )
firehose_backends = {} firehose_backends = BackendDict(FirehoseBackend, "firehose")
for available_region in Session().get_available_regions("firehose"):
firehose_backends[available_region] = FirehoseBackend()
for available_region in Session().get_available_regions(
"firehose", partition_name="aws-us-gov"
):
firehose_backends[available_region] = FirehoseBackend()
for available_region in Session().get_available_regions(
"firehose", partition_name="aws-cn"
):
firehose_backends[available_region] = FirehoseBackend()

View File

@ -1,10 +1,8 @@
import re import re
from datetime import datetime from datetime import datetime
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend from moto.core import ACCOUNT_ID, BaseBackend
from moto.core.utils import iso_8601_datetime_without_milliseconds from moto.core.utils import iso_8601_datetime_without_milliseconds, BackendDict
from .exceptions import ( from .exceptions import (
InvalidInputException, InvalidInputException,
ResourceAlreadyExistsException, ResourceAlreadyExistsException,
@ -167,6 +165,4 @@ class ForecastBackend(BaseBackend):
self.__init__(region_name) self.__init__(region_name)
forecast_backends = {} forecast_backends = BackendDict(ForecastBackend, "forecast")
for region in Session().get_available_regions("forecast"):
forecast_backends[region] = ForecastBackend(region)

View File

@ -2,9 +2,8 @@ import hashlib
import datetime import datetime
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .utils import get_job_id from .utils import get_job_id
@ -234,10 +233,4 @@ class GlacierBackend(BaseBackend):
return vault.create_archive(body, description) return vault.create_archive(body, description)
glacier_backends = {} glacier_backends = BackendDict(GlacierBackend, "glacier")
for region in Session().get_available_regions("glacier"):
glacier_backends[region] = GlacierBackend(region)
for region in Session().get_available_regions("glacier", partition_name="aws-us-gov"):
glacier_backends[region] = GlacierBackend(region)
for region in Session().get_available_regions("glacier", partition_name="aws-cn"):
glacier_backends[region] = GlacierBackend(region)

View File

@ -1,6 +1,6 @@
from __future__ import unicode_literals from __future__ import unicode_literals
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from datetime import datetime from datetime import datetime
from uuid import uuid4 from uuid import uuid4
@ -70,10 +70,4 @@ class Detector(BaseModel):
self.tags = tags self.tags = tags
guardduty_backends = {} guardduty_backends = BackendDict(GuardDutyBackend, "guardduty")
for region in Session().get_available_regions("guardduty"):
guardduty_backends[region] = GuardDutyBackend()
for region in Session().get_available_regions("guardduty", partition_name="aws-us-gov"):
guardduty_backends[region] = GuardDutyBackend()
for region in Session().get_available_regions("guardduty", partition_name="aws-cn"):
guardduty_backends[region] = GuardDutyBackend()

View File

@ -1,5 +1,4 @@
from .models import iot_backends from .models import iot_backends
from ..core.models import base_decorator from ..core.models import base_decorator
iot_backend = iot_backends["us-east-1"]
mock_iot = base_decorator(iot_backends) mock_iot = base_decorator(iot_backends)

View File

@ -9,8 +9,8 @@ from datetime import datetime
from .utils import PAGINATION_MODEL from .utils import PAGINATION_MODEL
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import BackendDict
from moto.utilities.utils import random_string from moto.utilities.utils import random_string
from moto.utilities.paginator import paginate from moto.utilities.paginator import paginate
from .exceptions import ( from .exceptions import (
@ -1524,10 +1524,4 @@ class IoTBackend(BaseBackend):
return domain_configuration return domain_configuration
iot_backends = {} iot_backends = BackendDict(IoTBackend, "iot")
for region in Session().get_available_regions("iot"):
iot_backends[region] = IoTBackend(region)
for region in Session().get_available_regions("iot", partition_name="aws-us-gov"):
iot_backends[region] = IoTBackend(region)
for region in Session().get_available_regions("iot", partition_name="aws-cn"):
iot_backends[region] = IoTBackend(region)

View File

@ -1,5 +1,4 @@
from .models import iotdata_backends from .models import iotdata_backends
from ..core.models import base_decorator from ..core.models import base_decorator
iotdata_backend = iotdata_backends["us-east-1"]
mock_iotdata = base_decorator(iotdata_backends) mock_iotdata = base_decorator(iotdata_backends)

View File

@ -1,10 +1,9 @@
import json import json
import time import time
import jsondiff import jsondiff
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import merge_dicts from moto.core.utils import merge_dicts, BackendDict
from moto.iot import iot_backends from moto.iot import iot_backends
from .exceptions import ( from .exceptions import (
ConflictException, ConflictException,
@ -204,10 +203,4 @@ class IoTDataPlaneBackend(BaseBackend):
return None return None
iotdata_backends = {} iotdata_backends = BackendDict(IoTDataPlaneBackend, "iot-data")
for region in Session().get_available_regions("iot-data"):
iotdata_backends[region] = IoTDataPlaneBackend(region)
for region in Session().get_available_regions("iot-data", partition_name="aws-us-gov"):
iotdata_backends[region] = IoTDataPlaneBackend(region)
for region in Session().get_available_regions("iot-data", partition_name="aws-cn"):
iotdata_backends[region] = IoTDataPlaneBackend(region)

View File

@ -6,10 +6,8 @@ import itertools
from operator import attrgetter from operator import attrgetter
from hashlib import md5 from hashlib import md5
from boto3 import Session
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import unix_time from moto.core.utils import unix_time, BackendDict
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.utilities.paginator import paginate from moto.utilities.paginator import paginate
from .exceptions import ( from .exceptions import (
@ -337,7 +335,7 @@ class Stream(CloudFormationModel):
class KinesisBackend(BaseBackend): class KinesisBackend(BaseBackend):
def __init__(self): def __init__(self, region=None):
self.streams = OrderedDict() self.streams = OrderedDict()
@staticmethod @staticmethod
@ -597,10 +595,4 @@ class KinesisBackend(BaseBackend):
del stream.tags[key] del stream.tags[key]
kinesis_backends = {} kinesis_backends = BackendDict(KinesisBackend, "kinesis")
for region in Session().get_available_regions("kinesis"):
kinesis_backends[region] = KinesisBackend()
for region in Session().get_available_regions("kinesis", partition_name="aws-us-gov"):
kinesis_backends[region] = KinesisBackend()
for region in Session().get_available_regions("kinesis", partition_name="aws-cn"):
kinesis_backends[region] = KinesisBackend()

View File

@ -1,4 +1,3 @@
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from datetime import datetime from datetime import datetime
from .exceptions import ( from .exceptions import (
@ -7,7 +6,7 @@ from .exceptions import (
) )
import random import random
import string import string
from moto.core.utils import get_random_hex from moto.core.utils import get_random_hex, BackendDict
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
@ -135,12 +134,4 @@ class KinesisVideoBackend(BaseBackend):
# add methods from here # add methods from here
kinesisvideo_backends = {} kinesisvideo_backends = BackendDict(KinesisVideoBackend, "kinesisvideo")
for region in Session().get_available_regions("kinesisvideo"):
kinesisvideo_backends[region] = KinesisVideoBackend(region)
for region in Session().get_available_regions(
"kinesisvideo", partition_name="aws-us-gov"
):
kinesisvideo_backends[region] = KinesisVideoBackend(region)
for region in Session().get_available_regions("kinesisvideo", partition_name="aws-cn"):
kinesisvideo_backends[region] = KinesisVideoBackend(region)

View File

@ -1,5 +1,5 @@
from boto3 import Session
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.utils import BackendDict
from moto.kinesisvideo import kinesisvideo_backends from moto.kinesisvideo import kinesisvideo_backends
from moto.sts.utils import random_session_token from moto.sts.utils import random_session_token
@ -68,20 +68,6 @@ class KinesisVideoArchivedMediaBackend(BaseBackend):
return content_type, payload return content_type, payload
kinesisvideoarchivedmedia_backends = {} kinesisvideoarchivedmedia_backends = BackendDict(
for region in Session().get_available_regions("kinesis-video-archived-media"): KinesisVideoArchivedMediaBackend, "kinesis-video-archived-media"
kinesisvideoarchivedmedia_backends[region] = KinesisVideoArchivedMediaBackend( )
region
)
for region in Session().get_available_regions(
"kinesis-video-archived-media", partition_name="aws-us-gov"
):
kinesisvideoarchivedmedia_backends[region] = KinesisVideoArchivedMediaBackend(
region
)
for region in Session().get_available_regions(
"kinesis-video-archived-media", partition_name="aws-cn"
):
kinesisvideoarchivedmedia_backends[region] = KinesisVideoArchivedMediaBackend(
region
)

View File

@ -3,10 +3,8 @@ import os
from collections import defaultdict from collections import defaultdict
from datetime import datetime, timedelta from datetime import datetime, timedelta
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend, CloudFormationModel from moto.core import ACCOUNT_ID, BaseBackend, CloudFormationModel
from moto.core.utils import unix_time from moto.core.utils import unix_time, BackendDict
from moto.utilities.tagging_service import TaggingService from moto.utilities.tagging_service import TaggingService
from moto.core.exceptions import JsonRESTError from moto.core.exceptions import JsonRESTError
@ -415,10 +413,4 @@ class KmsBackend(BaseBackend):
) )
kms_backends = {} kms_backends = BackendDict(KmsBackend, "kms")
for region in Session().get_available_regions("kms"):
kms_backends[region] = KmsBackend(region)
for region in Session().get_available_regions("kms", partition_name="aws-us-gov"):
kms_backends[region] = KmsBackend(region)
for region in Session().get_available_regions("kms", partition_name="aws-cn"):
kms_backends[region] = KmsBackend(region)

View File

@ -1,12 +1,11 @@
import uuid import uuid
from boto3 import Session
from datetime import datetime, timedelta from datetime import datetime, timedelta
from moto import core as moto_core from moto import core as moto_core
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.models import CloudFormationModel from moto.core.models import CloudFormationModel
from moto.core.utils import unix_time_millis from moto.core.utils import unix_time_millis, BackendDict
from moto.utilities.paginator import paginate from moto.utilities.paginator import paginate
from moto.logs.metric_filters import MetricFilters from moto.logs.metric_filters import MetricFilters
from moto.logs.exceptions import ( from moto.logs.exceptions import (
@ -984,14 +983,4 @@ class LogsBackend(BaseBackend):
return query_id return query_id
logs_backends = {} logs_backends = BackendDict(LogsBackend, "logs")
for available_region in Session().get_available_regions("logs"):
logs_backends[available_region] = LogsBackend(available_region)
for available_region in Session().get_available_regions(
"logs", partition_name="aws-us-gov"
):
logs_backends[available_region] = LogsBackend(available_region)
for available_region in Session().get_available_regions(
"logs", partition_name="aws-cn"
):
logs_backends[available_region] = LogsBackend(available_region)

View File

@ -3,9 +3,8 @@ from __future__ import division
import datetime import datetime
import re import re
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .exceptions import ( from .exceptions import (
BadRequestException, BadRequestException,
@ -1095,6 +1094,4 @@ class ManagedBlockchainBackend(BaseBackend):
self.nodes.get(nodeid).update(logpublishingconfiguration) self.nodes.get(nodeid).update(logpublishingconfiguration)
managedblockchain_backends = {} managedblockchain_backends = BackendDict(ManagedBlockchainBackend, "managedblockchain")
for region in Session().get_available_regions("managedblockchain"):
managedblockchain_backends[region] = ManagedBlockchainBackend(region)

View File

@ -1,8 +1,8 @@
from collections import OrderedDict from collections import OrderedDict
from uuid import uuid4 from uuid import uuid4
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from moto.mediaconnect.exceptions import NotFoundException from moto.mediaconnect.exceptions import NotFoundException
@ -234,12 +234,4 @@ class MediaConnectBackend(BaseBackend):
# add methods from here # add methods from here
mediaconnect_backends = {} mediaconnect_backends = BackendDict(MediaConnectBackend, "mediaconnect")
for region in Session().get_available_regions("mediaconnect"):
mediaconnect_backends[region] = MediaConnectBackend()
for region in Session().get_available_regions(
"mediaconnect", partition_name="aws-us-gov"
):
mediaconnect_backends[region] = MediaConnectBackend()
for region in Session().get_available_regions("mediaconnect", partition_name="aws-cn"):
mediaconnect_backends[region] = MediaConnectBackend()

View File

@ -1,5 +1,4 @@
from .models import medialive_backends from .models import medialive_backends
from ..core.models import base_decorator from ..core.models import base_decorator
medialive_backend = medialive_backends["us-east-1"]
mock_medialive = base_decorator(medialive_backends) mock_medialive = base_decorator(medialive_backends)

View File

@ -1,9 +1,8 @@
from collections import OrderedDict from collections import OrderedDict
from uuid import uuid4 from uuid import uuid4
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
class Input(BaseModel): class Input(BaseModel):
@ -291,10 +290,4 @@ class MediaLiveBackend(BaseBackend):
return a_input return a_input
medialive_backends = {} medialive_backends = BackendDict(MediaLiveBackend, "medialive")
for region in Session().get_available_regions("medialive"):
medialive_backends[region] = MediaLiveBackend()
for region in Session().get_available_regions("medialive", partition_name="aws-us-gov"):
medialive_backends[region] = MediaLiveBackend()
for region in Session().get_available_regions("medialive", partition_name="aws-cn"):
medialive_backends[region] = MediaLiveBackend()

View File

@ -1,8 +1,7 @@
from collections import OrderedDict from collections import OrderedDict
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .exceptions import ClientError from .exceptions import ClientError
@ -216,12 +215,4 @@ class MediaPackageBackend(BaseBackend):
raise ClientError(error, "origin endpoint with id={} not found".format(id)) raise ClientError(error, "origin endpoint with id={} not found".format(id))
mediapackage_backends = {} mediapackage_backends = BackendDict(MediaPackageBackend, "mediapackage")
for region in Session().get_available_regions("mediapackage"):
mediapackage_backends[region] = MediaPackageBackend(region)
for region in Session().get_available_regions(
"mediapackage", partition_name="aws-us-gov"
):
mediapackage_backends[region] = MediaPackageBackend(region)
for region in Session().get_available_regions("mediapackage", partition_name="aws-cn"):
mediapackage_backends[region] = MediaPackageBackend(region)

View File

@ -1,9 +1,8 @@
from collections import OrderedDict from collections import OrderedDict
from datetime import date from datetime import date
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .exceptions import ( from .exceptions import (
ContainerNotFoundException, ContainerNotFoundException,
ResourceNotFoundException, ResourceNotFoundException,
@ -129,12 +128,4 @@ class MediaStoreBackend(BaseBackend):
return metric_policy return metric_policy
mediastore_backends = {} mediastore_backends = BackendDict(MediaStoreBackend, "mediastore")
for region in Session().get_available_regions("mediastore"):
mediastore_backends[region] = MediaStoreBackend(region)
for region in Session().get_available_regions(
"mediastore", partition_name="aws-us-gov"
):
mediastore_backends[region] = MediaStoreBackend(region)
for region in Session().get_available_regions("mediastore", partition_name="aws-cn"):
mediastore_backends[region] = MediaStoreBackend(region)

View File

@ -1,9 +1,8 @@
import hashlib import hashlib
from collections import OrderedDict from collections import OrderedDict
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .exceptions import ClientError from .exceptions import ClientError
@ -75,14 +74,4 @@ class MediaStoreDataBackend(BaseBackend):
return response_items return response_items
mediastoredata_backends = {} mediastoredata_backends = BackendDict(MediaStoreDataBackend, "mediastore-data")
for region in Session().get_available_regions("mediastore-data"):
mediastoredata_backends[region] = MediaStoreDataBackend(region)
for region in Session().get_available_regions(
"mediastore-data", partition_name="aws-us-gov"
):
mediastoredata_backends[region] = MediaStoreDataBackend(region)
for region in Session().get_available_regions(
"mediastore-data", partition_name="aws-cn"
):
mediastoredata_backends[region] = MediaStoreDataBackend(region)

View File

@ -1,6 +1,7 @@
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.core.utils import BackendDict
import uuid import uuid
import datetime import datetime
from random import choice from random import choice
@ -494,17 +495,18 @@ class App(BaseModel):
class OpsWorksBackend(BaseBackend): class OpsWorksBackend(BaseBackend):
def __init__(self, ec2_backend): def __init__(self, region):
self.stacks = {} self.stacks = {}
self.layers = {} self.layers = {}
self.apps = {} self.apps = {}
self.instances = {} self.instances = {}
self.ec2_backend = ec2_backend self.region_name = region
self.ec2_backend = ec2_backends[region]
def reset(self): def reset(self):
ec2_backend = self.ec2_backend region = self.region_name
self.__dict__ = {} self.__dict__ = {}
self.__init__(ec2_backend) self.__init__(region)
def create_stack(self, **kwargs): def create_stack(self, **kwargs):
stack = Stack(**kwargs) stack = Stack(**kwargs)
@ -671,6 +673,4 @@ class OpsWorksBackend(BaseBackend):
self.instances[instance_id].start() self.instances[instance_id].start()
opsworks_backends = {} opsworks_backends = BackendDict(OpsWorksBackend, "ec2")
for region, ec2_backend in ec2_backends.items():
opsworks_backends[region] = OpsWorksBackend(ec2_backend)

View File

@ -1,9 +1,8 @@
from xml.etree import ElementTree as ET from xml.etree import ElementTree as ET
import datetime import datetime
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .resources import VOICE_DATA from .resources import VOICE_DATA
from .utils import make_arn_for_lexicon from .utils import make_arn_for_lexicon
@ -113,10 +112,4 @@ class PollyBackend(BaseBackend):
self._lexicons[name] = lexicon self._lexicons[name] = lexicon
polly_backends = {} polly_backends = BackendDict(PollyBackend, "polly")
for region in Session().get_available_regions("polly"):
polly_backends[region] = PollyBackend(region)
for region in Session().get_available_regions("polly", partition_name="aws-us-gov"):
polly_backends[region] = PollyBackend(region)
for region in Session().get_available_regions("polly", partition_name="aws-cn"):
polly_backends[region] = PollyBackend(region)

View File

@ -4,9 +4,8 @@ from datetime import datetime
import random import random
from uuid import uuid4 from uuid import uuid4
from boto3 import Session
from moto.core import BaseBackend, BaseModel, ACCOUNT_ID from moto.core import BaseBackend, BaseModel, ACCOUNT_ID
from moto.core.utils import unix_time from moto.core.utils import unix_time, BackendDict
from moto.organizations import organizations_backends from moto.organizations import organizations_backends
from moto.ram.exceptions import ( from moto.ram.exceptions import (
MalformedArnException, MalformedArnException,
@ -238,10 +237,4 @@ class ResourceAccessManagerBackend(BaseBackend):
return dict(returnValue=True) return dict(returnValue=True)
ram_backends = {} ram_backends = BackendDict(ResourceAccessManagerBackend, "ram")
for region in Session().get_available_regions("ram"):
ram_backends[region] = ResourceAccessManagerBackend(region)
for region in Session().get_available_regions("ram", partition_name="aws-us-gov"):
ram_backends[region] = ResourceAccessManagerBackend(region)
for region in Session().get_available_regions("ram", partition_name="aws-cn"):
ram_backends[region] = ResourceAccessManagerBackend(region)

View File

@ -1,6 +1,5 @@
from .models import rds_backends from .models import rds_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator, deprecated_base_decorator
rds_backend = rds_backends["us-east-1"]
mock_rds = base_decorator(rds_backends) mock_rds = base_decorator(rds_backends)
mock_rds_deprecated = deprecated_base_decorator(rds_backends) mock_rds_deprecated = deprecated_base_decorator(rds_backends)

View File

@ -1,7 +1,7 @@
from boto3 import Session
from jinja2 import Template from jinja2 import Template
from moto.core import BaseBackend, CloudFormationModel from moto.core import BaseBackend, CloudFormationModel
from moto.core.utils import BackendDict
from moto.ec2.models import ec2_backends from moto.ec2.models import ec2_backends
from moto.rds.exceptions import UnformattedGetAttTemplateException from moto.rds.exceptions import UnformattedGetAttTemplateException
from moto.rds2.models import rds2_backends from moto.rds2.models import rds2_backends
@ -337,10 +337,4 @@ class RDSBackend(BaseBackend):
return rds2_backends[self.region] return rds2_backends[self.region]
rds_backends = {} rds_backends = BackendDict(RDSBackend, "rds")
for region in Session().get_available_regions("rds"):
rds_backends[region] = RDSBackend(region)
for region in Session().get_available_regions("rds", partition_name="aws-us-gov"):
rds_backends[region] = RDSBackend(region)
for region in Session().get_available_regions("rds", partition_name="aws-cn"):
rds_backends[region] = RDSBackend(region)

View File

@ -5,13 +5,12 @@ import random
import string import string
from collections import defaultdict from collections import defaultdict
from boto3 import Session
from jinja2 import Template from jinja2 import Template
from re import compile as re_compile from re import compile as re_compile
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel, CloudFormationModel, ACCOUNT_ID from moto.core import BaseBackend, BaseModel, CloudFormationModel, ACCOUNT_ID
from moto.core.utils import iso_8601_datetime_with_milliseconds from moto.core.utils import iso_8601_datetime_with_milliseconds, BackendDict
from moto.ec2.models import ec2_backends from moto.ec2.models import ec2_backends
from .exceptions import ( from .exceptions import (
RDSClientError, RDSClientError,
@ -1817,10 +1816,4 @@ class DBParameterGroup(CloudFormationModel):
return db_parameter_group return db_parameter_group
rds2_backends = {} rds2_backends = BackendDict(RDS2Backend, "rds")
for region in Session().get_available_regions("rds"):
rds2_backends[region] = RDS2Backend(region)
for region in Session().get_available_regions("rds", partition_name="aws-us-gov"):
rds2_backends[region] = RDS2Backend(region)
for region in Session().get_available_regions("rds", partition_name="aws-cn"):
rds2_backends[region] = RDS2Backend(region)

View File

@ -1,6 +1,5 @@
from .models import redshift_backends from .models import redshift_backends
from ..core.models import base_decorator, deprecated_base_decorator from ..core.models import base_decorator, deprecated_base_decorator
redshift_backend = redshift_backends["us-east-1"]
mock_redshift = base_decorator(redshift_backends) mock_redshift = base_decorator(redshift_backends)
mock_redshift_deprecated = deprecated_base_decorator(redshift_backends) mock_redshift_deprecated = deprecated_base_decorator(redshift_backends)

View File

@ -1,11 +1,9 @@
import copy import copy
import datetime import datetime
from boto3 import Session
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import iso_8601_datetime_with_milliseconds from moto.core.utils import iso_8601_datetime_with_milliseconds, BackendDict
from moto.utilities.utils import random_string from moto.utilities.utils import random_string
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
from .exceptions import ( from .exceptions import (
@ -548,7 +546,7 @@ class Snapshot(TaggableResourceMixin, BaseModel):
class RedshiftBackend(BaseBackend): class RedshiftBackend(BaseBackend):
def __init__(self, ec2_backend, region_name): def __init__(self, region_name):
self.region = region_name self.region = region_name
self.clusters = {} self.clusters = {}
self.subnet_groups = {} self.subnet_groups = {}
@ -565,7 +563,7 @@ class RedshiftBackend(BaseBackend):
self.region, self.region,
) )
} }
self.ec2_backend = ec2_backend self.ec2_backend = ec2_backends[self.region]
self.snapshots = OrderedDict() self.snapshots = OrderedDict()
self.RESOURCE_TYPE_MAP = { self.RESOURCE_TYPE_MAP = {
"cluster": self.clusters, "cluster": self.clusters,
@ -577,10 +575,9 @@ class RedshiftBackend(BaseBackend):
self.snapshot_copy_grants = {} self.snapshot_copy_grants = {}
def reset(self): def reset(self):
ec2_backend = self.ec2_backend
region_name = self.region region_name = self.region
self.__dict__ = {} self.__dict__ = {}
self.__init__(ec2_backend, region_name) self.__init__(region_name)
@staticmethod @staticmethod
def default_vpc_endpoint_service(service_region, zones): def default_vpc_endpoint_service(service_region, zones):
@ -1007,10 +1004,4 @@ class RedshiftBackend(BaseBackend):
raise ClusterNotFoundError(cluster_identifier) raise ClusterNotFoundError(cluster_identifier)
redshift_backends = {} redshift_backends = BackendDict(RedshiftBackend, "redshift")
for region in Session().get_available_regions("redshift"):
redshift_backends[region] = RedshiftBackend(ec2_backends[region], region)
for region in Session().get_available_regions("redshift", partition_name="aws-us-gov"):
redshift_backends[region] = RedshiftBackend(ec2_backends[region], region)
for region in Session().get_available_regions("redshift", partition_name="aws-cn"):
redshift_backends[region] = RedshiftBackend(ec2_backends[region], region)

View File

@ -3,10 +3,8 @@ from builtins import str
import json import json
import re import re
from boto3 import Session from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import BackendDict
from moto.core import BaseBackend, BaseModel
from moto.core import ACCOUNT_ID
from .exceptions import BadRequestException from .exceptions import BadRequestException
@ -372,14 +370,4 @@ class ResourceGroupsBackend(BaseBackend):
return self.groups.by_name[group_name] return self.groups.by_name[group_name]
resourcegroups_backends = {} resourcegroups_backends = BackendDict(ResourceGroupsBackend, "resource-groups")
for region in Session().get_available_regions("resource-groups"):
resourcegroups_backends[region] = ResourceGroupsBackend(region)
for region in Session().get_available_regions(
"resource-groups", partition_name="aws-us-gov"
):
resourcegroups_backends[region] = ResourceGroupsBackend(region)
for region in Session().get_available_regions(
"resource-groups", partition_name="aws-cn"
):
resourcegroups_backends[region] = ResourceGroupsBackend(region)

View File

@ -1,9 +1,9 @@
import uuid import uuid
from boto3 import Session
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.exceptions import RESTError from moto.core.exceptions import RESTError
from moto.core.utils import BackendDict
from moto.s3 import s3_backends from moto.s3 import s3_backends
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
@ -729,14 +729,6 @@ class ResourceGroupsTaggingAPIBackend(BaseBackend):
# return failed_resources_map # return failed_resources_map
resourcegroupstaggingapi_backends = {} resourcegroupstaggingapi_backends = BackendDict(
for region in Session().get_available_regions("resourcegroupstaggingapi"): ResourceGroupsTaggingAPIBackend, "resourcegroupstaggingapi"
resourcegroupstaggingapi_backends[region] = ResourceGroupsTaggingAPIBackend(region) )
for region in Session().get_available_regions(
"resourcegroupstaggingapi", partition_name="aws-us-gov"
):
resourcegroupstaggingapi_backends[region] = ResourceGroupsTaggingAPIBackend(region)
for region in Session().get_available_regions(
"resourcegroupstaggingapi", partition_name="aws-cn"
):
resourcegroupstaggingapi_backends[region] = ResourceGroupsTaggingAPIBackend(region)

View File

@ -4,11 +4,9 @@ from datetime import datetime, timezone
from ipaddress import ip_address, ip_network, IPv4Address from ipaddress import ip_address, ip_network, IPv4Address
import re import re
from boto3 import Session
from moto.core import ACCOUNT_ID from moto.core import ACCOUNT_ID
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import get_random_hex from moto.core.utils import get_random_hex, BackendDict
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
from moto.ec2.exceptions import InvalidSubnetIdError from moto.ec2.exceptions import InvalidSubnetIdError
from moto.ec2.exceptions import InvalidSecurityGroupNotFoundError from moto.ec2.exceptions import InvalidSecurityGroupNotFoundError
@ -838,20 +836,4 @@ class Route53ResolverBackend(BaseBackend):
return resolver_endpoint return resolver_endpoint
route53resolver_backends = {} route53resolver_backends = BackendDict(Route53ResolverBackend, "route53resolver")
for available_region in Session().get_available_regions("route53resolver"):
route53resolver_backends[available_region] = Route53ResolverBackend(
available_region
)
for available_region in Session().get_available_regions(
"route53resolver", partition_name="aws-us-gov"
):
route53resolver_backends[available_region] = Route53ResolverBackend(
available_region
)
for available_region in Session().get_available_regions(
"route53resolver", partition_name="aws-cn"
):
route53resolver_backends[available_region] = Route53ResolverBackend(
available_region
)

View File

@ -1,9 +1,9 @@
import json import json
import os import os
from boto3 import Session
from datetime import datetime from datetime import datetime
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel, CloudFormationModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel, CloudFormationModel
from moto.core.exceptions import RESTError from moto.core.exceptions import RESTError
from moto.core.utils import BackendDict
from moto.sagemaker import validators from moto.sagemaker import validators
from moto.utilities.paginator import paginate from moto.utilities.paginator import paginate
from .exceptions import ( from .exceptions import (
@ -2114,10 +2114,4 @@ class FakeTrialComponent(BaseObject):
) )
sagemaker_backends = {} sagemaker_backends = BackendDict(SageMakerModelBackend, "sagemaker")
for region in Session().get_available_regions("sagemaker"):
sagemaker_backends[region] = SageMakerModelBackend(region)
for region in Session().get_available_regions("sagemaker", partition_name="aws-us-gov"):
sagemaker_backends[region] = SageMakerModelBackend(region)
for region in Session().get_available_regions("sagemaker", partition_name="aws-cn"):
sagemaker_backends[region] = SageMakerModelBackend(region)

View File

@ -1,8 +1,8 @@
"""SimpleDBBackend class with methods for supported APIs.""" """SimpleDBBackend class with methods for supported APIs."""
import re import re
from boto3 import Session
from collections import defaultdict from collections import defaultdict
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from threading import Lock from threading import Lock
from .exceptions import InvalidDomainName, UnknownDomainName from .exceptions import InvalidDomainName, UnknownDomainName
@ -98,12 +98,4 @@ class SimpleDBBackend(BaseBackend):
domain.put(item_name, attributes) domain.put(item_name, attributes)
sdb_backends = {} sdb_backends = BackendDict(SimpleDBBackend, "sdb")
for available_region in Session().get_available_regions("sdb"):
sdb_backends[available_region] = SimpleDBBackend(available_region)
for available_region in Session().get_available_regions(
"sdb", partition_name="aws-us-gov"
):
sdb_backends[available_region] = SimpleDBBackend(available_region)
for available_region in Session().get_available_regions("sdb", partition_name="aws-cn"):
sdb_backends[available_region] = SimpleDBBackend(available_region)

View File

@ -3,10 +3,10 @@ import json
import uuid import uuid
import datetime import datetime
from boto3 import Session
from typing import List, Tuple from typing import List, Tuple
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from .exceptions import ( from .exceptions import (
SecretNotFoundException, SecretNotFoundException,
SecretHasNoValueException, SecretHasNoValueException,
@ -796,14 +796,4 @@ class SecretsManagerBackend(BaseBackend):
) )
secretsmanager_backends = {} secretsmanager_backends = BackendDict(SecretsManagerBackend, "secretsmanager")
for region in Session().get_available_regions("secretsmanager"):
secretsmanager_backends[region] = SecretsManagerBackend(region_name=region)
for region in Session().get_available_regions(
"secretsmanager", partition_name="aws-us-gov"
):
secretsmanager_backends[region] = SecretsManagerBackend(region_name=region)
for region in Session().get_available_regions(
"secretsmanager", partition_name="aws-cn"
):
secretsmanager_backends[region] = SecretsManagerBackend(region_name=region)

View File

@ -283,7 +283,13 @@ def create_backend_app(service):
backend_app.view_functions = {} backend_app.view_functions = {}
backend_app.url_map = Map() backend_app.url_map = Map()
backend_app.url_map.converters["regex"] = RegexConverter backend_app.url_map.converters["regex"] = RegexConverter
backend = list(backends.get_backend(service).values())[0]
backend_dict = backends.get_backend(service)
if "us-east-1" in backend_dict:
backend = backend_dict["us-east-1"]
else:
backend = backend_dict["global"]
for url_path, handler in backend.flask_paths.items(): for url_path, handler in backend.flask_paths.items():
view_func = convert_flask_to_httpretty_response(handler) view_func = convert_flask_to_httpretty_response(handler)
if handler.__name__ == "dispatch": if handler.__name__ == "dispatch":

View File

@ -46,6 +46,10 @@ def ecs_new_arn_format():
return os.environ.get("MOTO_ECS_NEW_ARN", "false").lower() == "true" return os.environ.get("MOTO_ECS_NEW_ARN", "false").lower() == "true"
def allow_unknown_region():
return os.environ.get("MOTO_ALLOW_NONEXISTENT_REGION", "false").lower() == "true"
def moto_server_port(): def moto_server_port():
return os.environ.get("MOTO_PORT") or "5000" return os.environ.get("MOTO_PORT") or "5000"

View File

@ -5,13 +5,12 @@ import json
import requests import requests
import re import re
from boto3 import Session
from collections import OrderedDict from collections import OrderedDict
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import ( from moto.core.utils import (
iso_8601_datetime_with_milliseconds, iso_8601_datetime_with_milliseconds,
camelcase_to_underscores, camelcase_to_underscores,
BackendDict,
) )
from moto.sqs import sqs_backends from moto.sqs import sqs_backends
@ -819,13 +818,7 @@ class SNSBackend(BaseBackend):
self.topics[resource_arn]._tags.pop(key, None) self.topics[resource_arn]._tags.pop(key, None)
sns_backends = {} sns_backends = BackendDict(SNSBackend, "sns")
for region in Session().get_available_regions("sns"):
sns_backends[region] = SNSBackend(region)
for region in Session().get_available_regions("sns", partition_name="aws-us-gov"):
sns_backends[region] = SNSBackend(region)
for region in Session().get_available_regions("sns", partition_name="aws-cn"):
sns_backends[region] = SNSBackend(region)
DEFAULT_EFFECTIVE_DELIVERY_POLICY = { DEFAULT_EFFECTIVE_DELIVERY_POLICY = {

View File

@ -10,8 +10,6 @@ from copy import deepcopy
from typing import Dict from typing import Dict
from xml.sax.saxutils import escape from xml.sax.saxutils import escape
from boto3 import Session
from moto.core.exceptions import RESTError from moto.core.exceptions import RESTError
from moto.core import BaseBackend, BaseModel, CloudFormationModel from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import ( from moto.core.utils import (
@ -20,6 +18,7 @@ from moto.core.utils import (
unix_time, unix_time,
unix_time_millis, unix_time_millis,
tags_from_cloudformation_tags_list, tags_from_cloudformation_tags_list,
BackendDict,
) )
from .utils import generate_receipt_handle from .utils import generate_receipt_handle
from .exceptions import ( from .exceptions import (
@ -1108,10 +1107,4 @@ class SQSBackend(BaseBackend):
return True return True
sqs_backends = {} sqs_backends = BackendDict(SQSBackend, "sqs")
for region in Session().get_available_regions("sqs"):
sqs_backends[region] = SQSBackend(region)
for region in Session().get_available_regions("sqs", partition_name="aws-us-gov"):
sqs_backends[region] = SQSBackend(region)
for region in Session().get_available_regions("sqs", partition_name="aws-cn"):
sqs_backends[region] = SQSBackend(region)

View File

@ -1,5 +1,4 @@
from .models import ssm_backends from .models import ssm_backends
from ..core.models import base_decorator from ..core.models import base_decorator
ssm_backend = ssm_backends["us-east-1"]
mock_ssm = base_decorator(ssm_backends) mock_ssm = base_decorator(ssm_backends)

View File

@ -2,11 +2,11 @@ import re
from dataclasses import dataclass from dataclasses import dataclass
from typing import Dict from typing import Dict
from boto3 import Session
from collections import defaultdict from collections import defaultdict
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.exceptions import RESTError from moto.core.exceptions import RESTError
from moto.core.utils import BackendDict
from moto.ec2 import ec2_backends from moto.ec2 import ec2_backends
import datetime import datetime
@ -718,7 +718,7 @@ class FakeMaintenanceWindow:
class SimpleSystemManagerBackend(BaseBackend): class SimpleSystemManagerBackend(BaseBackend):
def __init__(self, region_name=None): def __init__(self, region):
super(SimpleSystemManagerBackend, self).__init__() super(SimpleSystemManagerBackend, self).__init__()
# each value is a list of all of the versions for a parameter # each value is a list of all of the versions for a parameter
# to get the current value, grab the last item of the list # to get the current value, grab the last item of the list
@ -731,7 +731,7 @@ class SimpleSystemManagerBackend(BaseBackend):
self.windows: Dict[str, FakeMaintenanceWindow] = dict() self.windows: Dict[str, FakeMaintenanceWindow] = dict()
self._region = region_name self._region = region
def reset(self): def reset(self):
region_name = self._region region_name = self._region
@ -1843,10 +1843,4 @@ class SimpleSystemManagerBackend(BaseBackend):
del self.windows[window_id] del self.windows[window_id]
ssm_backends = {} ssm_backends = BackendDict(SimpleSystemManagerBackend, "ssm")
for region in Session().get_available_regions("ssm"):
ssm_backends[region] = SimpleSystemManagerBackend(region)
for region in Session().get_available_regions("ssm", partition_name="aws-us-gov"):
ssm_backends[region] = SimpleSystemManagerBackend(region)
for region in Session().get_available_regions("ssm", partition_name="aws-cn"):
ssm_backends[region] = SimpleSystemManagerBackend(region)

View File

@ -1,5 +1,4 @@
from .models import stepfunction_backends from .models import stepfunction_backends
from ..core.models import base_decorator from ..core.models import base_decorator
stepfunction_backend = stepfunction_backends["us-east-1"]
mock_stepfunctions = base_decorator(stepfunction_backends) mock_stepfunctions = base_decorator(stepfunction_backends)

View File

@ -3,10 +3,8 @@ import re
from datetime import datetime from datetime import datetime
from dateutil.tz import tzlocal from dateutil.tz import tzlocal
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend, CloudFormationModel from moto.core import ACCOUNT_ID, BaseBackend, CloudFormationModel
from moto.core.utils import iso_8601_datetime_with_milliseconds from moto.core.utils import iso_8601_datetime_with_milliseconds, BackendDict
from uuid import uuid4 from uuid import uuid4
from .exceptions import ( from .exceptions import (
ExecutionAlreadyExists, ExecutionAlreadyExists,
@ -617,12 +615,4 @@ class StepFunctionBackend(BaseBackend):
return ACCOUNT_ID return ACCOUNT_ID
stepfunction_backends = {} stepfunction_backends = BackendDict(StepFunctionBackend, "stepfunctions")
for region in Session().get_available_regions("stepfunctions"):
stepfunction_backends[region] = StepFunctionBackend(region)
for region in Session().get_available_regions(
"stepfunctions", partition_name="aws-us-gov"
):
stepfunction_backends[region] = StepFunctionBackend(region)
for region in Session().get_available_regions("stepfunctions", partition_name="aws-cn"):
stepfunction_backends[region] = StepFunctionBackend(region)

View File

@ -1,5 +1,4 @@
from .models import support_backends from .models import support_backends
from ..core.models import base_decorator from ..core.models import base_decorator
support_backend = support_backends["us-east-1"]
mock_support = base_decorator(support_backends) mock_support = base_decorator(support_backends)

View File

@ -1,4 +1,3 @@
from boto3 import Session
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.utilities.utils import load_resource from moto.utilities.utils import load_resource
import datetime import datetime
@ -235,9 +234,3 @@ support_backends = {}
# Only currently supported in us-east-1 # Only currently supported in us-east-1
support_backends["us-east-1"] = SupportBackend("us-east-1") support_backends["us-east-1"] = SupportBackend("us-east-1")
for region in Session().get_available_regions("support"):
support_backends[region] = SupportBackend(region)
for region in Session().get_available_regions("support", partition_name="aws-us-gov"):
support_backends[region] = SupportBackend(region)
for region in Session().get_available_regions("support", partition_name="aws-cn"):
support_backends[region] = SupportBackend(region)

View File

@ -1,6 +1,5 @@
from boto3 import Session
from moto.core import BaseBackend from moto.core import BaseBackend
from moto.core.utils import BackendDict
from ..exceptions import ( from ..exceptions import (
SWFUnknownResourceFault, SWFUnknownResourceFault,
@ -433,10 +432,4 @@ class SWFBackend(BaseBackend):
wfe.signal(signal_name, input) wfe.signal(signal_name, input)
swf_backends = {} swf_backends = BackendDict(SWFBackend, "swf")
for region in Session().get_available_regions("swf"):
swf_backends[region] = SWFBackend(region)
for region in Session().get_available_regions("swf", partition_name="aws-us-gov"):
swf_backends[region] = SWFBackend(region)
for region in Session().get_available_regions("swf", partition_name="aws-cn"):
swf_backends[region] = SWFBackend(region)

View File

@ -1,6 +1,5 @@
from boto3 import Session
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel from moto.core import ACCOUNT_ID, BaseBackend, BaseModel
from moto.core.utils import BackendDict
class TimestreamTable(BaseModel): class TimestreamTable(BaseModel):
@ -154,27 +153,10 @@ class TimestreamWriteBackend(BaseBackend):
self.__init__(region_name) self.__init__(region_name)
timestreamwrite_backends = {} timestreamwrite_backends = BackendDict(TimestreamWriteBackend, "timestream-write")
for available_region in Session().get_available_regions("timestream-write"):
timestreamwrite_backends[available_region] = TimestreamWriteBackend(
available_region
)
for available_region in Session().get_available_regions(
"timestream-write", partition_name="aws-us-gov"
):
timestreamwrite_backends[available_region] = TimestreamWriteBackend(
available_region
)
for available_region in Session().get_available_regions(
"timestream-write", partition_name="aws-cn"
):
timestreamwrite_backends[available_region] = TimestreamWriteBackend(
available_region
)
if len(timestreamwrite_backends) == 0: # Boto does not return any regions at the time of writing (20/10/2021)
# Boto does not return any regions at the time of writing (20/10/2021) # Hardcoding the known regions for now
# Hardcoding the known regions for now # Thanks, Jeff
# Thanks, Jeff for r in ["us-east-1", "us-east-2", "us-west-2", "eu-central-1", "eu-west-1"]:
for r in ["us-east-1", "us-east-2", "us-west-2", "eu-central-1", "eu-west-1"]:
timestreamwrite_backends[r] = TimestreamWriteBackend(r) timestreamwrite_backends[r] = TimestreamWriteBackend(r)

View File

@ -1,7 +1,7 @@
import uuid import uuid
from datetime import datetime, timedelta from datetime import datetime, timedelta
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.ec2 import ec2_backends from moto.core.utils import BackendDict
from moto.sts.models import ACCOUNT_ID from moto.sts.models import ACCOUNT_ID
from .exceptions import ConflictException, BadRequestException from .exceptions import ConflictException, BadRequestException
@ -806,6 +806,4 @@ class TranscribeBackend(BaseBackend):
return response return response
transcribe_backends = {} transcribe_backends = BackendDict(TranscribeBackend, "transcribe")
for region, ec2_backend in ec2_backends.items():
transcribe_backends[region] = TranscribeBackend(region_name=region)

View File

@ -1,12 +1,10 @@
from uuid import uuid4 from uuid import uuid4
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.wafv2 import utils from moto.wafv2 import utils
# from moto.ec2.models import elbv2_backends
from .utils import make_arn_for_wacl, pascal_to_underscores_dict from .utils import make_arn_for_wacl, pascal_to_underscores_dict
from .exceptions import WAFV2DuplicateItemException from .exceptions import WAFV2DuplicateItemException
from moto.core.utils import iso_8601_datetime_with_milliseconds from moto.core.utils import iso_8601_datetime_with_milliseconds, BackendDict
import datetime import datetime
from collections import OrderedDict from collections import OrderedDict
@ -115,15 +113,7 @@ class WAFV2Backend(BaseBackend):
# return ec2_backends[self.region_name] # return ec2_backends[self.region_name]
wafv2_backends = {} wafv2_backends = BackendDict(WAFV2Backend, "waf-regional")
wafv2_backends[GLOBAL_REGION] = WAFV2Backend( wafv2_backends[GLOBAL_REGION] = WAFV2Backend(
GLOBAL_REGION GLOBAL_REGION
) # never used? cloudfront is global and uses us-east-1 ) # never used? cloudfront is global and uses us-east-1
for region in Session().get_available_regions("waf-regional"):
wafv2_backends[region] = WAFV2Backend(region)
for region in Session().get_available_regions(
"waf-regional", partition_name="aws-us-gov"
):
wafv2_backends[region] = WAFV2Backend(region)
for region in Session().get_available_regions("waf-regional", partition_name="aws-cn"):
wafv2_backends[region] = WAFV2Backend(region)

View File

@ -1,10 +1,10 @@
import bisect import bisect
from boto3 import Session
import datetime import datetime
from collections import defaultdict from collections import defaultdict
import json import json
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.exceptions import AWSError from moto.core.exceptions import AWSError
from moto.core.utils import BackendDict
from .exceptions import BadSegmentException from .exceptions import BadSegmentException
@ -230,7 +230,7 @@ class SegmentCollection(object):
class XRayBackend(BaseBackend): class XRayBackend(BaseBackend):
def __init__(self): def __init__(self, region=None):
self._telemetry_records = [] self._telemetry_records = []
self._segment_collection = SegmentCollection() self._segment_collection = SegmentCollection()
@ -292,10 +292,4 @@ class XRayBackend(BaseBackend):
return result return result
xray_backends = {} xray_backends = BackendDict(XRayBackend, "xray")
for region in Session().get_available_regions("xray"):
xray_backends[region] = XRayBackend()
for region in Session().get_available_regions("xray", partition_name="aws-us-gov"):
xray_backends[region] = XRayBackend()
for region in Session().get_available_regions("xray", partition_name="aws-cn"):
xray_backends[region] = XRayBackend()

View File

@ -1,7 +1,7 @@
"""{{ service_class }}Backend class with methods for supported APIs.""" """{{ service_class }}Backend class with methods for supported APIs."""
from boto3 import Session
from moto.core import BaseBackend, BaseModel from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
class {{ service_class }}Backend(BaseBackend): class {{ service_class }}Backend(BaseBackend):
@ -19,14 +19,4 @@ class {{ service_class }}Backend(BaseBackend):
# add methods from here # add methods from here
{{ escaped_service }}_backends = {} {{ escaped_service }}_backends = BackendDict({{ service_class }}Backend, "{{ service }}")
for available_region in Session().get_available_regions("{{ service }}"):
{{ escaped_service }}_backends[available_region] = {{ service_class }}Backend(available_region)
for available_region in Session().get_available_regions(
"{{ service }}", partition_name="aws-us-gov"
):
{{ escaped_service }}_backends[available_region] = {{ service_class }}Backend(available_region)
for available_region in Session().get_available_regions(
"{{ service }}", partition_name="aws-cn"
):
{{ escaped_service }}_backends[available_region] = {{ service_class }}Backend(available_region)

View File

@ -331,20 +331,28 @@ def test_list_trails():
all_trails = client.list_trails()["Trails"] all_trails = client.list_trails()["Trails"]
all_trails.should.have.length_of(3) all_trails.should.have.length_of(3)
for trail in all_trails:
set(trail.keys()).should.equal({"TrailARN", "Name", "HomeRegion"})
all_trails[0]["TrailARN"].should.equal(trail2["TrailARN"]) all_trails.should.contain(
all_trails[0]["Name"].should.equal(trail2["Name"]) {
all_trails[0]["HomeRegion"].should.equal("ap-southeast-2") "TrailARN": trail1["TrailARN"],
"Name": trail1["Name"],
all_trails[1]["TrailARN"].should.equal(trail3["TrailARN"]) "HomeRegion": "us-east-1",
all_trails[1]["Name"].should.equal(trail3["Name"]) }
all_trails[1]["HomeRegion"].should.equal("eu-west-1") )
all_trails.should.contain(
all_trails[2]["TrailARN"].should.equal(trail1["TrailARN"]) {
all_trails[2]["Name"].should.equal(trail1["Name"]) "TrailARN": trail2["TrailARN"],
all_trails[2]["HomeRegion"].should.equal("us-east-1") "Name": trail2["Name"],
"HomeRegion": "ap-southeast-2",
}
)
all_trails.should.contain(
{
"TrailARN": trail3["TrailARN"],
"Name": trail3["Name"],
"HomeRegion": "eu-west-1",
}
)
@mock_cloudtrail @mock_cloudtrail

View File

@ -0,0 +1,44 @@
import boto3
import mock
import os
import pytest
from moto import mock_sns, settings
from unittest import SkipTest
@mock_sns
def test_use_invalid_region():
if settings.TEST_SERVER_MODE:
raise SkipTest("ServerMode will throw different errors")
client = boto3.client("sns", region_name="any-region")
with pytest.raises(KeyError) as exc:
client.list_platform_applications()
str(exc.value).should.contain("any-region")
@mock_sns
@mock.patch.dict(os.environ, {"AWS_DEFAULT_REGION": "us-east-2"})
def test_use_region_from_env():
client = boto3.client("sns")
client.list_platform_applications()["PlatformApplications"].should.equal([])
@mock_sns
@mock.patch.dict(os.environ, {"AWS_DEFAULT_REGION": "any-region"})
def test_use_unknown_region_from_env():
if settings.TEST_SERVER_MODE:
raise SkipTest("Cannot set environemnt variables in ServerMode")
client = boto3.client("sns")
with pytest.raises(KeyError) as exc:
client.list_platform_applications()
str(exc.value).should.contain("any-region")
@mock_sns
@mock.patch.dict(os.environ, {"AWS_DEFAULT_REGION": "any-region"})
@mock.patch.dict(os.environ, {"MOTO_ALLOW_NONEXISTENT_REGION": "trUe"})
def test_use_unknown_region_from_env_but_allow_it():
if settings.TEST_SERVER_MODE:
raise SkipTest("Cannot set environemnt variables in ServerMode")
client = boto3.client("sns")
client.list_platform_applications()["PlatformApplications"].should.equal([])

View File

@ -4,7 +4,6 @@ import boto.ec2.elb
import boto3 import boto3
import pytest import pytest
import sure # noqa # pylint: disable=unused-import import sure # noqa # pylint: disable=unused-import
from boto3 import Session
from botocore.exceptions import ClientError from botocore.exceptions import ClientError
from moto import mock_ec2_deprecated, mock_autoscaling_deprecated, mock_elb_deprecated from moto import mock_ec2_deprecated, mock_autoscaling_deprecated, mock_elb_deprecated
@ -16,19 +15,6 @@ from uuid import uuid4
from .test_instances import retrieve_all_instances from .test_instances import retrieve_all_instances
def test_use_boto_regions():
boto_regions = set()
for region in Session().get_available_regions("ec2"):
boto_regions.add(region)
for region in Session().get_available_regions("ec2", partition_name="aws-us-gov"):
boto_regions.add(region)
for region in Session().get_available_regions("ec2", partition_name="aws-cn"):
boto_regions.add(region)
moto_regions = set(ec2_backends)
moto_regions.should.equal(boto_regions)
def add_servers_to_region(ami_id, count, region): def add_servers_to_region(ami_id, count, region):
conn = boto.ec2.connect_to_region(region) conn = boto.ec2.connect_to_region(region)
for _ in range(count): for _ in range(count):