104 lines
3.4 KiB
Python
Raw Normal View History

from __future__ import unicode_literals
import json
import boto.cloudformation
from moto.core import BaseBackend
from .parsing import ResourceMap, OutputMap
from .utils import generate_stack_id
from .exceptions import ValidationError
class FakeStack(object):
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'
template_dict = json.loads(self.template)
self.description = template_dict.get('Description')
self.resource_map = ResourceMap(stack_id, name, region_name, template_dict)
self.resource_map.create()
self.output_map = OutputMap(self.resource_map, template_dict)
self.output_map.create()
@property
def stack_resources(self):
return self.resource_map.values()
@property
def stack_outputs(self):
return self.output_map.values()
class CloudFormationBackend(BaseBackend):
def __init__(self):
self.stacks = {}
self.deleted_stacks = {}
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,
region_name=region_name,
notification_arns=notification_arns,
)
self.stacks[stack_id] = new_stack
return new_stack
def describe_stacks(self, name_or_stack_id):
stacks = self.stacks.values()
if name_or_stack_id:
for stack in stacks:
if stack.name == name_or_stack_id or stack.stack_id == name_or_stack_id:
return [stack]
if self.deleted_stacks:
deleted_stacks = self.deleted_stacks.values()
for stack in deleted_stacks:
if stack.stack_id == name_or_stack_id:
return [stack]
raise ValidationError(name_or_stack_id)
else:
return stacks
def list_stacks(self):
return self.stacks.values()
def get_stack(self, name_or_stack_id):
if name_or_stack_id in self.stacks:
# Lookup by stack id
return self.stacks.get(name_or_stack_id)
else:
# Lookup by stack name
return [stack for stack in self.stacks.values() if stack.name == name_or_stack_id][0]
# def update_stack(self, name, template):
# stack = self.get_stack(name)
# stack.template = template
# return stack
def delete_stack(self, name_or_stack_id):
if name_or_stack_id in self.stacks:
# Delete by stack id
stack = self.stacks.pop(name_or_stack_id, None)
stack.status = 'DELETE_COMPLETE'
self.deleted_stacks[stack.stack_id] = stack
return self.stacks.pop(name_or_stack_id, None)
else:
# Delete by stack name
stack_to_delete = [stack for stack in self.stacks.values() if stack.name == name_or_stack_id][0]
self.delete_stack(stack_to_delete.stack_id)
cloudformation_backends = {}
for region in boto.cloudformation.regions():
cloudformation_backends[region.name] = CloudFormationBackend()