Basic ELB support
This commit is contained in:
parent
421a5e60af
commit
b40d3a5629
@ -3,6 +3,7 @@ logging.getLogger('boto').setLevel(logging.CRITICAL)
|
||||
|
||||
from .dynamodb import mock_dynamodb
|
||||
from .ec2 import mock_ec2
|
||||
from .elb import mock_elb
|
||||
from .s3 import mock_s3
|
||||
from .ses import mock_ses
|
||||
from .sqs import mock_sqs
|
||||
|
2
moto/elb/__init__.py
Normal file
2
moto/elb/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
from .models import elb_backend
|
||||
mock_elb = elb_backend.decorator
|
80
moto/elb/models.py
Normal file
80
moto/elb/models.py
Normal file
@ -0,0 +1,80 @@
|
||||
from moto.core import BaseBackend
|
||||
|
||||
|
||||
class FakeHealthCheck(object):
|
||||
def __init__(self, timeout, healthy_threshold, unhealthy_threshold,
|
||||
interval, target):
|
||||
self.timeout = timeout
|
||||
self.healthy_threshold = healthy_threshold
|
||||
self.unhealthy_threshold = unhealthy_threshold
|
||||
self.interval = interval
|
||||
self.target = target
|
||||
|
||||
|
||||
class FakeListener(object):
|
||||
def __init__(self, load_balancer_port, instance_port, protocol):
|
||||
self.load_balancer_port = load_balancer_port
|
||||
self.instance_port = instance_port
|
||||
self.protocol = protocol.upper()
|
||||
|
||||
|
||||
class FakeLoadBalancer(object):
|
||||
def __init__(self, name, zones, ports):
|
||||
self.name = name
|
||||
self.health_check = None
|
||||
self.instance_ids = []
|
||||
self.zones = zones
|
||||
self.listeners = []
|
||||
for protocol, lb_port, instance_port in ports:
|
||||
listener = FakeListener(
|
||||
protocol=protocol,
|
||||
load_balancer_port=lb_port,
|
||||
instance_port=instance_port,
|
||||
)
|
||||
self.listeners.append(listener)
|
||||
|
||||
|
||||
class ELBBackend(BaseBackend):
|
||||
|
||||
def __init__(self):
|
||||
self.load_balancers = {}
|
||||
|
||||
def create_load_balancer(self, name, zones, ports):
|
||||
new_load_balancer = FakeLoadBalancer(name=name, zones=zones, ports=ports)
|
||||
self.load_balancers[name] = new_load_balancer
|
||||
return new_load_balancer
|
||||
|
||||
def describe_load_balancers(self, names):
|
||||
balancers = self.load_balancers.values()
|
||||
if names:
|
||||
return [balancer for balancer in balancers if balancer.name in names]
|
||||
else:
|
||||
return balancers
|
||||
|
||||
def delete_load_balancer(self, load_balancer_name):
|
||||
self.load_balancers.pop(load_balancer_name, None)
|
||||
|
||||
def get_load_balancer(self, load_balancer_name):
|
||||
return self.load_balancers.get(load_balancer_name)
|
||||
|
||||
def configure_health_check(self, load_balancer_name, timeout,
|
||||
healthy_threshold, unhealthy_threshold, interval,
|
||||
target):
|
||||
check = FakeHealthCheck(timeout, healthy_threshold, unhealthy_threshold,
|
||||
interval, target)
|
||||
load_balancer = self.get_load_balancer(load_balancer_name)
|
||||
load_balancer.health_check = check
|
||||
return check
|
||||
|
||||
def register_instances(self, load_balancer_name, instance_ids):
|
||||
load_balancer = self.get_load_balancer(load_balancer_name)
|
||||
load_balancer.instance_ids.extend(instance_ids)
|
||||
return load_balancer
|
||||
|
||||
def deregister_instances(self, load_balancer_name, instance_ids):
|
||||
load_balancer = self.get_load_balancer(load_balancer_name)
|
||||
new_instance_ids = [instance_id for instance_id in load_balancer.instance_ids if instance_id not in instance_ids]
|
||||
load_balancer.instance_ids = new_instance_ids
|
||||
return load_balancer
|
||||
|
||||
elb_backend = ELBBackend()
|
179
moto/elb/responses.py
Normal file
179
moto/elb/responses.py
Normal file
@ -0,0 +1,179 @@
|
||||
from jinja2 import Template
|
||||
|
||||
from moto.core.responses import BaseResponse
|
||||
from .models import elb_backend
|
||||
|
||||
|
||||
class ELBResponse(BaseResponse):
|
||||
|
||||
def create_load_balancer(self):
|
||||
"""
|
||||
u'Scheme': [u'internet-facing'],
|
||||
"""
|
||||
load_balancer_name = self.querystring.get('LoadBalancerName')[0]
|
||||
availability_zones = [value[0] for key, value in self.querystring.items() if "AvailabilityZones.member" in key]
|
||||
ports = []
|
||||
port_index = 1
|
||||
while True:
|
||||
try:
|
||||
protocol = self.querystring['Listeners.member.{}.Protocol'.format(port_index)][0]
|
||||
except KeyError:
|
||||
break
|
||||
lb_port = self.querystring['Listeners.member.{}.LoadBalancerPort'.format(port_index)][0]
|
||||
instance_port = self.querystring['Listeners.member.{}.InstancePort'.format(port_index)][0]
|
||||
ports.append([protocol, lb_port, instance_port])
|
||||
port_index += 1
|
||||
elb_backend.create_load_balancer(
|
||||
name=load_balancer_name,
|
||||
zones=availability_zones,
|
||||
ports=ports,
|
||||
)
|
||||
template = Template(CREATE_LOAD_BALANCER_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)
|
||||
template = Template(DESCRIBE_LOAD_BALANCERS_TEMPLATE)
|
||||
return template.render(load_balancers=load_balancers)
|
||||
|
||||
def delete_load_balancer(self):
|
||||
load_balancer_name = self.querystring.get('LoadBalancerName')[0]
|
||||
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(
|
||||
load_balancer_name=self.querystring.get('LoadBalancerName')[0],
|
||||
timeout=self.querystring.get('HealthCheck.Timeout')[0],
|
||||
healthy_threshold=self.querystring.get('HealthCheck.HealthyThreshold')[0],
|
||||
unhealthy_threshold=self.querystring.get('HealthCheck.UnhealthyThreshold')[0],
|
||||
interval=self.querystring.get('HealthCheck.Interval')[0],
|
||||
target=self.querystring.get('HealthCheck.Target')[0],
|
||||
)
|
||||
template = Template(CONFIGURE_HEALTH_CHECK_TEMPLATE)
|
||||
return template.render(check=check)
|
||||
|
||||
def register_instances_with_load_balancer(self):
|
||||
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)
|
||||
return template.render(load_balancer=load_balancer)
|
||||
|
||||
def deregister_instances_from_load_balancer(self):
|
||||
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)
|
||||
return template.render(load_balancer=load_balancer)
|
||||
|
||||
CREATE_LOAD_BALANCER_TEMPLATE = """<CreateLoadBalancerResult xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<DNSName>tests.us-east-1.elb.amazonaws.com</DNSName>
|
||||
</CreateLoadBalancerResult>"""
|
||||
|
||||
DELETE_LOAD_BALANCER_TEMPLATE = """<DeleteLoadBalancerResult xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
</DeleteLoadBalancerResult>"""
|
||||
|
||||
DESCRIBE_LOAD_BALANCERS_TEMPLATE = """<DescribeLoadBalancersResponse xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<DescribeLoadBalancersResult>
|
||||
<LoadBalancerDescriptions>
|
||||
{% for load_balancer in load_balancers %}
|
||||
<member>
|
||||
<SecurityGroups>
|
||||
</SecurityGroups>
|
||||
<LoadBalancerName>{{ load_balancer.name }}</LoadBalancerName>
|
||||
<CreatedTime>2013-01-01T00:00:00.19000Z</CreatedTime>
|
||||
<HealthCheck>
|
||||
{% if load_balancer.health_check %}
|
||||
<Interval>{{ load_balancer.health_check.interval }}</Interval>
|
||||
<Target>{{ load_balancer.health_check.target }}</Target>
|
||||
<HealthyThreshold>{{ load_balancer.health_check.healthy_threshold }}</HealthyThreshold>
|
||||
<Timeout>{{ load_balancer.health_check.timeout }}</Timeout>
|
||||
<UnhealthyThreshold>{{ load_balancer.health_check.unhealthy_threshold }}</UnhealthyThreshold>
|
||||
{% endif %}
|
||||
</HealthCheck>
|
||||
<VPCId>vpc-56e10e3d</VPCId>
|
||||
<ListenerDescriptions>
|
||||
{% for listener in load_balancer.listeners %}
|
||||
<member>
|
||||
<PolicyNames>
|
||||
<member>AWSConsolePolicy-1</member>
|
||||
</PolicyNames>
|
||||
<Listener>
|
||||
<Protocol>{{ listener.protocol }}</Protocol>
|
||||
<LoadBalancerPort>{{ listener.load_balancer_port }}</LoadBalancerPort>
|
||||
<InstanceProtocol>{{ listener.protocol }}</InstanceProtocol>
|
||||
<InstancePort>{{ listener.instance_port }}</InstancePort>
|
||||
</Listener>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</ListenerDescriptions>
|
||||
<Instances>
|
||||
{% for instance_id in load_balancer.instance_ids %}
|
||||
<member>
|
||||
<InstanceId>{{ instance_id }}</InstanceId>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</Instances>
|
||||
<Policies>
|
||||
<AppCookieStickinessPolicies/>
|
||||
<OtherPolicies/>
|
||||
<LBCookieStickinessPolicies>
|
||||
<member>
|
||||
<PolicyName>AWSConsolePolicy-1</PolicyName>
|
||||
<CookieExpirationPeriod>30</CookieExpirationPeriod>
|
||||
</member>
|
||||
</LBCookieStickinessPolicies>
|
||||
</Policies>
|
||||
<AvailabilityZones>
|
||||
{% for zone in load_balancer.zones %}
|
||||
<member>{{ zone }}</member>
|
||||
{% endfor %}
|
||||
</AvailabilityZones>
|
||||
<CanonicalHostedZoneName>tests.us-east-1.elb.amazonaws.com</CanonicalHostedZoneName>
|
||||
<CanonicalHostedZoneNameID>Z3ZONEID</CanonicalHostedZoneNameID>
|
||||
<Scheme>internet-facing</Scheme>
|
||||
<DNSName>tests.us-east-1.elb.amazonaws.com</DNSName>
|
||||
<BackendServerDescriptions/>
|
||||
<Subnets>
|
||||
</Subnets>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</LoadBalancerDescriptions>
|
||||
</DescribeLoadBalancersResult>
|
||||
<ResponseMetadata>
|
||||
<RequestId>f9880f01-7852-629d-a6c3-3ae2-666a409287e6dc0c</RequestId>
|
||||
</ResponseMetadata>
|
||||
</DescribeLoadBalancersResponse>"""
|
||||
|
||||
CONFIGURE_HEALTH_CHECK_TEMPLATE = """<ConfigureHealthCheckResult xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<HealthCheck>
|
||||
<Interval>{{ check.interval }}</Interval>
|
||||
<Target>{{ check.target }}</Target>
|
||||
<HealthyThreshold>{{ check.healthy_threshold }}</HealthyThreshold>
|
||||
<Timeout>{{ check.timeout }}</Timeout>
|
||||
<UnhealthyThreshold>{{ check.unhealthy_threshold }}</UnhealthyThreshold>
|
||||
</HealthCheck>
|
||||
</ConfigureHealthCheckResult>"""
|
||||
|
||||
REGISTER_INSTANCES_TEMPLATE = """<RegisterInstancesWithLoadBalancerResult xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<Instances>
|
||||
{% for instance_id in load_balancer.instance_ids %}
|
||||
<member>
|
||||
<InstanceId>{{ instance_id }}</InstanceId>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</Instances>
|
||||
</RegisterInstancesWithLoadBalancerResult>"""
|
||||
|
||||
DEREGISTER_INSTANCES_TEMPLATE = """<DeregisterInstancesWithLoadBalancerResult xmlns="http://elasticloadbalancing.amazonaws.com/doc/2012-06-01/">
|
||||
<Instances>
|
||||
{% for instance_id in load_balancer.instance_ids %}
|
||||
<member>
|
||||
<InstanceId>{{ instance_id }}</InstanceId>
|
||||
</member>
|
||||
{% endfor %}
|
||||
</Instances>
|
||||
</DeregisterInstancesWithLoadBalancerResult>"""
|
9
moto/elb/urls.py
Normal file
9
moto/elb/urls.py
Normal file
@ -0,0 +1,9 @@
|
||||
from .responses import ELBResponse
|
||||
|
||||
url_bases = [
|
||||
"https?://elasticloadbalancing.(.+).amazonaws.com",
|
||||
]
|
||||
|
||||
url_paths = {
|
||||
'{0}/$': ELBResponse().dispatch,
|
||||
}
|
121
tests/test_elb/test_elb.py
Normal file
121
tests/test_elb/test_elb.py
Normal file
@ -0,0 +1,121 @@
|
||||
import boto
|
||||
from boto.ec2.elb import HealthCheck
|
||||
import sure # flake8: noqa
|
||||
|
||||
from moto import mock_elb, mock_ec2
|
||||
|
||||
|
||||
@mock_elb
|
||||
def test_create_load_balancer():
|
||||
conn = boto.connect_elb()
|
||||
|
||||
zones = ['us-east-1a', 'us-east-1b']
|
||||
ports = [(80, 8080, 'http'), (443, 8443, 'tcp')]
|
||||
lb = conn.create_load_balancer('my-lb', zones, ports)
|
||||
|
||||
balancers = conn.get_all_load_balancers()
|
||||
balancer = balancers[0]
|
||||
balancer.name.should.equal("my-lb")
|
||||
set(balancer.availability_zones).should.equal(set(['us-east-1a', 'us-east-1b']))
|
||||
listener1 = balancer.listeners[0]
|
||||
listener1.load_balancer_port.should.equal(80)
|
||||
listener1.instance_port.should.equal(8080)
|
||||
listener1.protocol.should.equal("HTTP")
|
||||
listener2 = balancer.listeners[1]
|
||||
listener2.load_balancer_port.should.equal(443)
|
||||
listener2.instance_port.should.equal(8443)
|
||||
listener2.protocol.should.equal("TCP")
|
||||
|
||||
|
||||
@mock_elb
|
||||
def test_get_load_balancers_by_name():
|
||||
conn = boto.connect_elb()
|
||||
|
||||
zones = ['us-east-1a', 'us-east-1b']
|
||||
ports = [(80, 8080, 'http'), (443, 8443, 'tcp')]
|
||||
lb = conn.create_load_balancer('my-lb1', zones, ports)
|
||||
lb = conn.create_load_balancer('my-lb2', zones, ports)
|
||||
lb = conn.create_load_balancer('my-lb3', zones, ports)
|
||||
|
||||
conn.get_all_load_balancers().should.have.length_of(3)
|
||||
conn.get_all_load_balancers(load_balancer_names=['my-lb1']).should.have.length_of(1)
|
||||
conn.get_all_load_balancers(load_balancer_names=['my-lb1', 'my-lb2']).should.have.length_of(2)
|
||||
|
||||
|
||||
@mock_elb
|
||||
def test_delete_load_balancer():
|
||||
conn = boto.connect_elb()
|
||||
|
||||
zones = ['us-east-1a']
|
||||
ports = [(80, 8080, 'http'), (443, 8443, 'tcp')]
|
||||
lb = conn.create_load_balancer('my-lb', zones, ports)
|
||||
|
||||
balancers = conn.get_all_load_balancers()
|
||||
balancers.should.have.length_of(1)
|
||||
|
||||
conn.delete_load_balancer("my-lb")
|
||||
balancers = conn.get_all_load_balancers()
|
||||
balancers.should.have.length_of(0)
|
||||
|
||||
|
||||
@mock_elb
|
||||
def test_create_health_check():
|
||||
conn = boto.connect_elb()
|
||||
|
||||
hc = HealthCheck(
|
||||
interval=20,
|
||||
healthy_threshold=3,
|
||||
unhealthy_threshold=5,
|
||||
target='HTTP:8080/health',
|
||||
timeout=23,
|
||||
)
|
||||
|
||||
lb = conn.create_load_balancer('my-lb', [], [])
|
||||
lb.configure_health_check(hc)
|
||||
|
||||
balancer = conn.get_all_load_balancers()[0]
|
||||
health_check = balancer.health_check
|
||||
health_check.interval.should.equal(20)
|
||||
health_check.healthy_threshold.should.equal(3)
|
||||
health_check.unhealthy_threshold.should.equal(5)
|
||||
health_check.target.should.equal('HTTP:8080/health')
|
||||
health_check.timeout.should.equal(23)
|
||||
|
||||
|
||||
@mock_ec2
|
||||
@mock_elb
|
||||
def test_register_instances():
|
||||
ec2_conn = boto.connect_ec2()
|
||||
reservation = ec2_conn.run_instances('ami-1234abcd', 2)
|
||||
instance_id1 = reservation.instances[0].id
|
||||
instance_id2 = reservation.instances[1].id
|
||||
|
||||
conn = boto.connect_elb()
|
||||
lb = conn.create_load_balancer('my-lb', [], [])
|
||||
|
||||
lb.register_instances([instance_id1, instance_id2])
|
||||
|
||||
balancer = conn.get_all_load_balancers()[0]
|
||||
instance_ids = [instance.id for instance in balancer.instances]
|
||||
set(instance_ids).should.equal(set([instance_id1, instance_id2]))
|
||||
|
||||
|
||||
@mock_ec2
|
||||
@mock_elb
|
||||
def test_deregister_instances():
|
||||
ec2_conn = boto.connect_ec2()
|
||||
reservation = ec2_conn.run_instances('ami-1234abcd', 2)
|
||||
instance_id1 = reservation.instances[0].id
|
||||
instance_id2 = reservation.instances[1].id
|
||||
|
||||
conn = boto.connect_elb()
|
||||
lb = conn.create_load_balancer('my-lb', [], [])
|
||||
|
||||
lb.register_instances([instance_id1, instance_id2])
|
||||
|
||||
balancer = conn.get_all_load_balancers()[0]
|
||||
balancer.instances.should.have.length_of(2)
|
||||
balancer.deregister_instances([instance_id1])
|
||||
|
||||
balancer.instances.should.have.length_of(1)
|
||||
balancer.instances[0].id.should.equal(instance_id2)
|
0
tests/test_elb/test_server.py
Normal file
0
tests/test_elb/test_server.py
Normal file
Loading…
Reference in New Issue
Block a user