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 .dynamodb import mock_dynamodb
|
||||||
from .ec2 import mock_ec2
|
from .ec2 import mock_ec2
|
||||||
|
from .elb import mock_elb
|
||||||
from .s3 import mock_s3
|
from .s3 import mock_s3
|
||||||
from .ses import mock_ses
|
from .ses import mock_ses
|
||||||
from .sqs import mock_sqs
|
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