ELBv2 - Support create_listener with ForwardConfig param (#4704)
This commit is contained in:
parent
82d18443d3
commit
43269fc8af
@ -821,6 +821,17 @@ class ELBv2Backend(BaseBackend):
|
||||
"A 'QueryStringConfig' must be specified with 'query-string'"
|
||||
)
|
||||
|
||||
def _get_target_group_arns_from(self, action_data):
|
||||
if "TargetGroupArn" in action_data:
|
||||
return [action_data["TargetGroupArn"]]
|
||||
elif "ForwardConfig" in action_data:
|
||||
return [
|
||||
tg["TargetGroupArn"]
|
||||
for tg in action_data["ForwardConfig"].get("TargetGroups", [])
|
||||
]
|
||||
else:
|
||||
return []
|
||||
|
||||
def _validate_actions(self, actions):
|
||||
# validate Actions
|
||||
target_group_arns = [
|
||||
@ -829,10 +840,11 @@ class ELBv2Backend(BaseBackend):
|
||||
for i, action in enumerate(actions):
|
||||
index = i + 1
|
||||
action_type = action.type
|
||||
if action_type == "forward" and "TargetGroupArn" in action.data:
|
||||
action_target_group_arn = action.data["TargetGroupArn"]
|
||||
if action_target_group_arn not in target_group_arns:
|
||||
raise ActionTargetGroupNotFoundError(action_target_group_arn)
|
||||
if action_type == "forward":
|
||||
found_arns = self._get_target_group_arns_from(action_data=action.data)
|
||||
for target_group_arn in found_arns:
|
||||
if target_group_arn not in target_group_arns:
|
||||
raise ActionTargetGroupNotFoundError(target_group_arn)
|
||||
elif action_type == "fixed-response":
|
||||
self._validate_fixed_response_action(action, i, index)
|
||||
elif action_type in ["redirect", "authenticate-cognito"]:
|
||||
@ -998,8 +1010,10 @@ Member must satisfy regular expression pattern: {}".format(
|
||||
balancer.listeners[listener.arn] = listener
|
||||
for action in default_actions:
|
||||
if action.type == "forward":
|
||||
target_group = self.target_groups[action.data["TargetGroupArn"]]
|
||||
target_group.load_balancer_arns.append(load_balancer_arn)
|
||||
found_arns = self._get_target_group_arns_from(action_data=action.data)
|
||||
for arn in found_arns:
|
||||
target_group = self.target_groups[arn]
|
||||
target_group.load_balancer_arns.append(load_balancer_arn)
|
||||
|
||||
return listener
|
||||
|
||||
@ -1432,7 +1446,10 @@ Member must satisfy regular expression pattern: {}".format(
|
||||
for listener in load_balancer.listeners.values():
|
||||
for rule in listener.rules.values():
|
||||
for action in rule.actions:
|
||||
if action.data.get("TargetGroupArn") == target_group_arn:
|
||||
found_arns = self._get_target_group_arns_from(
|
||||
action_data=action.data
|
||||
)
|
||||
if target_group_arn in found_arns:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
@ -187,7 +187,7 @@ class ELBV2Response(BaseResponse):
|
||||
healthcheck_enabled = self._get_param("HealthCheckEnabled")
|
||||
healthy_threshold_count = self._get_param("HealthyThresholdCount")
|
||||
unhealthy_threshold_count = self._get_param("UnhealthyThresholdCount")
|
||||
matcher = self._get_param("Matcher")
|
||||
matcher = self._get_params().get("Matcher")
|
||||
target_type = self._get_param("TargetType")
|
||||
|
||||
target_group = self.elbv2_backend.create_target_group(
|
||||
|
@ -447,10 +447,12 @@ def test_describe_target_groups_no_arguments():
|
||||
HealthCheckTimeoutSeconds=5,
|
||||
HealthyThresholdCount=5,
|
||||
UnhealthyThresholdCount=2,
|
||||
Matcher={"HttpCode": "200"},
|
||||
Matcher={"HttpCode": "201"},
|
||||
)
|
||||
|
||||
conn.describe_target_groups()["TargetGroups"].should.have.length_of(1)
|
||||
groups = conn.describe_target_groups()["TargetGroups"]
|
||||
groups.should.have.length_of(1)
|
||||
groups[0].should.have.key("Matcher").equals({"HttpCode": "201"})
|
||||
|
||||
|
||||
@mock_elbv2
|
||||
@ -570,3 +572,123 @@ def test_delete_target_group_after_modifying_listener():
|
||||
default_actions.should.equal(
|
||||
[{"Type": "forward", "TargetGroupArn": target_group_arn2}]
|
||||
)
|
||||
|
||||
|
||||
@mock_elbv2
|
||||
@mock_ec2
|
||||
def test_create_listener_with_multiple_target_groups():
|
||||
client = boto3.client("elbv2", region_name="us-east-1")
|
||||
|
||||
response, vpc, _, _, _, conn = create_load_balancer()
|
||||
|
||||
load_balancer_arn = response.get("LoadBalancers")[0].get("LoadBalancerArn")
|
||||
|
||||
response = client.create_target_group(
|
||||
Name="a-target", Protocol="HTTP", Port=8080, VpcId=vpc.id,
|
||||
)
|
||||
target_group_arn1 = response.get("TargetGroups")[0]["TargetGroupArn"]
|
||||
|
||||
response = client.create_target_group(
|
||||
Name="a-target-2", Protocol="HTTPS", Port=8081, VpcId=vpc.id,
|
||||
)
|
||||
target_group_arn2 = response.get("TargetGroups")[0]["TargetGroupArn"]
|
||||
|
||||
conn.create_listener(
|
||||
LoadBalancerArn=load_balancer_arn,
|
||||
Protocol="HTTP",
|
||||
Port=80,
|
||||
DefaultActions=[
|
||||
{
|
||||
"Type": "forward",
|
||||
"ForwardConfig": {
|
||||
"TargetGroups": [
|
||||
{"TargetGroupArn": target_group_arn1, "Weight": 100},
|
||||
{"TargetGroupArn": target_group_arn2, "Weight": 0},
|
||||
],
|
||||
"TargetGroupStickinessConfig": {
|
||||
"Enabled": False,
|
||||
"DurationSeconds": 300,
|
||||
},
|
||||
},
|
||||
}
|
||||
],
|
||||
)
|
||||
|
||||
response = conn.describe_listeners(LoadBalancerArn=load_balancer_arn)
|
||||
listener = response["Listeners"][0]
|
||||
groups = listener["DefaultActions"][0]["ForwardConfig"]["TargetGroups"]
|
||||
groups.should.have.length_of(2)
|
||||
groups.should.contain({"TargetGroupArn": target_group_arn1, "Weight": 100})
|
||||
groups.should.contain({"TargetGroupArn": target_group_arn2, "Weight": 0})
|
||||
|
||||
|
||||
@mock_elbv2
|
||||
@mock_ec2
|
||||
def test_create_listener_with_invalid_target_group():
|
||||
response, _, _, _, _, conn = create_load_balancer()
|
||||
|
||||
load_balancer_arn = response.get("LoadBalancers")[0].get("LoadBalancerArn")
|
||||
|
||||
with pytest.raises(ClientError) as exc:
|
||||
conn.create_listener(
|
||||
LoadBalancerArn=load_balancer_arn,
|
||||
Protocol="HTTP",
|
||||
Port=80,
|
||||
DefaultActions=[
|
||||
{
|
||||
"Type": "forward",
|
||||
"ForwardConfig": {
|
||||
"TargetGroups": [{"TargetGroupArn": "unknown", "Weight": 100}]
|
||||
},
|
||||
}
|
||||
],
|
||||
)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("TargetGroupNotFound")
|
||||
err["Message"].should.equal("Target group 'unknown' not found")
|
||||
|
||||
|
||||
@mock_elbv2
|
||||
@mock_ec2
|
||||
def test_delete_target_group_while_listener_still_exists():
|
||||
client = boto3.client("elbv2", region_name="us-east-1")
|
||||
|
||||
response, vpc, _, _, _, conn = create_load_balancer()
|
||||
|
||||
load_balancer_arn = response.get("LoadBalancers")[0].get("LoadBalancerArn")
|
||||
|
||||
response = client.create_target_group(
|
||||
Name="a-target", Protocol="HTTP", Port=8080, VpcId=vpc.id,
|
||||
)
|
||||
target_group_arn1 = response.get("TargetGroups")[0]["TargetGroupArn"]
|
||||
|
||||
response = conn.create_listener(
|
||||
LoadBalancerArn=load_balancer_arn,
|
||||
Protocol="HTTP",
|
||||
Port=80,
|
||||
DefaultActions=[
|
||||
{
|
||||
"Type": "forward",
|
||||
"ForwardConfig": {
|
||||
"TargetGroups": [
|
||||
{"TargetGroupArn": target_group_arn1, "Weight": 100}
|
||||
]
|
||||
},
|
||||
}
|
||||
],
|
||||
)
|
||||
listener_arn = response["Listeners"][0]["ListenerArn"]
|
||||
|
||||
# Deletion does not succeed if the Listener still exists
|
||||
with pytest.raises(ClientError) as exc:
|
||||
client.delete_target_group(TargetGroupArn=target_group_arn1)
|
||||
err = exc.value.response["Error"]
|
||||
err["Code"].should.equal("ResourceInUse")
|
||||
err["Message"].should.equal(
|
||||
f"The target group '{target_group_arn1}' is currently in use by a listener or a rule"
|
||||
)
|
||||
|
||||
client.delete_listener(ListenerArn=listener_arn)
|
||||
|
||||
# Deletion does succeed now that the listener is deleted
|
||||
client.delete_target_group(TargetGroupArn=target_group_arn1)
|
||||
|
Loading…
Reference in New Issue
Block a user