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
parent b39861052b
commit bd847bd941
16 changed files with 184 additions and 90 deletions

View File

@ -47,12 +47,13 @@ class FakeLaunchConfiguration(object):
self.block_device_mapping_dict = block_device_mapping_dict
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
instance_profile_name = properties.get("IamInstanceProfile")
config = default_autoscaling_backend.create_launch_configuration(
backend = autoscaling_backends[region_name]
config = backend.create_launch_configuration(
name=resource_name,
image_id=properties.get("ImageId"),
key_name=properties.get("KeyName"),
@ -128,13 +129,14 @@ class FakeAutoScalingGroup(object):
self.set_desired_capacity(desired_capacity)
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
launch_config_name = properties.get("LaunchConfigurationName")
load_balancer_names = properties.get("LoadBalancerNames", [])
group = default_autoscaling_backend.create_autoscaling_group(
backend = autoscaling_backends[region_name]
group = backend.create_autoscaling_group(
name=resource_name,
availability_zones=properties.get("AvailabilityZones", []),
desired_capacity=properties.get("DesiredCapacity"),

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': {},

View File

@ -165,12 +165,13 @@ class NetworkInterface(object):
self._group_set.append(group)
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
security_group_ids = properties.get('SecurityGroups', [])
subnet_id = properties['SubnetId']
ec2_backend = ec2_backends[region_name]
subnet = ec2_backend.get_subnet(subnet_id)
private_ip_address = properties.get('PrivateIpAddress', None)
@ -324,9 +325,10 @@ class Instance(BotoInstance, TaggedEC2Resource):
associate_public_ip=kwargs.get("associate_public_ip"))
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
ec2_backend = ec2_backends[region_name]
security_group_ids = properties.get('SecurityGroups', [])
group_names = [ec2_backend.get_security_group_from_id(group_id).name for group_id in security_group_ids]
@ -975,9 +977,10 @@ class SecurityGroup(object):
self.vpc_id = vpc_id
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
ec2_backend = ec2_backends[region_name]
vpc_id = properties.get('VpcId')
security_group = ec2_backend.create_security_group(
name=resource_name,
@ -1203,12 +1206,13 @@ class VolumeAttachment(object):
self.device = device
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
instance_id = properties['InstanceId']
volume_id = properties['VolumeId']
ec2_backend = ec2_backends[region_name]
attachment = ec2_backend.attach_volume(
volume_id=volume_id,
instance_id=instance_id,
@ -1226,9 +1230,10 @@ class Volume(TaggedEC2Resource):
self.ec2_backend = ec2_backend
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
ec2_backend = ec2_backends[region_name]
volume = ec2_backend.create_volume(
size=properties.get('Size'),
zone_name=properties.get('AvailabilityZone'),
@ -1360,9 +1365,10 @@ class VPC(TaggedEC2Resource):
self.state = 'available'
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
ec2_backend = ec2_backends[region_name]
vpc = ec2_backend.create_vpc(
cidr_block=properties['CidrBlock'],
)
@ -1479,9 +1485,10 @@ class VPCPeeringConnection(TaggedEC2Resource):
self._status = VPCPeeringConnectionStatus()
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
ec2_backend = ec2_backends[region_name]
vpc = ec2_backend.get_vpc(properties['VpcId'])
peer_vpc = ec2_backend.get_vpc(properties['PeerVpcId'])
@ -1543,10 +1550,11 @@ class Subnet(TaggedEC2Resource):
self.cidr_block = cidr_block
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
vpc_id = properties['VpcId']
ec2_backend = ec2_backends[region_name]
subnet = ec2_backend.create_subnet(
vpc_id=vpc_id,
cidr_block=properties['CidrBlock']
@ -1615,12 +1623,13 @@ class SubnetRouteTableAssociation(object):
self.subnet_id = subnet_id
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
route_table_id = properties['RouteTableId']
subnet_id = properties['SubnetId']
ec2_backend = ec2_backends[region_name]
subnet_association = ec2_backend.create_subnet_association(
route_table_id=route_table_id,
subnet_id=subnet_id,
@ -1649,10 +1658,11 @@ class RouteTable(TaggedEC2Resource):
self.routes = {}
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
vpc_id = properties['VpcId']
ec2_backend = ec2_backends[region_name]
route_table = ec2_backend.create_route_table(
vpc_id=vpc_id,
)
@ -1781,7 +1791,7 @@ class Route(object):
self.vpc_pcx = vpc_pcx
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
gateway_id = properties.get('GatewayId')
@ -1790,6 +1800,7 @@ class Route(object):
pcx_id = properties.get('VpcPeeringConnectionId')
route_table_id = properties['RouteTableId']
ec2_backend = ec2_backends[region_name]
route_table = ec2_backend.create_route(
route_table_id=route_table_id,
destination_cidr_block=properties['DestinationCidrBlock'],
@ -1860,7 +1871,8 @@ class InternetGateway(TaggedEC2Resource):
self.vpc = None
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
ec2_backend = ec2_backends[region_name]
return ec2_backend.create_internet_gateway()
@property
@ -1935,9 +1947,10 @@ class VPCGatewayAttachment(object):
self.vpc_id = vpc_id
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
ec2_backend = ec2_backends[region_name]
return ec2_backend.create_vpc_gateway_attachment(
gateway_id=properties['InternetGatewayId'],
vpc_id=properties['VpcId'],
@ -2056,7 +2069,9 @@ class ElasticAddress(object):
self.association_id = None
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
ec2_backend = ec2_backends[region_name]
properties = cloudformation_json.get('Properties')
instance_id = None
if properties:

View File

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

View File

@ -1,4 +1,6 @@
from __future__ import unicode_literals
import boto.ec2.elb
from moto.core import BaseBackend
@ -38,9 +40,10 @@ class FakeLoadBalancer(object):
self.listeners.append(listener)
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
elb_backend = elb_backends[region_name]
new_elb = elb_backend.create_load_balancer(
name=properties.get('LoadBalancerName', resource_name),
zones=properties.get('AvailabilityZones'),
@ -148,4 +151,9 @@ class ELBBackend(BaseBackend):
load_balancer.instance_ids = new_instance_ids
return load_balancer
elb_backend = ELBBackend()
elb_backends = {}
for region in boto.ec2.elb.regions():
elb_backends[region.name] = ELBBackend()
elb_backend = elb_backends['us-east-1']

View File

@ -2,11 +2,15 @@ from __future__ import unicode_literals
from jinja2 import Template
from moto.core.responses import BaseResponse
from .models import elb_backend
from .models import elb_backends
class ELBResponse(BaseResponse):
@property
def elb_backend(self):
return elb_backends[self.region]
def create_load_balancer(self):
"""
u'Scheme': [u'internet-facing'],
@ -26,7 +30,7 @@ class ELBResponse(BaseResponse):
ports.append([protocol, lb_port, instance_port, ssl_certificate_id])
port_index += 1
elb_backend.create_load_balancer(
self.elb_backend.create_load_balancer(
name=load_balancer_name,
zones=availability_zones,
ports=ports,
@ -49,14 +53,14 @@ class ELBResponse(BaseResponse):
ports.append([protocol, lb_port, instance_port, ssl_certificate_id])
port_index += 1
elb_backend.create_load_balancer_listeners(name=load_balancer_name, ports=ports)
self.elb_backend.create_load_balancer_listeners(name=load_balancer_name, ports=ports)
template = Template(CREATE_LOAD_BALANCER_LISTENERS_TEMPLATE)
return template.render()
def describe_load_balancers(self):
names = [value[0] for key, value in self.querystring.items() if "LoadBalancerNames.member" in key]
load_balancers = elb_backend.describe_load_balancers(names)
load_balancers = self.elb_backend.describe_load_balancers(names)
template = Template(DESCRIBE_LOAD_BALANCERS_TEMPLATE)
return template.render(load_balancers=load_balancers)
@ -73,18 +77,18 @@ class ELBResponse(BaseResponse):
port_index += 1
ports.append(int(port))
elb_backend.delete_load_balancer_listeners(load_balancer_name, ports)
self.elb_backend.delete_load_balancer_listeners(load_balancer_name, ports)
template = Template(DELETE_LOAD_BALANCER_LISTENERS)
return template.render()
def delete_load_balancer(self):
load_balancer_name = self.querystring.get('LoadBalancerName')[0]
elb_backend.delete_load_balancer(load_balancer_name)
self.elb_backend.delete_load_balancer(load_balancer_name)
template = Template(DELETE_LOAD_BALANCER_TEMPLATE)
return template.render()
def configure_health_check(self):
check = elb_backend.configure_health_check(
check = self.elb_backend.configure_health_check(
load_balancer_name=self.querystring.get('LoadBalancerName')[0],
timeout=self.querystring.get('HealthCheck.Timeout')[0],
healthy_threshold=self.querystring.get('HealthCheck.HealthyThreshold')[0],
@ -99,7 +103,7 @@ class ELBResponse(BaseResponse):
load_balancer_name = self.querystring.get('LoadBalancerName')[0]
instance_ids = [value[0] for key, value in self.querystring.items() if "Instances.member" in key]
template = Template(REGISTER_INSTANCES_TEMPLATE)
load_balancer = elb_backend.register_instances(load_balancer_name, instance_ids)
load_balancer = self.elb_backend.register_instances(load_balancer_name, instance_ids)
return template.render(load_balancer=load_balancer)
def set_load_balancer_listener_sslcertificate(self):
@ -107,7 +111,7 @@ class ELBResponse(BaseResponse):
ssl_certificate_id = self.querystring['SSLCertificateId'][0]
lb_port = self.querystring['LoadBalancerPort'][0]
elb_backend.set_load_balancer_listener_sslcertificate(load_balancer_name, lb_port, ssl_certificate_id)
self.elb_backend.set_load_balancer_listener_sslcertificate(load_balancer_name, lb_port, ssl_certificate_id)
template = Template(SET_LOAD_BALANCER_SSL_CERTIFICATE)
return template.render()
@ -116,7 +120,7 @@ class ELBResponse(BaseResponse):
load_balancer_name = self.querystring.get('LoadBalancerName')[0]
instance_ids = [value[0] for key, value in self.querystring.items() if "Instances.member" in key]
template = Template(DEREGISTER_INSTANCES_TEMPLATE)
load_balancer = elb_backend.deregister_instances(load_balancer_name, instance_ids)
load_balancer = self.elb_backend.deregister_instances(load_balancer_name, instance_ids)
return template.render(load_balancer=load_balancer)
CREATE_LOAD_BALANCER_TEMPLATE = """<CreateLoadBalancerResult xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">

View File

@ -16,7 +16,7 @@ class Role(object):
self.policies = policies
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
return iam_backend.create_role(
@ -45,7 +45,7 @@ class InstanceProfile(object):
self.roles = roles if roles else []
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
role_ids = properties['Roles']

View File

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

View File

@ -5,6 +5,7 @@ import time
import re
from xml.sax.saxutils import escape
import boto.sqs
from moto.core import BaseBackend
from moto.core.utils import camelcase_to_underscores, get_random_message_id
@ -120,9 +121,10 @@ class Queue(object):
self.receive_message_wait_time_seconds = 0
@classmethod
def create_from_cloudformation_json(cls, resource_name, cloudformation_json):
def create_from_cloudformation_json(cls, resource_name, cloudformation_json, region_name):
properties = cloudformation_json['Properties']
sqs_backend = sqs_backends[region_name]
return sqs_backend.create_queue(
name=properties['QueueName'],
visibility_timeout=properties.get('VisibilityTimeout'),
@ -272,4 +274,8 @@ class SQSBackend(BaseBackend):
return
raise ReceiptHandleIsInvalid
sqs_backend = SQSBackend()
sqs_backends = {}
for region in boto.sqs.regions():
sqs_backends[region.name] = SQSBackend()
sqs_backend = sqs_backends['us-east-1']

View File

@ -4,7 +4,7 @@ from jinja2 import Template
from moto.core.responses import BaseResponse
from moto.core.utils import camelcase_to_underscores
from .utils import parse_message_attributes
from .models import sqs_backend
from .models import sqs_backends
from .exceptions import (
MessageAttributesInvalid,
MessageNotInflight,
@ -16,19 +16,23 @@ MAXIMUM_VISIBILTY_TIMEOUT = 43200
class QueuesResponse(BaseResponse):
@property
def sqs_backend(self):
return sqs_backends[self.region]
def create_queue(self):
visibility_timeout = None
if 'Attribute.1.Name' in self.querystring and self.querystring.get('Attribute.1.Name')[0] == 'VisibilityTimeout':
visibility_timeout = self.querystring.get("Attribute.1.Value")[0]
queue_name = self.querystring.get("QueueName")[0]
queue = sqs_backend.create_queue(queue_name, visibility_timeout=visibility_timeout)
queue = self.sqs_backend.create_queue(queue_name, visibility_timeout=visibility_timeout)
template = Template(CREATE_QUEUE_RESPONSE)
return template.render(queue=queue)
def get_queue_url(self):
queue_name = self.querystring.get("QueueName")[0]
queue = sqs_backend.get_queue(queue_name)
queue = self.sqs_backend.get_queue(queue_name)
if queue:
template = Template(GET_QUEUE_URL_RESPONSE)
return template.render(queue=queue)
@ -37,12 +41,17 @@ class QueuesResponse(BaseResponse):
def list_queues(self):
queue_name_prefix = self.querystring.get("QueueNamePrefix", [None])[0]
queues = sqs_backend.list_queues(queue_name_prefix)
queues = self.sqs_backend.list_queues(queue_name_prefix)
template = Template(LIST_QUEUES_RESPONSE)
return template.render(queues=queues)
class QueueResponse(BaseResponse):
@property
def sqs_backend(self):
return sqs_backends[self.region]
def change_message_visibility(self):
queue_name = self.path.split("/")[-1]
receipt_handle = self.querystring.get("ReceiptHandle")[0]
@ -54,7 +63,7 @@ class QueueResponse(BaseResponse):
), dict(status=400)
try:
sqs_backend.change_message_visibility(
self.sqs_backend.change_message_visibility(
queue_name=queue_name,
receipt_handle=receipt_handle,
visibility_timeout=visibility_timeout
@ -67,7 +76,7 @@ class QueueResponse(BaseResponse):
def get_queue_attributes(self):
queue_name = self.path.split("/")[-1]
queue = sqs_backend.get_queue(queue_name)
queue = self.sqs_backend.get_queue(queue_name)
template = Template(GET_QUEUE_ATTRIBUTES_RESPONSE)
return template.render(queue=queue)
@ -75,12 +84,12 @@ class QueueResponse(BaseResponse):
queue_name = self.path.split("/")[-1]
key = camelcase_to_underscores(self.querystring.get('Attribute.Name')[0])
value = self.querystring.get('Attribute.Value')[0]
sqs_backend.set_queue_attribute(queue_name, key, value)
self.sqs_backend.set_queue_attribute(queue_name, key, value)
return SET_QUEUE_ATTRIBUTE_RESPONSE
def delete_queue(self):
queue_name = self.path.split("/")[-1]
queue = sqs_backend.delete_queue(queue_name)
queue = self.sqs_backend.delete_queue(queue_name)
if not queue:
return "A queue with name {0} does not exist".format(queue_name), dict(status=404)
template = Template(DELETE_QUEUE_RESPONSE)
@ -101,7 +110,7 @@ class QueueResponse(BaseResponse):
return e.description, dict(status=e.status_code)
queue_name = self.path.split("/")[-1]
message = sqs_backend.send_message(
message = self.sqs_backend.send_message(
queue_name,
message,
message_attributes=message_attributes,
@ -137,7 +146,7 @@ class QueueResponse(BaseResponse):
message_user_id = self.querystring.get(message_user_id_key)[0]
delay_key = 'SendMessageBatchRequestEntry.{0}.DelaySeconds'.format(index)
delay_seconds = self.querystring.get(delay_key, [None])[0]
message = sqs_backend.send_message(queue_name, message_body[0], delay_seconds=delay_seconds)
message = self.sqs_backend.send_message(queue_name, message_body[0], delay_seconds=delay_seconds)
message.user_id = message_user_id
message_attributes = parse_message_attributes(self.querystring, base='SendMessageBatchRequestEntry.{0}.'.format(index), value_namespace='')
@ -153,7 +162,7 @@ class QueueResponse(BaseResponse):
def delete_message(self):
queue_name = self.path.split("/")[-1]
receipt_handle = self.querystring.get("ReceiptHandle")[0]
sqs_backend.delete_message(queue_name, receipt_handle)
self.sqs_backend.delete_message(queue_name, receipt_handle)
template = Template(DELETE_MESSAGE_RESPONSE)
return template.render()
@ -178,7 +187,7 @@ class QueueResponse(BaseResponse):
# Found all messages
break
sqs_backend.delete_message(queue_name, receipt_handle[0])
self.sqs_backend.delete_message(queue_name, receipt_handle[0])
message_user_id_key = 'DeleteMessageBatchRequestEntry.{0}.Id'.format(index)
message_user_id = self.querystring.get(message_user_id_key)[0]
@ -190,7 +199,7 @@ class QueueResponse(BaseResponse):
def receive_message(self):
queue_name = self.path.split("/")[-1]
message_count = int(self.querystring.get("MaxNumberOfMessages")[0])
messages = sqs_backend.receive_messages(queue_name, message_count)
messages = self.sqs_backend.receive_messages(queue_name, message_count)
template = Template(RECEIVE_MESSAGE_RESPONSE)
output = template.render(messages=messages)
return output

View File

@ -1,9 +1,12 @@
from __future__ import unicode_literals
import json
import boto
import boto.cloudformation
import sure # noqa
# Ensure 'assert_raises' context manager support for Python 2.6
import tests.backport_assert_raises
import tests.backport_assert_raises # noqa
from nose.tools import assert_raises
from moto import mock_cloudformation
@ -38,6 +41,18 @@ def test_create_stack():
stack.get_template().should.equal(dummy_template)
@mock_cloudformation
def test_creating_stacks_across_regions():
west1_conn = boto.cloudformation.connect_to_region("us-west-1")
west1_conn.create_stack("test_stack", template_body=dummy_template_json)
west2_conn = boto.cloudformation.connect_to_region("us-west-2")
west2_conn.create_stack("test_stack", template_body=dummy_template_json)
list(west1_conn.describe_stacks()).should.have.length_of(1)
list(west2_conn.describe_stacks()).should.have.length_of(1)
@mock_cloudformation
def test_create_stack_with_notification_arn():
conn = boto.connect_cloudformation()

View File

@ -2,6 +2,8 @@ from __future__ import unicode_literals
import json
import boto
import boto.cloudformation
import boto.ec2
import sure # noqa
from moto import (
@ -464,13 +466,13 @@ def test_iam_roles():
def test_single_instance_with_ebs_volume():
template_json = json.dumps(single_instance_with_ebs_volume.template)
conn = boto.connect_cloudformation()
conn = boto.cloudformation.connect_to_region("us-west-1")
conn.create_stack(
"test_stack",
template_body=template_json,
)
ec2_conn = boto.connect_ec2()
ec2_conn = boto.ec2.connect_to_region("us-west-1")
reservation = ec2_conn.get_all_instances()[0]
ec2_instance = reservation.instances[0]
@ -490,10 +492,7 @@ def test_classic_eip():
template_json = json.dumps(ec2_classic_eip.template)
conn = boto.connect_cloudformation()
conn.create_stack(
"test_stack",
template_body=template_json,
)
conn.create_stack("test_stack", template_body=template_json)
ec2_conn = boto.connect_ec2()
eip = ec2_conn.get_all_addresses()[0]
@ -509,10 +508,7 @@ def test_vpc_eip():
template_json = json.dumps(vpc_eip.template)
conn = boto.connect_cloudformation()
conn.create_stack(
"test_stack",
template_body=template_json,
)
conn.create_stack("test_stack", template_body=template_json)
ec2_conn = boto.connect_ec2()
eip = ec2_conn.get_all_addresses()[0]
@ -528,10 +524,7 @@ def test_fn_join():
template_json = json.dumps(fn_join.template)
conn = boto.connect_cloudformation()
conn.create_stack(
"test_stack",
template_body=template_json,
)
conn.create_stack("test_stack", template_body=template_json)
ec2_conn = boto.connect_ec2()
eip = ec2_conn.get_all_addresses()[0]

View File

@ -82,7 +82,7 @@ def test_parse_stack_resources():
stack_id="test_id",
name="test_stack",
template=dummy_template_json,
)
region_name='us-west-1')
stack.resource_map.should.have.length_of(1)
list(stack.resource_map.keys())[0].should.equal('Queue')
@ -101,7 +101,8 @@ def test_parse_stack_with_name_type_resource():
stack = FakeStack(
stack_id="test_id",
name="test_stack",
template=name_type_template_json)
template=name_type_template_json,
region_name='us-west-1')
stack.resource_map.should.have.length_of(1)
list(stack.resource_map.keys())[0].should.equal('Queue')
@ -113,7 +114,8 @@ def test_parse_stack_with_outputs():
stack = FakeStack(
stack_id="test_id",
name="test_stack",
template=output_type_template_json)
template=output_type_template_json,
region_name='us-west-1')
stack.output_map.should.have.length_of(1)
list(stack.output_map.keys())[0].should.equal('Output1')
@ -126,7 +128,8 @@ def test_parse_stack_with_get_attribute_outputs():
stack = FakeStack(
stack_id="test_id",
name="test_stack",
template=get_attribute_outputs_template_json)
template=get_attribute_outputs_template_json,
region_name='us-west-1')
stack.output_map.should.have.length_of(1)
list(stack.output_map.keys())[0].should.equal('Output1')
@ -137,4 +140,4 @@ def test_parse_stack_with_get_attribute_outputs():
def test_parse_stack_with_bad_get_attribute_outputs():
FakeStack.when.called_with(
"test_id", "test_stack", bad_output_template_json).should.throw(BotoServerError)
"test_id", "test_stack", bad_output_template_json, "us-west-1").should.throw(BotoServerError)