Skip to content

Commit

Permalink
Preparation for MultiAccount support (#5157)
Browse files Browse the repository at this point in the history
  • Loading branch information
bblommers authored Jun 4, 2022
1 parent 620f15a commit 79a2a9d
Show file tree
Hide file tree
Showing 155 changed files with 726 additions and 945 deletions.
20 changes: 9 additions & 11 deletions moto/acm/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -423,17 +423,11 @@ def __repr__(self):


class AWSCertificateManagerBackend(BaseBackend):
def __init__(self, region):
super().__init__()
self.region = region
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self._certificates = {}
self._idempotency_tokens = {}

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

@staticmethod
def default_vpc_endpoint_service(service_region, zones):
"""Default VPC endpoint service."""
Expand Down Expand Up @@ -491,12 +485,16 @@ def import_cert(self, certificate, private_key, chain=None, arn=None, tags=None)
else:
# Will reuse provided ARN
bundle = CertBundle(
certificate, private_key, chain=chain, region=self.region, arn=arn
certificate,
private_key,
chain=chain,
region=self.region_name,
arn=arn,
)
else:
# Will generate a random ARN
bundle = CertBundle(
certificate, private_key, chain=chain, region=self.region
certificate, private_key, chain=chain, region=self.region_name
)

self._certificates[bundle.arn] = bundle
Expand Down Expand Up @@ -548,7 +546,7 @@ def request_certificate(
return arn

cert = CertBundle.generate_cert(
domain_name, region=self.region, sans=subject_alt_names
domain_name, region=self.region_name, sans=subject_alt_names
)
if idempotency_token is not None:
self._set_idempotency_token_arn(idempotency_token, cert.arn)
Expand Down
10 changes: 2 additions & 8 deletions moto/apigateway/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1239,23 +1239,17 @@ class APIGatewayBackend(BaseBackend):
- This only works when using the decorators, not in ServerMode
"""

def __init__(self, region_name):
super().__init__()
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self.apis = {}
self.keys = {}
self.usage_plans = {}
self.usage_plan_keys = {}
self.domain_names = {}
self.models = {}
self.region_name = region_name
self.base_path_mappings = {}
self.vpc_links = {}

def reset(self):
region_name = self.region_name
self.__dict__ = {}
self.__init__(region_name)

def create_rest_api(
self,
name,
Expand Down
10 changes: 2 additions & 8 deletions moto/apigatewayv2/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -980,18 +980,12 @@ def to_json(self):
class ApiGatewayV2Backend(BaseBackend):
"""Implementation of ApiGatewayV2 APIs."""

def __init__(self, region_name=None):
self.region_name = region_name
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self.apis = dict()
self.vpc_links = dict()
self.tagger = TaggingService()

def reset(self):
"""Re-initialize all attributes for this instance."""
region_name = self.region_name
self.__dict__ = {}
self.__init__(region_name)

def create_api(
self,
api_key_selection_expression,
Expand Down
20 changes: 7 additions & 13 deletions moto/applicationautoscaling/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,19 +63,13 @@ class ScalableDimensionValueSet(Enum):


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

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

@staticmethod
def default_vpc_endpoint_service(service_region, zones):
"""Default VPC endpoint service."""
Expand All @@ -85,7 +79,7 @@ def default_vpc_endpoint_service(service_region, zones):

@property
def applicationautoscaling_backend(self):
return applicationautoscaling_backends[self.region]
return applicationautoscaling_backends[self.region_name]

def describe_scalable_targets(self, namespace, r_ids=None, dimension=None):
"""Describe scalable targets."""
Expand Down Expand Up @@ -166,7 +160,7 @@ def put_scaling_policy(
if policy_key in self.policies:
old_policy = self.policies[policy_key]
policy = FakeApplicationAutoscalingPolicy(
region_name=self.region,
region_name=self.region_name,
policy_name=policy_name,
service_namespace=service_namespace,
resource_id=resource_id,
Expand All @@ -176,7 +170,7 @@ def put_scaling_policy(
)
else:
policy = FakeApplicationAutoscalingPolicy(
region_name=self.region,
region_name=self.region_name,
policy_name=policy_name,
service_namespace=service_namespace,
resource_id=resource_id,
Expand Down Expand Up @@ -311,7 +305,7 @@ def put_scheduled_action(
start_time,
end_time,
scalable_target_action,
self.region,
self.region_name,
)
self.scheduled_actions.append(action)

Expand Down
10 changes: 2 additions & 8 deletions moto/appsync/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,17 +187,11 @@ def to_json(self):
class AppSyncBackend(BaseBackend):
"""Implementation of AppSync APIs."""

def __init__(self, region_name=None):
self.region_name = region_name
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self.graphql_apis = dict()
self.tagger = TaggingService()

def reset(self):
"""Re-initialize all attributes for this instance."""
region_name = self.region_name
self.__dict__ = {}
self.__init__(region_name)

def create_graphql_api(
self,
name,
Expand Down
5 changes: 2 additions & 3 deletions moto/athena/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,8 @@ def __init__(self, name, description, database, query_string, workgroup):
class AthenaBackend(BaseBackend):
region_name = None

def __init__(self, region_name=None):
if region_name is not None:
self.region_name = region_name
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self.work_groups = {}
self.executions = {}
self.named_queries = {}
Expand Down
17 changes: 6 additions & 11 deletions moto/autoscaling/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def __init__(

@property
def arn(self):
return f"arn:aws:autoscaling:{self.autoscaling_backend.region}:{get_account_id()}:scalingPolicy:c322761b-3172-4d56-9a21-0ed9d6161d67:autoScalingGroupName/{self.as_name}:policyName/{self.name}"
return f"arn:aws:autoscaling:{self.autoscaling_backend.region_name}:{get_account_id()}:scalingPolicy:c322761b-3172-4d56-9a21-0ed9d6161d67:autoScalingGroupName/{self.as_name}:policyName/{self.name}"

def execute(self):
if self.adjustment_type == "ExactCapacity":
Expand Down Expand Up @@ -303,7 +303,7 @@ def __init__(
self.ec2_backend = ec2_backend
self.name = name
self._id = str(uuid4())
self.region = self.autoscaling_backend.region
self.region = self.autoscaling_backend.region_name

self._set_azs_and_vpcs(availability_zones, vpc_zone_identifier)

Expand Down Expand Up @@ -650,20 +650,15 @@ def append_target_groups(self, target_group_arns):


class AutoScalingBackend(BaseBackend):
def __init__(self, region_name):
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self.autoscaling_groups = OrderedDict()
self.launch_configurations = OrderedDict()
self.policies = {}
self.lifecycle_hooks = {}
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):
region = self.region
self.__dict__ = {}
self.__init__(region)

@staticmethod
def default_vpc_endpoint_service(service_region, zones):
Expand Down Expand Up @@ -721,7 +716,7 @@ def create_launch_configuration(
ebs_optimized=ebs_optimized,
associate_public_ip_address=associate_public_ip_address,
block_device_mapping_dict=block_device_mappings,
region_name=self.region,
region_name=self.region_name,
metadata_options=metadata_options,
classic_link_vpc_id=classic_link_vpc_id,
classic_link_vpc_security_groups=classic_link_vpc_security_groups,
Expand Down Expand Up @@ -1273,4 +1268,4 @@ def describe_tags(self, filters):
return tags


autoscaling_backends = BackendDict(AutoScalingBackend, "ec2")
autoscaling_backends = BackendDict(AutoScalingBackend, "autoscaling")
9 changes: 2 additions & 7 deletions moto/awslambda/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1308,16 +1308,11 @@ def lambda_handler(event, context):
.. note:: When using the decorators, a Docker container cannot reach Moto, as it does not run as a server. Any boto3-invocations used within your Lambda will try to connect to AWS.
"""

def __init__(self, region_name):
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self._lambdas = LambdaStorage(region_name=region_name)
self._event_source_mappings = {}
self._layers = LayerStorage()
self.region_name = region_name

def reset(self):
region_name = self.region_name
self.__dict__ = {}
self.__init__(region_name)

@staticmethod
def default_vpc_endpoint_service(service_region, zones):
Expand Down
10 changes: 3 additions & 7 deletions moto/batch/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -825,9 +825,8 @@ class BatchBackend(BaseBackend):
With this decorator, jobs are simply marked as 'Success' without trying to execute any commands/scripts.
"""

def __init__(self, region_name=None):
super().__init__()
self.region_name = region_name
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
self.tagger = TaggingService()

self._compute_environments = {}
Expand Down Expand Up @@ -872,16 +871,13 @@ def logs_backend(self):
return logs_backends[self.region_name]

def reset(self):
region_name = self.region_name

for job in self._jobs.values():
if job.status not in ("FAILED", "SUCCEEDED"):
job.stop = True
# Try to join
job.join(0.2)

self.__dict__ = {}
self.__init__(region_name)
super().reset()

def get_compute_environment_by_arn(self, arn):
return self._compute_environments.get(arn)
Expand Down
5 changes: 1 addition & 4 deletions moto/batch_simple/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,9 @@
class BatchSimpleBackend(BaseBackend):
"""
Implements a Batch-Backend that does not use Docker containers. Submitted Jobs are simply marked as Success
Use the `@mock_batch_simple`-decorator to use this class.
Annotate your tests with `@mock_batch_simple`-decorator to use this Batch-implementation.
"""

def __init__(self, region_name=None):
self.region_name = region_name

@property
def backend(self):
return batch_backends[self.region_name]
Expand Down
3 changes: 1 addition & 2 deletions moto/budgets/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from .models import budgets_backend
from .models import budgets_backends
from ..core.models import base_decorator

budgets_backends = {"global": budgets_backend}
mock_budgets = base_decorator(budgets_backends)
9 changes: 6 additions & 3 deletions moto/budgets/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
from copy import deepcopy
from datetime import datetime
from moto.core import BaseBackend, BaseModel
from moto.core.utils import unix_time
from moto.core.utils import unix_time, BackendDict

from .exceptions import BudgetMissingLimit, DuplicateRecordException, NotFoundException

Expand Down Expand Up @@ -69,7 +69,8 @@ def get_notifications(self):
class BudgetsBackend(BaseBackend):
"""Implementation of Budgets APIs."""

def __init__(self):
def __init__(self, region_name, account_id):
super().__init__(region_name, account_id)
# {"account_id": {"budget_name": Budget}}
self.budgets = defaultdict(dict)

Expand Down Expand Up @@ -123,4 +124,6 @@ def describe_notifications_for_budget(self, account_id, budget_name):
return self.budgets[account_id][budget_name].get_notifications()


budgets_backend = BudgetsBackend()
budgets_backends = BackendDict(
BudgetsBackend, "budgets", use_boto3_regions=False, additional_regions=["global"]
)
Loading

0 comments on commit 79a2a9d

Please sign in to comment.