Allow boto_elb to manage ELB backend policies.

This commit is contained in:
Stephen Woodrow 2015-11-24 16:40:44 -08:00
parent 8d07688af9
commit ff0e4fa2b9
2 changed files with 98 additions and 2 deletions

View File

@ -144,6 +144,13 @@ def get_elb_config(name, region=None, key=None, keyid=None, profile=None):
listener_dict['certificate'] = _listener.ssl_certificate_id
listeners.append(listener_dict)
ret['listeners'] = listeners
backends = []
for _backend in lb.backends:
bs_dict = {}
bs_dict['instance_port'] = _backend.instance_port
bs_dict['policies'] = [p.policy_name for p in _backend.policies]
backends.append(bs_dict)
ret['backends'] = backends
ret['subnets'] = lb.subnets
ret['security_groups'] = lb.security_groups
ret['scheme'] = lb.scheme
@ -828,6 +835,31 @@ def set_listener_policy(name, port, policies=None, region=None, key=None,
return True
def set_backend_policy(name, port, policies=None, region=None, key=None,
keyid=None, profile=None):
'''
Set the policies of an ELB backend server.
CLI example:
salt myminion boto_elb.set_backend_policy myelb 443 "[policy1,policy2]"
'''
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
if not exists(name, region, key, keyid, profile):
return True
if policies is None:
policies = []
try:
conn.set_lb_policies_of_backend_server(name, port, policies)
log.info('Set policies {0} on ELB {1} backend server {2}'.format(policies, name, port))
except boto.exception.BotoServerError as e:
log.debug(e)
log.info('Failed to set policy {0} on ELB {1} backend server {2}: {3}'.format(policies, name, port, e.message))
return False
return True
def set_tags(name, tags, region=None, key=None, keyid=None, profile=None):
'''
Add the tags on an ELB

View File

@ -57,6 +57,10 @@ passed in as a dict, or as a string to pull from pillars or minion config:
- elb_port: 8210
instance_port: 8210
elb_protocol: TCP
- backends:
- instance_port: 80
policies:
- enable-proxy-protocol
- health_check:
target: 'HTTP:80/'
- attributes:
@ -84,6 +88,10 @@ passed in as a dict, or as a string to pull from pillars or minion config:
- policy_name: cookie-policy
policy_type: LBCookieStickinessPolicyType
policy: {} # no policy means this is a session cookie
- policy_name: enable-proxy-protocol
policy_type: ProxyProtocolPolicyType
policy:
ProxyProtocol: true
# Using a profile from pillars
Ensure myelb ELB exists:
@ -256,6 +264,7 @@ def present(
alarms_from_pillar="boto_elb_alarms",
policies=None,
policies_from_pillar="boto_elb_policies",
backends=None,
region=None,
key=None,
keyid=None,
@ -406,8 +415,8 @@ def present(
ret['result'] = _ret['result']
if ret['result'] is False:
return ret
_ret = _policies_present(name, policies, policies_from_pillar, listeners, region, key,
keyid, profile)
_ret = _policies_present(name, policies, policies_from_pillar, listeners,
backends, region, key, keyid, profile)
ret['changes'] = dictupdate.update(ret['changes'], _ret['changes'])
ret['comment'] = ' '.join([ret['comment'], _ret['comment']])
if not _ret['result']:
@ -1023,6 +1032,7 @@ def _policies_present(
policies,
policies_from_pillar,
listeners,
backends,
region,
key,
keyid,
@ -1032,6 +1042,8 @@ def _policies_present(
policies = []
pillar_policies = __salt__['config.option'](policies_from_pillar, [])
policies = policies + pillar_policies
if backends is None:
backends = []
# check for policy name uniqueness and correct type
policy_names = set()
@ -1058,6 +1070,14 @@ def _policies_present(
raise SaltInvocationError('Listener {0} on ELB {1} refers to '
'undefined policy {2}.'.format(l['elb_port'], name, p))
# check that backends refer to valid policy names
for b in backends:
for p in b.get('policies', []):
if p not in policy_names:
raise SaltInvocationError('Backend {0} on ELB {1} refers to '
'undefined policy '
'{2}.'.format(b['instance_port'], name, p))
ret = {'result': True, 'comment': '', 'changes': {}}
lb = __salt__['boto_elb.get_elb_config'](name, region, key, keyid, profile)
@ -1107,6 +1127,17 @@ def _policies_present(
if re.match(r'^ELBSecurityPolicy-\d{4}-\d{2}$', p):
default_aws_policies.add(p)
expected_policies_by_backend = {}
for b in backends:
expected_policies_by_backend[b['instance_port']] = set(
[cnames_by_name[p] for p in b.get('policies', [])])
actual_policies_by_backend = {}
for b in lb['backends']:
backend_policies = set(b.get('policies', []))
actual_policies_by_backend[b['instance_port']] = backend_policies
to_delete = []
to_create = []
@ -1126,6 +1157,14 @@ def _policies_present(
if policies != expected_policies_by_listener.get(port, set()):
listeners_to_update.add(port)
backends_to_update = set()
for port, policies in expected_policies_by_backend.iteritems():
if policies != actual_policies_by_backend.get(port, set()):
backends_to_update.add(port)
for port, policies in actual_policies_by_backend.iteritems():
if policies != expected_policies_by_backend.get(port, set()):
backends_to_update.add(port)
if __opts__['test']:
msg = []
if to_create or to_delete:
@ -1136,6 +1175,8 @@ def _policies_present(
msg.append('Policy {0} deleted.'.format(policy))
for listener in listeners_to_update:
msg.append('Listener {0} policies updated.'.format(listener))
for backend in backends_to_update:
msg.append('Backend {0} policies updated.'.format(backend))
else:
msg.append('Policies already set on ELB {0}.'.format(name))
ret['comment'] = ' '.join(msg)
@ -1186,6 +1227,29 @@ def _policies_present(
ret['result'] = False
return ret
for port in backends_to_update:
policy_set = __salt__['boto_elb.set_backend_policy'](
name=name,
port=port,
policies=list(expected_policies_by_backend.get(port, [])),
region=region,
key=key,
keyid=keyid,
profile=profile)
if policy_set:
policy_key = 'backend_{0}_policy'.format(port)
ret['changes'][policy_key] = {
'old': list(actual_policies_by_backend.get(port, [])),
'new': list(expected_policies_by_backend.get(port, [])),
}
comment = "Policy {0} was created on ELB {1} backend {2}".format(
expected_policies_by_backend[port], name, port)
ret['comment'] = ' '.join([ret['comment'], comment])
ret['result'] = True
else:
ret['result'] = False
return ret
if to_delete:
for policy_name in to_delete:
deleted = __salt__['boto_elb.delete_policy'](