From 971e432ad3a7bbe8051b3a9922d5d10e6437146b Mon Sep 17 00:00:00 2001 From: Macwan Nevil Date: Fri, 15 Sep 2023 15:42:47 +0530 Subject: [PATCH] ELBv2: fix parity in describe_target_group (#6812) --- moto/elbv2/exceptions.py | 4 +- moto/elbv2/models.py | 21 ++++- moto/elbv2/responses.py | 1 + tests/test_elbv2/test_elbv2_target_groups.py | 87 +++++++++++++++++++- 4 files changed, 102 insertions(+), 11 deletions(-) diff --git a/moto/elbv2/exceptions.py b/moto/elbv2/exceptions.py index 9550fcb9e095..dd2fa6ee924e 100644 --- a/moto/elbv2/exceptions.py +++ b/moto/elbv2/exceptions.py @@ -35,9 +35,7 @@ def __init__(self) -> None: class TargetGroupNotFoundError(ELBClientError): def __init__(self) -> None: - super().__init__( - "TargetGroupNotFound", "The specified target group does not exist." - ) + super().__init__("TargetGroupNotFound", "One or more target groups not found") class TooManyTagsError(ELBClientError): diff --git a/moto/elbv2/models.py b/moto/elbv2/models.py index 9f0e53e2d2a8..2ae4f3f51658 100644 --- a/moto/elbv2/models.py +++ b/moto/elbv2/models.py @@ -1377,20 +1377,33 @@ def describe_target_groups( target_group_arns: List[str], names: Optional[List[str]], ) -> Iterable[FakeTargetGroup]: + + args = sum(bool(arg) for arg in [load_balancer_arn, target_group_arns, names]) + + if args > 1: + raise ValidationError( + "Target group names, target group ARNs, and a load balancer ARN cannot be specified at the same time" + ) + if load_balancer_arn: if load_balancer_arn not in self.load_balancers: raise LoadBalancerNotFoundError() - return [ + target_groups = [ tg for tg in self.target_groups.values() if load_balancer_arn in tg.load_balancer_arns ] + if target_groups is None or len(target_groups) == 0: + raise TargetGroupNotFoundError() + return sorted(target_groups, key=lambda tg: tg.name) if target_group_arns: try: - return [self.target_groups[arn] for arn in target_group_arns] + target_groups = [self.target_groups[arn] for arn in target_group_arns] + return sorted(target_groups, key=lambda tg: tg.name) except KeyError: raise TargetGroupNotFoundError() + if names: matched = [] for name in names: @@ -1401,9 +1414,9 @@ def describe_target_groups( if not found: raise TargetGroupNotFoundError() matched.append(found) - return matched + return sorted(matched, key=lambda tg: tg.name) - return self.target_groups.values() + return sorted(self.target_groups.values(), key=lambda tg: tg.name) def describe_listeners( self, load_balancer_arn: Optional[str], listener_arns: List[str] diff --git a/moto/elbv2/responses.py b/moto/elbv2/responses.py index 652d5b9b9aa0..443d92fbb416 100644 --- a/moto/elbv2/responses.py +++ b/moto/elbv2/responses.py @@ -1070,6 +1070,7 @@ def remove_listener_certificates(self) -> str: {% if target_group.vpc_id %} {{ target_group.vpc_id }} {% endif %} + {{ target_group.ip_address_type }} {{ target_group.healthcheck_protocol }} {% if target_group.healthcheck_port %}{{ target_group.healthcheck_port }}{% endif %} {{ target_group.healthcheck_path or '' }} diff --git a/tests/test_elbv2/test_elbv2_target_groups.py b/tests/test_elbv2/test_elbv2_target_groups.py index 53e311e11b63..1370cb8fe5fc 100644 --- a/tests/test_elbv2/test_elbv2_target_groups.py +++ b/tests/test_elbv2/test_elbv2_target_groups.py @@ -122,7 +122,7 @@ def test_create_target_group_and_listeners(): http_listener_arn = listener["ListenerArn"] response = conn.describe_target_groups( - LoadBalancerArn=load_balancer_arn, Names=["a-target"] + LoadBalancerArn=load_balancer_arn, ) assert len(response["TargetGroups"]) == 1 @@ -455,17 +455,23 @@ def test_describe_invalid_target_group(): conn.describe_target_groups(Names=["invalid"]) err = exc.value.response["Error"] assert err["Code"] == "TargetGroupNotFound" - assert err["Message"] == "The specified target group does not exist." + assert err["Message"] == "One or more target groups not found" @mock_elbv2 @mock_ec2 -def test_describe_target_groups_no_arguments(): +def test_describe_target_groups(): + elbv2 = boto3.client("elbv2", region_name="us-east-1") + response, vpc, _, _, _, conn = create_load_balancer() + lb_arn = response["LoadBalancers"][0]["LoadBalancerArn"] assert "LoadBalancerArn" in response["LoadBalancers"][0] - conn.create_target_group( + groups = conn.describe_target_groups()["TargetGroups"] + assert len(groups) == 0 + + response = conn.create_target_group( Name="a-target", Protocol="HTTP", Port=8080, @@ -479,11 +485,84 @@ def test_describe_target_groups_no_arguments(): UnhealthyThresholdCount=2, Matcher={"HttpCode": "201"}, ) + arn_a = response["TargetGroups"][0]["TargetGroupArn"] + + conn.create_listener( + LoadBalancerArn=lb_arn, + Protocol="HTTP", + Port=80, + DefaultActions=[{"Type": "forward", "TargetGroupArn": arn_a}], + ) groups = conn.describe_target_groups()["TargetGroups"] assert len(groups) == 1 assert groups[0]["Matcher"] == {"HttpCode": "201"} + response = elbv2.create_target_group( + Name="c-target", + Protocol="HTTP", + Port=8081, + VpcId=vpc.id, + ) + arn_c = response["TargetGroups"][0]["TargetGroupArn"] + groups = conn.describe_target_groups()["TargetGroups"] + assert len(groups) == 2 + assert groups[0]["TargetGroupName"] == "a-target" + assert groups[1]["TargetGroupName"] == "c-target" + + response = elbv2.create_target_group( + Name="b-target", + Protocol="HTTP", + Port=8082, + VpcId=vpc.id, + ) + arn_b = response["TargetGroups"][0]["TargetGroupArn"] + groups = conn.describe_target_groups()["TargetGroups"] + assert len(groups) == 3 + assert groups[0]["TargetGroupName"] == "a-target" + assert groups[1]["TargetGroupName"] == "b-target" + assert groups[2]["TargetGroupName"] == "c-target" + + groups = conn.describe_target_groups(Names=["a-target"])["TargetGroups"] + assert len(groups) == 1 + assert groups[0]["TargetGroupName"] == "a-target" + + groups = conn.describe_target_groups(Names=["a-target", "b-target"])["TargetGroups"] + assert len(groups) == 2 + assert groups[0]["TargetGroupName"] == "a-target" + assert groups[1]["TargetGroupName"] == "b-target" + + groups = conn.describe_target_groups(TargetGroupArns=[arn_b])["TargetGroups"] + assert len(groups) == 1 + assert groups[0]["TargetGroupName"] == "b-target" + + groups = conn.describe_target_groups(TargetGroupArns=[arn_b, arn_c])["TargetGroups"] + assert len(groups) == 2 + assert groups[0]["TargetGroupName"] == "b-target" + assert groups[1]["TargetGroupName"] == "c-target" + + groups = conn.describe_target_groups(LoadBalancerArn=lb_arn)["TargetGroups"] + assert len(groups) == 1 + assert groups[0]["TargetGroupName"] == "a-target" + + response = conn.create_target_group( + Name="d-target", + Protocol="HTTP", + Port=8082, + VpcId=vpc.id, + ) + arn_d = response["TargetGroups"][0]["TargetGroupArn"] + conn.create_listener( + LoadBalancerArn=lb_arn, + Protocol="HTTP", + Port=80, + DefaultActions=[{"Type": "forward", "TargetGroupArn": arn_d}], + ) + groups = conn.describe_target_groups(LoadBalancerArn=lb_arn)["TargetGroups"] + assert len(groups) == 2 + assert groups[0]["TargetGroupName"] == "a-target" + assert groups[1]["TargetGroupName"] == "d-target" + @mock_elbv2 @mock_ec2