Cleanup multi-region support for ELB, SQS, Cloudformation, EC2, Autoscaling.

This commit is contained in:
Steve Pulec 2014-11-15 13:34:52 -05:00
commit bd847bd941
16 changed files with 184 additions and 90 deletions

View file

@ -1,3 +1,10 @@
from __future__ import unicode_literals
from .models import cloudformation_backend
mock_cloudformation = cloudformation_backend.decorator
from .models import cloudformation_backends, cloudformation_backend # flake8: noqa
from ..core.models import MockAWS
def mock_cloudformation(func=None):
if func:
return MockAWS(cloudformation_backends)(func)
else:
return MockAWS(cloudformation_backends)

View file

@ -1,6 +1,7 @@
from __future__ import unicode_literals
import json
import boto.cloudformation
from moto.core import BaseBackend
from .parsing import ResourceMap, OutputMap
@ -9,9 +10,10 @@ from .exceptions import ValidationError
class FakeStack(object):
def __init__(self, stack_id, name, template, notification_arns=None):
def __init__(self, stack_id, name, template, region_name, notification_arns=None):
self.stack_id = stack_id
self.name = name
self.region_name = region_name
self.notification_arns = notification_arns if notification_arns else []
self.template = template
self.status = 'CREATE_COMPLETE'
@ -19,7 +21,7 @@ class FakeStack(object):
template_dict = json.loads(self.template)
self.description = template_dict.get('Description')
self.resource_map = ResourceMap(stack_id, name, template_dict)
self.resource_map = ResourceMap(stack_id, name, region_name, template_dict)
self.resource_map.create()
self.output_map = OutputMap(self.resource_map, template_dict)
@ -40,9 +42,15 @@ class CloudFormationBackend(BaseBackend):
self.stacks = {}
self.deleted_stacks = {}
def create_stack(self, name, template, notification_arns=None):
def create_stack(self, name, template, region_name, notification_arns=None):
stack_id = generate_stack_id(name)
new_stack = FakeStack(stack_id=stack_id, name=name, template=template, notification_arns=notification_arns)
new_stack = FakeStack(
stack_id=stack_id,
name=name,
template=template,
region_name=region_name,
notification_arns=notification_arns,
)
self.stacks[stack_id] = new_stack
return new_stack
@ -90,4 +98,8 @@ class CloudFormationBackend(BaseBackend):
self.delete_stack(stack_to_delete.stack_id)
cloudformation_backend = CloudFormationBackend()
cloudformation_backends = {}
for region in boto.cloudformation.regions():
cloudformation_backends[region.name] = CloudFormationBackend()
cloudformation_backend = cloudformation_backends['us-east-1']

View file

@ -120,7 +120,7 @@ def resource_name_property_from_type(resource_type):
return NAME_TYPE_MAP.get(resource_type)
def parse_resource(logical_id, resource_json, resources_map):
def parse_resource(logical_id, resource_json, resources_map, region_name):
resource_type = resource_json['Type']
resource_class = resource_class_from_type(resource_type)
if not resource_class:
@ -142,7 +142,7 @@ def parse_resource(logical_id, resource_json, resources_map):
logical_id,
random_suffix())
resource = resource_class.create_from_cloudformation_json(resource_name, resource_json)
resource = resource_class.create_from_cloudformation_json(resource_name, resource_json, region_name)
resource.type = resource_type
resource.logical_resource_id = logical_id
return resource
@ -164,9 +164,10 @@ class ResourceMap(collections.Mapping):
each resources is passed this lazy map that it can grab dependencies from.
"""
def __init__(self, stack_id, stack_name, template):
def __init__(self, stack_id, stack_name, region_name, template):
self._template = template
self._resource_json_map = template['Resources']
self._region_name = region_name
# Create the default resources
self._parsed_resources = {
@ -183,7 +184,7 @@ class ResourceMap(collections.Mapping):
return self._parsed_resources[resource_logical_id]
else:
resource_json = self._resource_json_map.get(resource_logical_id)
new_resource = parse_resource(resource_logical_id, resource_json, self)
new_resource = parse_resource(resource_logical_id, resource_json, self, self._region_name)
self._parsed_resources[resource_logical_id] = new_resource
return new_resource

View file

@ -4,19 +4,24 @@ import json
from jinja2 import Template
from moto.core.responses import BaseResponse
from .models import cloudformation_backend
from .models import cloudformation_backends
class CloudFormationResponse(BaseResponse):
@property
def cloudformation_backend(self):
return cloudformation_backends[self.region]
def create_stack(self):
stack_name = self._get_param('StackName')
stack_body = self._get_param('TemplateBody')
stack_notification_arns = self._get_multi_param('NotificationARNs.member')
stack = cloudformation_backend.create_stack(
stack = self.cloudformation_backend.create_stack(
name=stack_name,
template=stack_body,
region_name=self.region,
notification_arns=stack_notification_arns
)
stack_body = {
@ -32,34 +37,34 @@ class CloudFormationResponse(BaseResponse):
stack_name_or_id = None
if self._get_param('StackName'):
stack_name_or_id = self.querystring.get('StackName')[0]
stacks = cloudformation_backend.describe_stacks(stack_name_or_id)
stacks = self.cloudformation_backend.describe_stacks(stack_name_or_id)
template = Template(DESCRIBE_STACKS_TEMPLATE)
return template.render(stacks=stacks)
def describe_stack_resources(self):
stack_name = self._get_param('StackName')
stack = cloudformation_backend.get_stack(stack_name)
stack = self.cloudformation_backend.get_stack(stack_name)
template = Template(LIST_STACKS_RESOURCES_RESPONSE)
return template.render(stack=stack)
def list_stacks(self):
stacks = cloudformation_backend.list_stacks()
stacks = self.cloudformation_backend.list_stacks()
template = Template(LIST_STACKS_RESPONSE)
return template.render(stacks=stacks)
def get_template(self):
name_or_stack_id = self.querystring.get('StackName')[0]
stack = cloudformation_backend.get_stack(name_or_stack_id)
stack = self.cloudformation_backend.get_stack(name_or_stack_id)
return stack.template
# def update_stack(self):
# stack_name = self._get_param('StackName')
# stack_body = self._get_param('TemplateBody')
# stack = cloudformation_backend.update_stack(
# stack = self.cloudformation_backend.update_stack(
# name=stack_name,
# template=stack_body,
# )
@ -75,7 +80,7 @@ class CloudFormationResponse(BaseResponse):
def delete_stack(self):
name_or_stack_id = self.querystring.get('StackName')[0]
cloudformation_backend.delete_stack(name_or_stack_id)
self.cloudformation_backend.delete_stack(name_or_stack_id)
return json.dumps({
'DeleteStackResponse': {
'DeleteStackResult': {},