From 543e5fb07730c8116cab33da75ef3d492a21c48e Mon Sep 17 00:00:00 2001 From: Jack Danger Date: Wed, 2 Aug 2017 15:57:15 -0700 Subject: [PATCH] Implementing ELBV2 target group attributes --- moto/elbv2/models.py | 5 +++ moto/elbv2/responses.py | 58 ++++++++++++++++++++++++++- tests/test_elbv2/test_elbv2.py | 73 ++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 1 deletion(-) diff --git a/moto/elbv2/models.py b/moto/elbv2/models.py index 7682ae097..10d9ad220 100644 --- a/moto/elbv2/models.py +++ b/moto/elbv2/models.py @@ -55,6 +55,11 @@ class FakeTargetGroup(BaseModel): self.unhealthy_threshold_count = unhealthy_threshold_count self.load_balancer_arns = [] + self.attributes = { + 'deregistration_delay.timeout_seconds': 300, + 'stickiness.enabled': 'false', + } + self.targets = OrderedDict() def register(self, targets): diff --git a/moto/elbv2/responses.py b/moto/elbv2/responses.py index c000dd0c9..751652901 100644 --- a/moto/elbv2/responses.py +++ b/moto/elbv2/responses.py @@ -1,7 +1,9 @@ from __future__ import unicode_literals from moto.core.responses import BaseResponse from .models import elbv2_backends -from .exceptions import DuplicateTagKeysError, LoadBalancerNotFoundError +from .exceptions import DuplicateTagKeysError +from .exceptions import LoadBalancerNotFoundError +from .exceptions import TargetGroupNotFoundError class ELBV2Response(BaseResponse): @@ -107,6 +109,14 @@ class ELBV2Response(BaseResponse): template = self.response_template(DESCRIBE_TARGET_GROUPS_TEMPLATE) return template.render(target_groups=target_groups) + def describe_target_group_attributes(self): + target_group_arn = self._get_param('TargetGroupArn') + target_group = self.elbv2_backend.target_groups.get(target_group_arn) + if not target_group: + raise TargetGroupNotFoundError() + template = self.response_template(DESCRIBE_TARGET_GROUP_ATTRIBUTES_TEMPLATE) + return template.render(attributes=target_group.attributes) + def describe_listeners(self): load_balancer_arn = self._get_param('LoadBalancerArn') listener_arns = self._get_multi_param('ListenerArns.member') @@ -135,6 +145,19 @@ class ELBV2Response(BaseResponse): template = self.response_template(DELETE_LISTENER_TEMPLATE) return template.render() + def modify_target_group_attributes(self): + target_group_arn = self._get_param('TargetGroupArn') + target_group = self.elbv2_backend.target_groups.get(target_group_arn) + attributes = { + attr['key']: attr['value'] + for attr in self._get_list_prefix('Attributes.member') + } + target_group.attributes.update(attributes) + if not target_group: + raise TargetGroupNotFoundError() + template = self.response_template(MODIFY_TARGET_GROUP_ATTRIBUTES_TEMPLATE) + return template.render(attributes=attributes) + def register_targets(self): target_group_arn = self._get_param('TargetGroupArn') targets = self._get_list_prefix('Targets.member') @@ -455,6 +478,23 @@ DESCRIBE_TARGET_GROUPS_TEMPLATE = """ + + + {% for key, value in attributes.items() %} + + {{ key }} + {{ value }} + + {% endfor %} + + + + 70092c0e-f3a9-11e5-ae48-cff02092876b + +""" + + DESCRIBE_LISTENERS_TEMPLATE = """ @@ -504,6 +544,22 @@ CONFIGURE_HEALTH_CHECK_TEMPLATE = """ + + + {% for key, value in attributes.items() %} + + {{ key }} + {{ value }} + + {% endfor %} + + + + 70092c0e-f3a9-11e5-ae48-cff02092876b + +""" + REGISTER_TARGETS_TEMPLATE = """ diff --git a/tests/test_elbv2/test_elbv2.py b/tests/test_elbv2/test_elbv2.py index c9eb9ea43..6bfe2ca4f 100644 --- a/tests/test_elbv2/test_elbv2.py +++ b/tests/test_elbv2/test_elbv2.py @@ -445,3 +445,76 @@ def test_register_targets(): response = conn.describe_target_health(TargetGroupArn=target_group.get('TargetGroupArn')) response.get('TargetHealthDescriptions').should.have.length_of(1) + + +@mock_ec2 +@mock_elbv2 +def test_target_group_attributes(): + conn = boto3.client('elbv2', region_name='us-east-1') + ec2 = boto3.resource('ec2', region_name='us-east-1') + + security_group = ec2.create_security_group(GroupName='a-security-group', Description='First One') + vpc = ec2.create_vpc(CidrBlock='172.28.7.0/24', InstanceTenancy='default') + subnet1 = ec2.create_subnet(VpcId=vpc.id, CidrBlock='172.28.7.192/26', AvailabilityZone='us-east-1a') + subnet2 = ec2.create_subnet(VpcId=vpc.id, CidrBlock='172.28.7.192/26', AvailabilityZone='us-east-1b') + + response = conn.create_load_balancer( + Name='my-lb', + Subnets=[subnet1.id, subnet2.id], + SecurityGroups=[security_group.id], + Scheme='internal', + Tags=[{'Key': 'key_name', 'Value': 'a_value'}]) + + response = conn.create_target_group( + Name='a-target', + Protocol='HTTP', + Port=8080, + VpcId=vpc.id, + HealthCheckProtocol='HTTP', + HealthCheckPort='8080', + HealthCheckPath='/', + HealthCheckIntervalSeconds=5, + HealthCheckTimeoutSeconds=5, + HealthyThresholdCount=5, + UnhealthyThresholdCount=2, + Matcher={'HttpCode': '200'}) + target_group = response.get('TargetGroups')[0] + + # Check it's in the describe_target_groups response + response = conn.describe_target_groups() + response.get('TargetGroups').should.have.length_of(1) + target_group_arn = target_group['TargetGroupArn'] + + # The attributes should start with the two defaults + response = conn.describe_target_group_attributes(TargetGroupArn=target_group_arn) + response['Attributes'].should.have.length_of(2) + attributes = {attr['Key']: attr['Value'] for attr in response['Attributes']} + attributes['deregistration_delay.timeout_seconds'].should.equal('300') + attributes['stickiness.enabled'].should.equal('false') + + # add cookie stickiness + response = conn.modify_target_group_attributes( + TargetGroupArn=target_group_arn, + Attributes=[ + { + 'Key': 'stickiness.enabled', + 'Value': 'true', + }, + { + 'Key': 'stickiness.type', + 'Value': 'lb_cookie', + }, + ]) + + # the response should have only the keys updated + response['Attributes'].should.have.length_of(2) + attributes = {attr['Key']: attr['Value'] for attr in response['Attributes']} + attributes['stickiness.type'].should.equal('lb_cookie') + attributes['stickiness.enabled'].should.equal('true') + + # These new values should be in the full attribute list + response = conn.describe_target_group_attributes(TargetGroupArn=target_group_arn) + response['Attributes'].should.have.length_of(3) + attributes = {attr['Key']: attr['Value'] for attr in response['Attributes']} + attributes['stickiness.type'].should.equal('lb_cookie') + attributes['stickiness.enabled'].should.equal('true')