ELB Proxy Protocol support for backends
This commit is contained in:
parent
c9cfde4d0c
commit
72da61ba83
1 changed files with 110 additions and 2 deletions
|
@ -44,6 +44,16 @@ options:
|
||||||
- Purge existing listeners on ELB that are not found in listeners
|
- Purge existing listeners on ELB that are not found in listeners
|
||||||
required: false
|
required: false
|
||||||
default: true
|
default: true
|
||||||
|
instance_ids:
|
||||||
|
description:
|
||||||
|
- List of instance ids to attach to this ELB
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
|
purge_instance_ids:
|
||||||
|
description:
|
||||||
|
- Purge existing instance ids on ELB that are not found in instance_ids
|
||||||
|
required: false
|
||||||
|
default: false
|
||||||
zones:
|
zones:
|
||||||
description:
|
description:
|
||||||
- List of availability zones to enable on this ELB
|
- List of availability zones to enable on this ELB
|
||||||
|
@ -165,6 +175,7 @@ EXAMPLES = """
|
||||||
- protocol: http # options are http, https, ssl, tcp
|
- protocol: http # options are http, https, ssl, tcp
|
||||||
load_balancer_port: 80
|
load_balancer_port: 80
|
||||||
instance_port: 80
|
instance_port: 80
|
||||||
|
proxy_protocol: True
|
||||||
- protocol: https
|
- protocol: https
|
||||||
load_balancer_port: 443
|
load_balancer_port: 443
|
||||||
instance_protocol: http # optional, defaults to value of protocol setting
|
instance_protocol: http # optional, defaults to value of protocol setting
|
||||||
|
@ -179,6 +190,9 @@ EXAMPLES = """
|
||||||
name: "test-vpc"
|
name: "test-vpc"
|
||||||
scheme: internal
|
scheme: internal
|
||||||
state: present
|
state: present
|
||||||
|
instance_ids:
|
||||||
|
- i-abcd1234
|
||||||
|
purge_instance_ids: true
|
||||||
subnets:
|
subnets:
|
||||||
- subnet-abcd1234
|
- subnet-abcd1234
|
||||||
- subnet-1a2b3c4d
|
- subnet-1a2b3c4d
|
||||||
|
@ -354,12 +368,15 @@ class ElbManager(object):
|
||||||
scheme="internet-facing", connection_draining_timeout=None,
|
scheme="internet-facing", connection_draining_timeout=None,
|
||||||
idle_timeout=None,
|
idle_timeout=None,
|
||||||
cross_az_load_balancing=None, access_logs=None,
|
cross_az_load_balancing=None, access_logs=None,
|
||||||
stickiness=None, wait=None, wait_timeout=None, region=None, **aws_connect_params):
|
stickiness=None, wait=None, wait_timeout=None, region=None,
|
||||||
|
instance_ids=None, purge_instance_ids=None, **aws_connect_params):
|
||||||
|
|
||||||
self.module = module
|
self.module = module
|
||||||
self.name = name
|
self.name = name
|
||||||
self.listeners = listeners
|
self.listeners = listeners
|
||||||
self.purge_listeners = purge_listeners
|
self.purge_listeners = purge_listeners
|
||||||
|
self.instance_ids = instance_ids
|
||||||
|
self.purge_instance_ids = purge_instance_ids
|
||||||
self.zones = zones
|
self.zones = zones
|
||||||
self.purge_zones = purge_zones
|
self.purge_zones = purge_zones
|
||||||
self.security_group_ids = security_group_ids
|
self.security_group_ids = security_group_ids
|
||||||
|
@ -408,6 +425,10 @@ class ElbManager(object):
|
||||||
self._set_access_log()
|
self._set_access_log()
|
||||||
# add sitcky options
|
# add sitcky options
|
||||||
self.select_stickiness_policy()
|
self.select_stickiness_policy()
|
||||||
|
# ensure backend server policies are correct
|
||||||
|
self._set_backend_policies()
|
||||||
|
# set/remove instance ids
|
||||||
|
self._set_instance_ids()
|
||||||
|
|
||||||
def ensure_gone(self):
|
def ensure_gone(self):
|
||||||
"""Destroy the ELB"""
|
"""Destroy the ELB"""
|
||||||
|
@ -456,6 +477,8 @@ class ElbManager(object):
|
||||||
'hosted_zone_id': check_elb.canonical_hosted_zone_name_id,
|
'hosted_zone_id': check_elb.canonical_hosted_zone_name_id,
|
||||||
'lb_cookie_policy': lb_cookie_policy,
|
'lb_cookie_policy': lb_cookie_policy,
|
||||||
'app_cookie_policy': app_cookie_policy,
|
'app_cookie_policy': app_cookie_policy,
|
||||||
|
'proxy_policy': self._get_proxy_protocol_policy(),
|
||||||
|
'backends': self._get_backend_policies(),
|
||||||
'instances': [instance.id for instance in check_elb.instances],
|
'instances': [instance.id for instance in check_elb.instances],
|
||||||
'out_of_service_count': 0,
|
'out_of_service_count': 0,
|
||||||
'in_service_count': 0,
|
'in_service_count': 0,
|
||||||
|
@ -968,6 +991,84 @@ class ElbManager(object):
|
||||||
else:
|
else:
|
||||||
self._set_listener_policy(listeners_dict)
|
self._set_listener_policy(listeners_dict)
|
||||||
|
|
||||||
|
def _get_backend_policies(self):
|
||||||
|
"""Get a list of backend policies"""
|
||||||
|
return [
|
||||||
|
str(backend.instance_port) + ':' + policy.policy_name for backend in self.elb.backends
|
||||||
|
for policy in backend.policies
|
||||||
|
]
|
||||||
|
|
||||||
|
def _set_backend_policies(self):
|
||||||
|
"""Sets policies for all backends"""
|
||||||
|
ensure_proxy_protocol = False
|
||||||
|
replace = []
|
||||||
|
backend_policies = self._get_backend_policies()
|
||||||
|
|
||||||
|
# Find out what needs to be changed
|
||||||
|
for listener in self.listeners:
|
||||||
|
want = False
|
||||||
|
|
||||||
|
if 'proxy_protocol' in listener and listener['proxy_protocol']:
|
||||||
|
ensure_proxy_protocol = True
|
||||||
|
want = True
|
||||||
|
|
||||||
|
if str(listener['instance_port']) + ':ProxyProtocol-policy' in backend_policies:
|
||||||
|
if not want:
|
||||||
|
replace.append({'port': listener['instance_port'], 'policies': []})
|
||||||
|
elif want:
|
||||||
|
replace.append({'port': listener['instance_port'], 'policies': ['ProxyProtocol-policy']})
|
||||||
|
|
||||||
|
# enable or disable proxy protocol
|
||||||
|
if ensure_proxy_protocol:
|
||||||
|
self._set_proxy_protocol_policy()
|
||||||
|
|
||||||
|
# Make the backend policies so
|
||||||
|
for item in replace:
|
||||||
|
self.elb_conn.set_lb_policies_of_backend_server(self.elb.name, item['port'], item['policies'])
|
||||||
|
self.changed = True
|
||||||
|
|
||||||
|
def _get_proxy_protocol_policy(self):
|
||||||
|
"""Find out if the elb has a proxy protocol enabled"""
|
||||||
|
for policy in self.elb.policies.other_policies:
|
||||||
|
if policy.policy_name == 'ProxyProtocol-policy':
|
||||||
|
return policy.policy_name
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _set_proxy_protocol_policy(self):
|
||||||
|
"""Install a proxy protocol policy if needed"""
|
||||||
|
proxy_policy = self._get_proxy_protocol_policy()
|
||||||
|
|
||||||
|
if proxy_policy is None:
|
||||||
|
self.elb_conn.create_lb_policy(
|
||||||
|
self.elb.name, 'ProxyProtocol-policy', 'ProxyProtocolPolicyType', {'ProxyProtocol': True}
|
||||||
|
)
|
||||||
|
self.changed = True
|
||||||
|
|
||||||
|
# TODO: remove proxy protocol policy if not needed anymore? There is no side effect to leaving it there
|
||||||
|
|
||||||
|
def _diff_list(self, a, b):
|
||||||
|
"""Find the entries in list a that are not in list b"""
|
||||||
|
b = set(b)
|
||||||
|
return [aa for aa in a if aa not in b]
|
||||||
|
|
||||||
|
def _set_instance_ids(self):
|
||||||
|
"""Register or deregister instances from an lb instance"""
|
||||||
|
assert_instances = self.instance_ids or []
|
||||||
|
|
||||||
|
has_instances = [has_instance.id for has_instance in self.elb.instances]
|
||||||
|
|
||||||
|
add_instances = self._diff_list(assert_instances, has_instances)
|
||||||
|
if add_instances:
|
||||||
|
self.elb_conn.register_instances(self.elb.name, add_instances)
|
||||||
|
self.changed = True
|
||||||
|
|
||||||
|
if self.purge_instance_ids:
|
||||||
|
remove_instances = self._diff_list(has_instances, assert_instances)
|
||||||
|
if remove_instances:
|
||||||
|
self.elb_conn.deregister_instances(self.elb.name, remove_instances)
|
||||||
|
self.changed = True
|
||||||
|
|
||||||
def _get_health_check_target(self):
|
def _get_health_check_target(self):
|
||||||
"""Compose target string from healthcheck parameters"""
|
"""Compose target string from healthcheck parameters"""
|
||||||
protocol = self.health_check['ping_protocol'].upper()
|
protocol = self.health_check['ping_protocol'].upper()
|
||||||
|
@ -986,6 +1087,8 @@ def main():
|
||||||
name={'required': True},
|
name={'required': True},
|
||||||
listeners={'default': None, 'required': False, 'type': 'list'},
|
listeners={'default': None, 'required': False, 'type': 'list'},
|
||||||
purge_listeners={'default': True, 'required': False, 'type': 'bool'},
|
purge_listeners={'default': True, 'required': False, 'type': 'bool'},
|
||||||
|
instance_ids={'default': None, 'required': False, 'type': 'list'},
|
||||||
|
purge_instance_ids={'default': False, 'required': False, 'type': 'bool'},
|
||||||
zones={'default': None, 'required': False, 'type': 'list'},
|
zones={'default': None, 'required': False, 'type': 'list'},
|
||||||
purge_zones={'default': False, 'required': False, 'type': 'bool'},
|
purge_zones={'default': False, 'required': False, 'type': 'bool'},
|
||||||
security_group_ids={'default': None, 'required': False, 'type': 'list'},
|
security_group_ids={'default': None, 'required': False, 'type': 'list'},
|
||||||
|
@ -1020,6 +1123,8 @@ def main():
|
||||||
state = module.params['state']
|
state = module.params['state']
|
||||||
listeners = module.params['listeners']
|
listeners = module.params['listeners']
|
||||||
purge_listeners = module.params['purge_listeners']
|
purge_listeners = module.params['purge_listeners']
|
||||||
|
instance_ids = module.params['instance_ids']
|
||||||
|
purge_instance_ids = module.params['purge_instance_ids']
|
||||||
zones = module.params['zones']
|
zones = module.params['zones']
|
||||||
purge_zones = module.params['purge_zones']
|
purge_zones = module.params['purge_zones']
|
||||||
security_group_ids = module.params['security_group_ids']
|
security_group_ids = module.params['security_group_ids']
|
||||||
|
@ -1060,13 +1165,16 @@ def main():
|
||||||
except boto.exception.NoAuthHandlerFound, e:
|
except boto.exception.NoAuthHandlerFound, e:
|
||||||
module.fail_json(msg = str(e))
|
module.fail_json(msg = str(e))
|
||||||
|
|
||||||
|
|
||||||
elb_man = ElbManager(module, name, listeners, purge_listeners, zones,
|
elb_man = ElbManager(module, name, listeners, purge_listeners, zones,
|
||||||
purge_zones, security_group_ids, health_check,
|
purge_zones, security_group_ids, health_check,
|
||||||
subnets, purge_subnets, scheme,
|
subnets, purge_subnets, scheme,
|
||||||
connection_draining_timeout, idle_timeout,
|
connection_draining_timeout, idle_timeout,
|
||||||
cross_az_load_balancing,
|
cross_az_load_balancing,
|
||||||
access_logs, stickiness, wait, wait_timeout,
|
access_logs, stickiness, wait, wait_timeout,
|
||||||
region=region, **aws_connect_params)
|
region=region, instance_ids=instance_ids, purge_instance_ids=purge_instance_ids,
|
||||||
|
**aws_connect_params)
|
||||||
|
|
||||||
|
|
||||||
# check for unsupported attributes for this version of boto
|
# check for unsupported attributes for this version of boto
|
||||||
if cross_az_load_balancing and not elb_man._check_attribute_support('cross_zone_load_balancing'):
|
if cross_az_load_balancing and not elb_man._check_attribute_support('cross_zone_load_balancing'):
|
||||||
|
|
Loading…
Reference in a new issue