summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Melendez <tom@supertom.com>2016-11-04 12:31:00 -0700
committerRyan Brown <sb@ryansb.com>2016-11-04 15:31:00 -0400
commit94d28fbd6fc68c7bb7216214575c68e0a9c5fc5a (patch)
tree6fb3543fb60fc933eec74646c1b66ce7256339b9
parent4db6d47ef86b1063548853cacf4196fa687c1e87 (diff)
downloadansible-modules-core-94d28fbd6fc68c7bb7216214575c68e0a9c5fc5a.tar.gz
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)
-rw-r--r--cloud/google/gce_mig.py124
1 files changed, 124 insertions, 0 deletions
diff --git a/cloud/google/gce_mig.py b/cloud/google/gce_mig.py
index bb44be1f..11433b35 100644
--- a/cloud/google/gce_mig.py
+++ b/cloud/google/gce_mig.py
@@ -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)