From 17a2e5ead279e7459a19183b0b03ddcf4eae0fbb Mon Sep 17 00:00:00 2001
From: Wayne Witzel III <wayne@riotousliving.com>
Date: Fri, 17 Feb 2017 11:18:40 -0500
Subject: [PATCH] Add Tower Host module (#21482)

---
 .../ansible_tower/tower_host.py               | 186 ++++++++++++++++++
 1 file changed, 186 insertions(+)
 create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py

diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py
new file mode 100644
index 00000000000..12562e999b2
--- /dev/null
+++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py
@@ -0,0 +1,186 @@
+#!/usr/bin/python
+#coding: utf-8 -*-
+
+# (c) 2017, Wayne Witzel III <wayne@riotousliving.com>
+#
+# This module is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This software is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this software.  If not, see <http://www.gnu.org/licenses/>.
+
+ANSIBLE_METADATA = {'status': ['preview'],
+                    'supported_by': 'community',
+                    'version': '1.0'}
+
+DOCUMENTATION = '''
+---
+module: tower_host
+version_added: "2.3"
+short_description: create, update, or destroy Ansible Tower host.
+description:
+    - Create, update, or destroy Ansible Tower hosts. See
+      U(https://www.ansible.com/tower) for an overview.
+options:
+    name:
+      description:
+        - The name to use for the host.
+      required: True
+    description:
+      description:
+        - The description to use for the host.
+      required: False
+      default: null
+    inventory:
+      description:
+        - Inventory the host should be made a member of.
+      required: True
+    enabled:
+      description:
+        - If the host should be enabled.
+      required: False
+      default: True
+    variables:
+      description:
+        - Variables to use for the host. Use '@' for a file.
+    state:
+      description:
+        - Desired state of the resource.
+      required: False
+      default: "present"
+      choices: ["present", "absent"]
+    tower_host:
+      description:
+        - URL to your Tower instance.
+      required: False
+      default: null
+    tower_username:
+        description:
+          - Username for your Tower instance.
+        required: False
+        default: null
+    tower_password:
+        description:
+          - Password for your Tower instance.
+        required: False
+        default: null
+    tower_verify_ssl:
+        description:
+          - Dis/allow insecure connections to Tower. If C(no), SSL certificates will not be validated.
+            This should only be used on personally controlled sites using self-signed certificates.
+        required: False
+        default: True
+    tower_config_file:
+      description:
+        - Path to the Tower config file. See notes.
+      required: False
+      default: null
+
+
+requirements:
+  - "python >= 2.6"
+  - "ansible-tower-cli >= 3.0.3"
+
+notes:
+  - If no I(config_file) is provided we will attempt to use the tower-cli library
+    defaults to find your Tower host information.
+  - I(config_file) should contain Tower configuration in the following format
+      host=hostname
+      username=username
+      password=password
+'''
+
+
+EXAMPLES = '''
+- name: Add tower host
+  tower_host:
+    name: localhost
+    description: "Local Host Group"
+    inventory: "Local Inventory"
+    state: present
+    tower_config_file: "~/tower_cli.cfg"
+'''
+
+
+try:
+    import os
+    import tower_cli
+    import tower_cli.utils.exceptions as exc
+
+    from tower_cli.conf import settings
+    from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode
+
+    HAS_TOWER_CLI = True
+except ImportError:
+    HAS_TOWER_CLI = False
+
+
+def main():
+    module = AnsibleModule(
+        argument_spec = dict(
+            name = dict(required=True),
+            description = dict(),
+            inventory = dict(required=True),
+            enabled = dict(type='bool', default=True),
+            variables = dict(),
+            tower_host = dict(),
+            tower_username = dict(),
+            tower_password = dict(no_log=True),
+            tower_verify_ssl = dict(type='bool', default=True),
+            tower_config_file = dict(type='path'),
+            state = dict(choices=['present', 'absent'], default='present'),
+        ),
+        supports_check_mode=True
+    )
+
+    if not HAS_TOWER_CLI:
+        module.fail_json(msg='ansible-tower-cli required for this module')
+
+    name = module.params.get('name')
+    description = module.params.get('description')
+    inventory = module.params.get('inventory')
+    enabled = module.params.get('enabled')
+    state = module.params.get('state')
+
+    variables = module.params.get('variables')
+    if variables:
+        if variables.startswith('@'):
+            filename = os.path.expanduser(variables[1:])
+            variables = module.contents_from_file(filename)
+
+    json_output = {'host': name, 'state': state}
+
+    tower_auth = tower_auth_config(module)
+    with settings.runtime_values(**tower_auth):
+        tower_check_mode(module)
+        host = tower_cli.get_resource('host')
+
+        try:
+            inv_res = tower_cli.get_resource('inventory')
+            inv = inv_res.get(name=inventory)
+
+            if state == 'present':
+                result = host.modify(name=name, inventory=inv['id'], enabled=enabled,
+                                    variables=variables, description=description, create_on_missing=True)
+                json_output['id'] = result['id']
+            elif state == 'absent':
+                result = host.delete(name=name, inventory=inv['id'])
+        except (exc.NotFound) as excinfo:
+            module.fail_json(msg='Failed to update host, inventory not found: {0}'.format(excinfo), changed=False)
+        except (exc.ConnectionError, exc.BadRequest) as excinfo:
+            module.fail_json(msg='Failed to update host: {0}'.format(excinfo), changed=False)
+
+    json_output['changed'] = result['changed']
+    module.exit_json(**json_output)
+
+
+from ansible.module_utils.basic import AnsibleModule
+if __name__ == '__main__':
+    main()