From 2f72d082c0478eaee50bf35898e5c2faa7f2dc63 Mon Sep 17 00:00:00 2001 From: Ryan Brown Date: Fri, 2 Mar 2018 11:31:53 -0500 Subject: [PATCH] Use Tower v2 API when available, falling back to v1 where necessary (#36663) * Use Tower v2 API when available, falling back to v1 where necessary --- .../modules/cloud/amazon/ec2_instance.py | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/lib/ansible/modules/cloud/amazon/ec2_instance.py b/lib/ansible/modules/cloud/amazon/ec2_instance.py index ad946c6ec47..5f34ab51831 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_instance.py +++ b/lib/ansible/modules/cloud/amazon/ec2_instance.py @@ -47,11 +47,20 @@ options: - Opaque blob of data which is made available to the ec2 instance tower_callback: description: - - Preconfigured user-data to enable an instance to perform a Tower callback. - - Requires parameters I(tower_callback.tower_address), I(tower_callback.job_template_id), and I(tower_callback.host_config_key). + - Preconfigured user-data to enable an instance to perform a Tower callback (Linux only). - Mutually exclusive with I(user_data). - For Windows instances, to enable remote access via Ansible set I(tower_callback.windows) to true, and optionally set an admin password. - If using 'windows' and 'set_password', callback to Tower will not be performed but the instance will be ready to receive winrm connections from Ansible. + suboptions: + tower_address: + description: + - IP address or DNS name of Tower server. Must be accessible via this address from the VPC that this instance will be launched in. + template_id: + description: + - Either the integer ID of the Tower Job Template, or the name (name supported only for Tower 3.2+) + host_config_key: + description: + - Host configuration secret key generated by the Tower job template. tags: description: - A hash/dictionary of tags to add to the new instance or to add/remove from an existing one. @@ -600,6 +609,7 @@ except ImportError: pass from ansible.module_utils.six import text_type +from ansible.module_utils.six.moves.urllib import parse as urlparse from ansible.module_utils._text import to_bytes, to_native import ansible.module_utils.ec2 as ec2_utils from ansible.module_utils.ec2 import (boto3_conn, @@ -639,6 +649,8 @@ def tower_callback_script(tower_conf, windows=False, passwd=None): if p not in tower_conf: module.fail_json(msg="Incomplete tower_callback configuration. tower_callback.{0} not set.".format(p)) + if isinstance(tower_conf['job_template_id'], text_type): + tower_conf['job_template_id'] = urlparse.quote(tower_conf['job_template_id']) tpl = string.Template(textwrap.dedent("""#!/bin/bash set -x @@ -647,10 +659,19 @@ def tower_callback_script(tower_conf, windows=False, passwd=None): while [[ $attempt -lt $retry_attempts ]] do status_code=`curl --max-time 10 -v -k -s -i \ - --data "host_config_key=${host_config_key}" \ - https://${tower_address}/api/v1/job_templates/${template_id}/callback/ \ - | head -n 1 \ - | awk '{print $2}'` + --data "host_config_key=${host_config_key}" \ + 'https://${tower_address}/api/v2/job_templates/${template_id}/callback/' \ + | head -n 1 \ + | awk '{print $2}'` + if [[ $status_code == 404 ]] + then + status_code=`curl --max-time 10 -v -k -s -i \ + --data "host_config_key=${host_config_key}" \ + 'https://${tower_address}/api/v1/job_templates/${template_id}/callback/' \ + | head -n 1 \ + | awk '{print $2}'` + # fall back to using V1 API for Tower 3.1 and below, since v2 API will always 404 + fi if [[ $status_code == 201 ]] then exit 0