Fix/autoscaling elb interaction (#3757)
* Add minimal failing test case. * Improve ELB instance ids handling. We need to handle the instances originated by an autoscaling group differently.
This commit is contained in:
parent
bcc7938615
commit
273d632515
@ -946,10 +946,10 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
for elb in elbs:
|
for elb in elbs:
|
||||||
elb_instace_ids = set(elb.instance_ids)
|
elb_instace_ids = set(elb.instance_ids)
|
||||||
self.elb_backend.register_instances(
|
self.elb_backend.register_instances(
|
||||||
elb.name, group_instance_ids - elb_instace_ids
|
elb.name, group_instance_ids - elb_instace_ids, from_autoscaling=True,
|
||||||
)
|
)
|
||||||
self.elb_backend.deregister_instances(
|
self.elb_backend.deregister_instances(
|
||||||
elb.name, elb_instace_ids - group_instance_ids
|
elb.name, elb_instace_ids - group_instance_ids, from_autoscaling=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
def update_attached_target_groups(self, group_name):
|
def update_attached_target_groups(self, group_name):
|
||||||
@ -1007,7 +1007,9 @@ class AutoScalingBackend(BaseBackend):
|
|||||||
group_instance_ids = set(state.instance.id for state in group.instance_states)
|
group_instance_ids = set(state.instance.id for state in group.instance_states)
|
||||||
elbs = self.elb_backend.describe_load_balancers(names=group.load_balancers)
|
elbs = self.elb_backend.describe_load_balancers(names=group.load_balancers)
|
||||||
for elb in elbs:
|
for elb in elbs:
|
||||||
self.elb_backend.deregister_instances(elb.name, group_instance_ids)
|
self.elb_backend.deregister_instances(
|
||||||
|
elb.name, group_instance_ids, from_autoscaling=True
|
||||||
|
)
|
||||||
group.load_balancers = [
|
group.load_balancers = [
|
||||||
x for x in group.load_balancers if x not in load_balancer_names
|
x for x in group.load_balancers if x not in load_balancer_names
|
||||||
]
|
]
|
||||||
|
@ -82,7 +82,8 @@ class FakeLoadBalancer(CloudFormationModel):
|
|||||||
):
|
):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.health_check = None
|
self.health_check = None
|
||||||
self.instance_ids = []
|
self.instance_sparse_ids = []
|
||||||
|
self.instance_autoscaling_ids = []
|
||||||
self.zones = zones
|
self.zones = zones
|
||||||
self.listeners = []
|
self.listeners = []
|
||||||
self.backends = []
|
self.backends = []
|
||||||
@ -119,6 +120,11 @@ class FakeLoadBalancer(CloudFormationModel):
|
|||||||
)
|
)
|
||||||
self.backends.append(backend)
|
self.backends.append(backend)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def instance_ids(self):
|
||||||
|
"""Return all the instances attached to the ELB"""
|
||||||
|
return self.instance_sparse_ids + self.instance_autoscaling_ids
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def cloudformation_name_type():
|
def cloudformation_name_type():
|
||||||
return "LoadBalancerName"
|
return "LoadBalancerName"
|
||||||
@ -403,19 +409,39 @@ class ELBBackend(BaseBackend):
|
|||||||
|
|
||||||
return balancer
|
return balancer
|
||||||
|
|
||||||
def register_instances(self, load_balancer_name, instance_ids):
|
def register_instances(
|
||||||
|
self, load_balancer_name, instance_ids, from_autoscaling=False
|
||||||
|
):
|
||||||
load_balancer = self.get_load_balancer(load_balancer_name)
|
load_balancer = self.get_load_balancer(load_balancer_name)
|
||||||
load_balancer.instance_ids.extend(instance_ids)
|
attr_name = (
|
||||||
|
"instance_sparse_ids"
|
||||||
|
if not from_autoscaling
|
||||||
|
else "instance_autoscaling_ids"
|
||||||
|
)
|
||||||
|
|
||||||
|
actual_instance_ids = getattr(load_balancer, attr_name)
|
||||||
|
actual_instance_ids.extend(instance_ids)
|
||||||
return load_balancer
|
return load_balancer
|
||||||
|
|
||||||
def deregister_instances(self, load_balancer_name, instance_ids):
|
def deregister_instances(
|
||||||
|
self, load_balancer_name, instance_ids, from_autoscaling=False
|
||||||
|
):
|
||||||
load_balancer = self.get_load_balancer(load_balancer_name)
|
load_balancer = self.get_load_balancer(load_balancer_name)
|
||||||
|
attr_name = (
|
||||||
|
"instance_sparse_ids"
|
||||||
|
if not from_autoscaling
|
||||||
|
else "instance_autoscaling_ids"
|
||||||
|
)
|
||||||
|
actual_instance_ids = getattr(load_balancer, attr_name)
|
||||||
|
|
||||||
new_instance_ids = [
|
new_instance_ids = [
|
||||||
instance_id
|
instance_id
|
||||||
for instance_id in load_balancer.instance_ids
|
for instance_id in actual_instance_ids
|
||||||
if instance_id not in instance_ids
|
if instance_id not in instance_ids
|
||||||
]
|
]
|
||||||
load_balancer.instance_ids = new_instance_ids
|
|
||||||
|
setattr(load_balancer, attr_name, new_instance_ids)
|
||||||
|
|
||||||
return load_balancer
|
return load_balancer
|
||||||
|
|
||||||
def set_cross_zone_load_balancing_attribute(self, load_balancer_name, attribute):
|
def set_cross_zone_load_balancing_attribute(self, load_balancer_name, attribute):
|
||||||
|
@ -31,11 +31,30 @@ from tests import EXAMPLE_AMI_ID
|
|||||||
|
|
||||||
@mock_autoscaling_deprecated
|
@mock_autoscaling_deprecated
|
||||||
@mock_elb_deprecated
|
@mock_elb_deprecated
|
||||||
|
@mock_ec2_deprecated
|
||||||
def test_create_autoscaling_group():
|
def test_create_autoscaling_group():
|
||||||
mocked_networking = setup_networking_deprecated()
|
mocked_networking = setup_networking_deprecated()
|
||||||
elb_conn = boto.ec2.elb.connect_to_region("us-east-1")
|
elb_conn = boto.ec2.elb.connect_to_region("us-east-1")
|
||||||
elb_conn.create_load_balancer("test_lb", zones=[], listeners=[(80, 8080, "http")])
|
elb_conn.create_load_balancer("test_lb", zones=[], listeners=[(80, 8080, "http")])
|
||||||
|
|
||||||
|
# we attach a couple of machines to the load balancer
|
||||||
|
# that are not managed by the auto scaling group
|
||||||
|
INSTANCE_COUNT_START = 3
|
||||||
|
INSTANCE_COUNT_GROUP = 2
|
||||||
|
ec2 = boto3.resource("ec2", region_name="us-east-1")
|
||||||
|
instances = ec2.create_instances(
|
||||||
|
ImageId=EXAMPLE_AMI_ID,
|
||||||
|
InstanceType="t1.micro",
|
||||||
|
MaxCount=INSTANCE_COUNT_START,
|
||||||
|
MinCount=INSTANCE_COUNT_START,
|
||||||
|
SubnetId=mocked_networking["subnet1"],
|
||||||
|
)
|
||||||
|
|
||||||
|
instances_ids = [_.id for _ in instances]
|
||||||
|
elb_conn.register_instances(
|
||||||
|
"test_lb", instances_ids,
|
||||||
|
)
|
||||||
|
|
||||||
conn = boto.ec2.autoscale.connect_to_region("us-east-1")
|
conn = boto.ec2.autoscale.connect_to_region("us-east-1")
|
||||||
config = LaunchConfiguration(
|
config = LaunchConfiguration(
|
||||||
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
|
name="tester", image_id=EXAMPLE_AMI_ID, instance_type="t2.medium"
|
||||||
@ -46,11 +65,11 @@ def test_create_autoscaling_group():
|
|||||||
name="tester_group",
|
name="tester_group",
|
||||||
availability_zones=["us-east-1a", "us-east-1b"],
|
availability_zones=["us-east-1a", "us-east-1b"],
|
||||||
default_cooldown=60,
|
default_cooldown=60,
|
||||||
desired_capacity=2,
|
desired_capacity=INSTANCE_COUNT_GROUP,
|
||||||
health_check_period=100,
|
health_check_period=100,
|
||||||
health_check_type="EC2",
|
health_check_type="EC2",
|
||||||
max_size=2,
|
max_size=INSTANCE_COUNT_GROUP,
|
||||||
min_size=2,
|
min_size=INSTANCE_COUNT_GROUP,
|
||||||
launch_config=config,
|
launch_config=config,
|
||||||
load_balancers=["test_lb"],
|
load_balancers=["test_lb"],
|
||||||
placement_group="test_placement",
|
placement_group="test_placement",
|
||||||
@ -73,9 +92,9 @@ def test_create_autoscaling_group():
|
|||||||
group.name.should.equal("tester_group")
|
group.name.should.equal("tester_group")
|
||||||
set(group.availability_zones).should.equal(set(["us-east-1a", "us-east-1b"]))
|
set(group.availability_zones).should.equal(set(["us-east-1a", "us-east-1b"]))
|
||||||
group.desired_capacity.should.equal(2)
|
group.desired_capacity.should.equal(2)
|
||||||
group.max_size.should.equal(2)
|
group.max_size.should.equal(INSTANCE_COUNT_GROUP)
|
||||||
group.min_size.should.equal(2)
|
group.min_size.should.equal(INSTANCE_COUNT_GROUP)
|
||||||
group.instances.should.have.length_of(2)
|
group.instances.should.have.length_of(INSTANCE_COUNT_GROUP)
|
||||||
group.vpc_zone_identifier.should.equal(
|
group.vpc_zone_identifier.should.equal(
|
||||||
"{subnet1},{subnet2}".format(
|
"{subnet1},{subnet2}".format(
|
||||||
subnet1=mocked_networking["subnet1"], subnet2=mocked_networking["subnet2"]
|
subnet1=mocked_networking["subnet1"], subnet2=mocked_networking["subnet2"]
|
||||||
@ -95,6 +114,9 @@ def test_create_autoscaling_group():
|
|||||||
tag.value.should.equal("test_value")
|
tag.value.should.equal("test_value")
|
||||||
tag.propagate_at_launch.should.equal(True)
|
tag.propagate_at_launch.should.equal(True)
|
||||||
|
|
||||||
|
instances_attached = elb_conn.describe_instance_health("test_lb")
|
||||||
|
len(instances_attached).should.equal(INSTANCE_COUNT_START + INSTANCE_COUNT_GROUP)
|
||||||
|
|
||||||
|
|
||||||
@mock_autoscaling_deprecated
|
@mock_autoscaling_deprecated
|
||||||
def test_create_autoscaling_groups_defaults():
|
def test_create_autoscaling_groups_defaults():
|
||||||
|
Loading…
x
Reference in New Issue
Block a user