ELB:describe_instance_health() - implement OutOfService status (#5154)

This commit is contained in:
Bert Blommers 2022-05-21 22:55:36 +00:00 committed by GitHub
parent 12843c4eae
commit 096a89266c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 84 additions and 32 deletions

View File

@ -2292,7 +2292,7 @@
## elb
<details>
<summary>62% implemented</summary>
<summary>65% implemented</summary>
- [ ] add_tags
- [X] apply_security_groups_to_load_balancer
@ -2308,7 +2308,7 @@
- [X] delete_load_balancer_policy
- [ ] deregister_instances_from_load_balancer
- [ ] describe_account_limits
- [ ] describe_instance_health
- [X] describe_instance_health
- [ ] describe_load_balancer_attributes
- [X] describe_load_balancer_policies
- [ ] describe_load_balancer_policy_types

View File

@ -39,7 +39,7 @@ elb
- [X] delete_load_balancer_policy
- [ ] deregister_instances_from_load_balancer
- [ ] describe_account_limits
- [ ] describe_instance_health
- [X] describe_instance_health
- [ ] describe_load_balancer_attributes
- [X] describe_load_balancer_policies
- [ ] describe_load_balancer_policy_types

View File

@ -353,6 +353,9 @@ class Instance(TaggedEC2Resource, BotoInstance, CloudFormationModel):
"Client.UserInitiatedShutdown",
)
def is_running(self):
return self._state.name == "running"
def delete(self, region): # pylint: disable=unused-argument
self.terminate()

View File

@ -6,6 +6,7 @@ from collections import OrderedDict
from moto.core import BaseBackend, BaseModel, CloudFormationModel
from moto.core.utils import BackendDict
from moto.ec2.models import ec2_backends
from moto.ec2.exceptions import InvalidInstanceIdError
from uuid import uuid4
from .exceptions import (
BadHealthCheckDefinition,
@ -380,6 +381,26 @@ class ELBBackend(BaseBackend):
raise PolicyNotFoundError()
return policies
def describe_instance_health(self, lb_name, instances):
provided_ids = [i["InstanceId"] for i in instances]
registered_ids = self.get_load_balancer(lb_name).instance_ids
ec2_backend = ec2_backends[self.region_name]
if len(provided_ids) == 0:
provided_ids = registered_ids
instances = []
for instance_id in provided_ids:
if instance_id not in registered_ids:
instances.append({"InstanceId": instance_id, "State": "Unknown"})
else:
try:
instance = ec2_backend.get_instance(instance_id)
state = "InService" if instance.is_running() else "OutOfService"
instances.append({"InstanceId": instance_id, "State": state})
except InvalidInstanceIdError:
pass
return instances
def delete_load_balancer_listeners(self, name, ports):
balancer = self.load_balancers.get(name, None)
listeners = []

View File

@ -288,21 +288,10 @@ class ELBResponse(BaseResponse):
return template.render(policies=policies)
def describe_instance_health(self):
load_balancer_name = self._get_param("LoadBalancerName")
provided_instance_ids = [
list(param.values())[0]
for param in self._get_list_prefix("Instances.member")
]
registered_instances_id = self.elb_backend.get_load_balancer(
load_balancer_name
).instance_ids
if len(provided_instance_ids) == 0:
provided_instance_ids = registered_instances_id
lb_name = self._get_param("LoadBalancerName")
instances = self._get_params().get("Instances", [])
instances = self.elb_backend.describe_instance_health(lb_name, instances)
template = self.response_template(DESCRIBE_INSTANCE_HEALTH_TEMPLATE)
instances = []
for instance_id in provided_instance_ids:
state = "InService" if instance_id in registered_instances_id else "Unknown"
instances.append({"InstanceId": instance_id, "State": state})
return template.render(instances=instances)
def add_tags(self):

View File

@ -868,30 +868,69 @@ def test_connection_settings_attribute():
def test_describe_instance_health():
elb = boto3.client("elb", region_name="us-east-1")
ec2 = boto3.client("ec2", region_name="us-east-1")
instances = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2)[
"Instances"
]
# Create three instances
resp = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=2, MaxCount=2)
instance_ids = [i["InstanceId"] for i in resp["Instances"]]
# Register two instances with an LB
lb_name = "my_load_balancer"
elb.create_load_balancer(
Listeners=[{"InstancePort": 80, "LoadBalancerPort": 8080, "Protocol": "HTTP"}],
LoadBalancerName=lb_name,
)
elb.register_instances_with_load_balancer(
LoadBalancerName=lb_name, Instances=[{"InstanceId": instances[0]["InstanceId"]}]
LoadBalancerName=lb_name,
Instances=[{"InstanceId": instance_ids[0]}, {"InstanceId": instance_ids[1]}],
)
# Describe the Health of all instances
instances_health = elb.describe_instance_health(LoadBalancerName=lb_name)[
"InstanceStates"
]
instances_health.should.have.length_of(2)
@mock_ec2
@mock_elb
def test_describe_instance_health__with_instance_ids():
elb = boto3.client("elb", region_name="us-east-1")
ec2 = boto3.client("ec2", region_name="us-east-1")
# Create three instances
resp = ec2.run_instances(ImageId=EXAMPLE_AMI_ID, MinCount=3, MaxCount=3)
instance_ids = [i["InstanceId"] for i in resp["Instances"]]
# Register two instances with an LB
lb_name = "my_load_balancer"
elb.create_load_balancer(
Listeners=[{"InstancePort": 80, "LoadBalancerPort": 8080, "Protocol": "HTTP"}],
LoadBalancerName=lb_name,
)
elb.register_instances_with_load_balancer(
LoadBalancerName=lb_name,
Instances=[{"InstanceId": instance_ids[0]}, {"InstanceId": instance_ids[2]}],
)
# Stop one instance
ec2.stop_instances(InstanceIds=[instance_ids[2]])
# Describe the Health of instances
instances_health = elb.describe_instance_health(
LoadBalancerName=lb_name,
Instances=[{"InstanceId": instance["InstanceId"]} for instance in instances],
)
instances_health["InstanceStates"].should.have.length_of(2)
instances_health["InstanceStates"][0]["InstanceId"].should.equal(
instances[0]["InstanceId"]
)
instances_health["InstanceStates"][0]["State"].should.equal("InService")
instances_health["InstanceStates"][1]["InstanceId"].should.equal(
instances[1]["InstanceId"]
)
instances_health["InstanceStates"][1]["State"].should.equal("Unknown")
Instances=[{"InstanceId": iid} for iid in instance_ids],
)["InstanceStates"]
instances_health.should.have.length_of(3)
# The first instance is healthy
instances_health[0]["InstanceId"].should.equal(instance_ids[0])
instances_health[0]["State"].should.equal("InService")
# The second instance was never known to ELB
instances_health[1]["InstanceId"].should.equal(instance_ids[1])
instances_health[1]["State"].should.equal("Unknown")
# The third instance was stopped
instances_health[2]["InstanceId"].should.equal(instance_ids[2])
instances_health[2]["State"].should.equal("OutOfService")
@mock_elb