Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Mock region #4699

Merged
merged 7 commits into from
Dec 24, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/docs/faq.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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 />`
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"
1 change: 1 addition & 0 deletions docs/docs/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,7 @@ Here is an example:
os.environ['AWS_SECRET_ACCESS_KEY'] = 'testing'
os.environ['AWS_SECURITY_TOKEN'] = 'testing'
os.environ['AWS_SESSION_TOKEN'] = 'testing'
os.environ['AWS_DEFAULT_REGION'] = 'us-east-1'

@pytest.fixture(scope='function')
def s3(aws_credentials):
Expand Down
6 changes: 2 additions & 4 deletions moto/acm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import datetime
from moto.core import BaseBackend, BaseModel
from moto.core.exceptions import AWSError
from moto.ec2 import ec2_backends
from moto.core.utils import BackendDict
from moto import settings

from .utils import make_arn_for_certificate
Expand Down Expand Up @@ -559,6 +559,4 @@ def export_certificate(self, certificate_arn, passphrase):
return certificate, certificate_chain, private_key


acm_backends = {}
for region, ec2_backend in ec2_backends.items():
acm_backends[region] = AWSCertificateManagerBackend(region)
acm_backends = BackendDict(AWSCertificateManagerBackend, "ec2")
16 changes: 2 additions & 14 deletions moto/apigateway/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,16 +8,14 @@

import time

from boto3.session import Session

try:
from urlparse import urlparse
except ImportError:
from urllib.parse import urlparse
import responses
from moto.core import ACCOUNT_ID, BaseBackend, BaseModel, CloudFormationModel
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.http_parser import TypeHttpParser
from .integration_parsers.unknown_parser import TypeUnknownParser
Expand Down Expand Up @@ -1819,14 +1817,4 @@ def delete_base_path_mapping(self, domain_name, base_path):
self.base_path_mappings[domain_name].pop(base_path)


apigateway_backends = {}
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)
apigateway_backends = BackendDict(APIGatewayBackend, "apigateway")
1 change: 0 additions & 1 deletion moto/applicationautoscaling/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .models import applicationautoscaling_backends
from ..core.models import base_decorator

applicationautoscaling_backend = applicationautoscaling_backends["us-east-1"]
mock_applicationautoscaling = base_decorator(applicationautoscaling_backends)
14 changes: 5 additions & 9 deletions moto/applicationautoscaling/models.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from moto.core import BaseBackend, BaseModel
from moto.core.utils import BackendDict
from moto.ecs import ecs_backends
from .exceptions import AWSValidationException
from collections import OrderedDict
Expand Down Expand Up @@ -58,18 +59,17 @@ class ScalableDimensionValueSet(Enum):


class ApplicationAutoscalingBackend(BaseBackend):
def __init__(self, region, ecs):
def __init__(self, region):
super().__init__()
self.region = region
self.ecs_backend = ecs
self.ecs_backend = ecs_backends[region]
self.targets = OrderedDict()
self.policies = {}

def reset(self):
region = self.region
ecs = self.ecs_backend
self.__dict__ = {}
self.__init__(region, ecs)
self.__init__(region)

@staticmethod
def default_vpc_endpoint_service(service_region, zones):
Expand Down Expand Up @@ -356,8 +356,4 @@ def formulate_key(service_namespace, resource_id, scalable_dimension, policy_nam
)


applicationautoscaling_backends = {}
for region_name, ecs_backend in ecs_backends.items():
applicationautoscaling_backends[region_name] = ApplicationAutoscalingBackend(
region_name, ecs_backend
)
applicationautoscaling_backends = BackendDict(ApplicationAutoscalingBackend, "ec2")
10 changes: 2 additions & 8 deletions moto/athena/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import time

from boto3 import Session
from moto.core import BaseBackend, BaseModel, ACCOUNT_ID
from moto.core.utils import BackendDict

from uuid import uuid4

Expand Down Expand Up @@ -143,10 +143,4 @@ def get_named_query(self, query_id):
return self.named_queries[query_id] if query_id in self.named_queries else None


athena_backends = {}
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)
athena_backends = BackendDict(AthenaBackend, "athena")
24 changes: 9 additions & 15 deletions moto/autoscaling/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from collections import OrderedDict
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.elb import elb_backends
from moto.elbv2 import elbv2_backends
Expand Down Expand Up @@ -633,22 +633,20 @@ def append_target_groups(self, target_group_arns):


class AutoScalingBackend(BaseBackend):
def __init__(self, ec2_backend, elb_backend, elbv2_backend):
def __init__(self, region_name):
self.autoscaling_groups = OrderedDict()
self.launch_configurations = OrderedDict()
self.policies = {}
self.lifecycle_hooks = {}
self.ec2_backend = ec2_backend
self.elb_backend = elb_backend
self.elbv2_backend = elbv2_backend
self.region = self.elbv2_backend.region_name
self.ec2_backend = ec2_backends[region_name]
self.elb_backend = elb_backends[region_name]
self.elbv2_backend = elbv2_backends[region_name]
self.region = region_name

def reset(self):
ec2_backend = self.ec2_backend
elb_backend = self.elb_backend
elbv2_backend = self.elbv2_backend
region = self.region
self.__dict__ = {}
self.__init__(ec2_backend, elb_backend, elbv2_backend)
self.__init__(region)

@staticmethod
def default_vpc_endpoint_service(service_region, zones):
Expand Down Expand Up @@ -1245,8 +1243,4 @@ def describe_tags(self, filters):
return tags


autoscaling_backends = {}
for region, ec2_backend in ec2_backends.items():
autoscaling_backends[region] = AutoScalingBackend(
ec2_backend, elb_backends[region], elbv2_backends[region]
)
autoscaling_backends = BackendDict(AutoScalingBackend, "ec2")
12 changes: 2 additions & 10 deletions moto/awslambda/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@
import weakref
import requests.exceptions

from boto3 import Session

from moto.awslambda.policy import Policy
from moto.core import BaseBackend, CloudFormationModel
from moto.core.exceptions import RESTError
from moto.iam.models import iam_backend
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.logs.models import logs_backends
from moto.s3.exceptions import MissingBucket, MissingKey
Expand Down Expand Up @@ -1451,10 +1449,4 @@ def do_validate_s3():
return os.environ.get("VALIDATE_LAMBDA_S3", "") in ["", "1", "true"]


lambda_backends = {}
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)
lambda_backends = BackendDict(LambdaBackend, "lambda")
11 changes: 2 additions & 9 deletions moto/batch/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import docker
import threading
import dateutil.parser
from boto3 import Session

from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.iam import iam_backends
Expand All @@ -26,7 +25,7 @@
from moto.ec2.models import INSTANCE_TYPES as EC2_INSTANCE_TYPES
from moto.iam.exceptions import IAMNotFoundException
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 ..utilities.tagging_service import TaggingService

Expand Down Expand Up @@ -1475,10 +1474,4 @@ def terminate_job(self, job_id, reason):
job.terminate(reason)


batch_backends = {}
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)
batch_backends = BackendDict(BatchBackend, "batch")
16 changes: 3 additions & 13 deletions moto/cloudformation/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import yaml
import uuid

from boto3 import Session
from collections import OrderedDict
from yaml.parser import ParserError # pylint:disable=c-extension-no-member
from yaml.scanner import ScannerError # pylint:disable=c-extension-no-member
Expand All @@ -13,6 +12,7 @@
from moto.core.utils import (
iso_8601_datetime_with_milliseconds,
iso_8601_datetime_without_milliseconds,
BackendDict,
)
from moto.sns.models import sns_backends

Expand Down Expand Up @@ -518,7 +518,7 @@ def filter_stacks(all_stacks, status_filter):


class CloudFormationBackend(BaseBackend):
def __init__(self):
def __init__(self, region=None):
self.stacks = OrderedDict()
self.stacksets = OrderedDict()
self.deleted_stacks = {}
Expand Down Expand Up @@ -896,14 +896,4 @@ def _validate_export_uniqueness(self, stack):
)


cloudformation_backends = {}
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()
cloudformation_backends = BackendDict(CloudFormationBackend, "cloudformation")
15 changes: 2 additions & 13 deletions moto/cloudtrail/models.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import re
import time

from boto3 import Session
from datetime import datetime
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 (
S3BucketDoesNotExistException,
InsufficientSnsTopicPolicyException,
Expand Down Expand Up @@ -261,14 +260,4 @@ def reset(self):
self.__init__(region_name)


cloudtrail_backends = {}
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)
cloudtrail_backends = BackendDict(CloudTrailBackend, "cloudtrail")
1 change: 0 additions & 1 deletion moto/cloudwatch/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from .models import cloudwatch_backends
from ..core.models import base_decorator, deprecated_base_decorator

cloudwatch_backend = cloudwatch_backends["us-east-1"]
mock_cloudwatch = base_decorator(cloudwatch_backends)
mock_cloudwatch_deprecated = deprecated_base_decorator(cloudwatch_backends)
13 changes: 2 additions & 11 deletions moto/cloudwatch/models.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import json

from boto3 import Session

from moto.core import (
BaseBackend,
BaseModel,
Expand All @@ -10,6 +8,7 @@
from moto.core.utils import (
iso_8601_datetime_without_milliseconds,
iso_8601_datetime_with_nanoseconds,
BackendDict,
)
from datetime import datetime, timedelta
from dateutil.tz import tzutc
Expand Down Expand Up @@ -680,12 +679,4 @@ def _get_paginated(self, metrics):
return None, metrics


cloudwatch_backends = {}
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)
cloudwatch_backends = BackendDict(CloudWatchBackend, "cloudwatch")
9 changes: 3 additions & 6 deletions moto/codecommit/models.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from boto3 import Session
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 moto.core import ACCOUNT_ID
from .exceptions import RepositoryDoesNotExistException, RepositoryNameExistsException
Expand Down Expand Up @@ -33,7 +32,7 @@ def __init__(self, region, repository_description, repository_name):


class CodeCommitBackend(BaseBackend):
def __init__(self):
def __init__(self, region=None):
self.repositories = {}

@staticmethod
Expand Down Expand Up @@ -71,6 +70,4 @@ def delete_repository(self, repository_name):
return None


codecommit_backends = {}
for region in Session().get_available_regions("codecommit"):
codecommit_backends[region] = CodeCommitBackend()
codecommit_backends = BackendDict(CodeCommitBackend, "codecommit")