Support for named_ports in Managed Instance Groups. A libcloud guard has been implemented, as this feature will only be available in libcloud >= 1.3, or by using trunk. (#5167)
This commit is contained in:
parent
0ec56bb563
commit
b85bcb71c3
1 changed files with 124 additions and 0 deletions
|
@ -84,6 +84,13 @@ options:
|
|||
on Autoscaling.
|
||||
required: false
|
||||
default: null
|
||||
named_ports:
|
||||
version_added: "2.3"
|
||||
description:
|
||||
- Define named ports that backend services can forward data to. Format is a a list of
|
||||
name:port dictionaries.
|
||||
required: false
|
||||
default: null
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
|
@ -104,6 +111,11 @@ EXAMPLES = '''
|
|||
state: present
|
||||
size: 1
|
||||
template: my-instance-template-1
|
||||
named_ports:
|
||||
- name: http
|
||||
port: 80
|
||||
- name: foobar
|
||||
port: 82
|
||||
- pause: seconds=30
|
||||
- name: Recreate MIG Instances with Instance Template change.
|
||||
gce_mig:
|
||||
|
@ -167,6 +179,12 @@ name:
|
|||
type: string
|
||||
sample: "my-managed-instance-group"
|
||||
|
||||
named_ports:
|
||||
description: list of named ports acted upon
|
||||
returned: when named_ports are initially set or updated
|
||||
type: list
|
||||
sample: [{ "name": "http", "port": 80 }, { "name": "foo", "port": 82 }]
|
||||
|
||||
size:
|
||||
description: Number of VMs in Managed Instance Group.
|
||||
returned: changed
|
||||
|
@ -222,6 +240,18 @@ deleted_autoscaler:
|
|||
returned: When the delete of an Autoscaler was attempted.
|
||||
type: bool
|
||||
sample: true
|
||||
|
||||
set_named_ports:
|
||||
description: True if the named_ports have been set
|
||||
returned: named_ports have been set
|
||||
type: bool
|
||||
sample: true
|
||||
|
||||
updated_named_ports:
|
||||
description: True if the named_ports have been updated
|
||||
returned: named_ports have been updated
|
||||
type: bool
|
||||
sample: true
|
||||
'''
|
||||
|
||||
import socket
|
||||
|
@ -324,6 +354,38 @@ def _validate_autoscaling_params(params):
|
|||
return (True, '')
|
||||
|
||||
|
||||
def _validate_named_port_params(params):
|
||||
"""
|
||||
Validate the named ports parameters
|
||||
|
||||
:param params: Ansible dictionary containing named_ports configuration
|
||||
It is expected that autoscaling config will be found at the
|
||||
key 'named_ports'. That key should contain a list of
|
||||
{name : port} dictionaries.
|
||||
:type params: ``dict``
|
||||
|
||||
:return: Tuple containing a boolean and a string. True if params
|
||||
are valid, False otherwise, plus str for message.
|
||||
:rtype: ``(``bool``, ``str``)``
|
||||
"""
|
||||
if not params['named_ports']:
|
||||
# It's optional, so if not set at all, it's valid.
|
||||
return (True, '')
|
||||
if not isinstance(params['named_ports'], list):
|
||||
return (False, 'named_ports: expected list of name:port dictionaries.')
|
||||
req_fields = [
|
||||
{'name': 'name', 'required': True, 'type': str},
|
||||
{'name': 'port', 'required': True, 'type': int}
|
||||
] # yapf: disable
|
||||
|
||||
for np in params['named_ports']:
|
||||
(valid_named_ports, np_msg) = _check_params(np, req_fields)
|
||||
if not valid_named_ports:
|
||||
return (False, np_msg)
|
||||
|
||||
return (True, '')
|
||||
|
||||
|
||||
def _get_instance_list(mig, field='name', filter_list=['NONE']):
|
||||
"""
|
||||
Helper to grab field from instances response.
|
||||
|
@ -595,6 +657,38 @@ def get_mig(gce, name, zone):
|
|||
return None
|
||||
|
||||
|
||||
def update_named_ports(mig, named_ports):
|
||||
"""
|
||||
Set the named ports on a Managed Instance Group.
|
||||
|
||||
Sort the existing named ports and new. If different, update.
|
||||
This also implicitly allows for the removal of named_por
|
||||
|
||||
:param mig: Managed Instance Group Object from libcloud.
|
||||
:type mig: :class: `GCEInstanceGroupManager`
|
||||
|
||||
:param named_ports: list of dictionaries in the format of {'name': port}
|
||||
:type named_ports: ``list`` of ``dict``
|
||||
|
||||
:return: True if successful
|
||||
:rtype: ``bool``
|
||||
"""
|
||||
changed = False
|
||||
existing_ports = []
|
||||
new_ports = []
|
||||
if hasattr(mig.instance_group, 'named_ports'):
|
||||
existing_ports = sorted(mig.instance_group.named_ports,
|
||||
key=lambda x: x['name'])
|
||||
if named_ports is not None:
|
||||
new_ports = sorted(named_ports, key=lambda x: x['name'])
|
||||
|
||||
if existing_ports != new_ports:
|
||||
if mig.instance_group.set_named_ports(named_ports):
|
||||
changed = True
|
||||
|
||||
return changed
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(argument_spec=dict(
|
||||
name=dict(required=True),
|
||||
|
@ -607,6 +701,7 @@ def main():
|
|||
state=dict(choices=['absent', 'present'], default='present'),
|
||||
zone=dict(required=True),
|
||||
autoscaling=dict(type='dict', default=None),
|
||||
named_ports=dict(type='list', default=None),
|
||||
service_account_email=dict(),
|
||||
service_account_permissions=dict(type='list'),
|
||||
pem_file=dict(),
|
||||
|
@ -634,11 +729,22 @@ def main():
|
|||
params['template'] = module.params.get('template')
|
||||
params['recreate_instances'] = module.params.get('recreate_instances')
|
||||
params['autoscaling'] = module.params.get('autoscaling', None)
|
||||
params['named_ports'] = module.params.get('named_ports', None)
|
||||
|
||||
(valid_autoscaling, as_msg) = _validate_autoscaling_params(params)
|
||||
if not valid_autoscaling:
|
||||
module.fail_json(msg=as_msg, changed=False)
|
||||
|
||||
if params['named_ports'] is not None and not hasattr(
|
||||
gce, 'ex_instancegroup_set_named_ports'):
|
||||
module.fail_json(
|
||||
msg="Apache Libcloud 1.3.0+ is required to use 'named_ports' option",
|
||||
changed=False)
|
||||
|
||||
(valid_named_ports, np_msg) = _validate_named_port_params(params)
|
||||
if not valid_named_ports:
|
||||
module.fail_json(msg=np_msg, changed=False)
|
||||
|
||||
changed = False
|
||||
json_output = {'state': params['state'], 'zone': params['zone']}
|
||||
mig = get_mig(gce, params['name'], params['zone'])
|
||||
|
@ -681,6 +787,18 @@ def main():
|
|||
changed=False)
|
||||
|
||||
json_output['created_autoscaler'] = True
|
||||
# Add named ports if available
|
||||
if params['named_ports']:
|
||||
mig = get_mig(gce, params['name'], params['zone'])
|
||||
if not mig:
|
||||
module.fail_json(
|
||||
msg='Unable to fetch created MIG %s to create \
|
||||
autoscaler in zone: %s' % (
|
||||
params['name'], params['zone']), changed=False)
|
||||
json_output['set_named_ports'] = update_named_ports(
|
||||
mig, params['named_ports'])
|
||||
if json_output['set_named_ports']:
|
||||
json_output['named_ports'] = params['named_ports']
|
||||
|
||||
elif params['state'] == 'absent':
|
||||
# Delete MIG
|
||||
|
@ -704,6 +822,7 @@ def main():
|
|||
|
||||
else:
|
||||
# Update MIG
|
||||
|
||||
# If we're going to update a MIG, we need a size and template values.
|
||||
# If not specified, we use the values from the existing MIG.
|
||||
if not params['size']:
|
||||
|
@ -755,6 +874,11 @@ def main():
|
|||
changed = update_autoscaler(gce, autoscaler,
|
||||
params['autoscaling'])
|
||||
json_output['updated_autoscaler'] = changed
|
||||
named_ports = params['named_ports'] or []
|
||||
json_output['updated_named_ports'] = update_named_ports(mig,
|
||||
named_ports)
|
||||
if json_output['updated_named_ports']:
|
||||
json_output['named_ports'] = named_ports
|
||||
|
||||
json_output['changed'] = changed
|
||||
json_output.update(params)
|
||||
|
|
Loading…
Reference in a new issue