From 6140308675d184b9198a2b204005aa709cb50b6d Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Mon, 30 Jan 2017 13:42:32 -0500 Subject: [PATCH 001/103] Ansible Tower organization module (#20355) * add Ansible Tower organization module * skip Python 2.4 check for ansible_tower module * make spec and doc match, extract tower auth helper method * added auth params at module level * support check mode * extract check mode check to ansible_tower utils, add utils to 2.4 skip * update interpreter shebang * remove colon from docs * no log for password, verify_ssl default to true --- lib/ansible/module_utils/ansible_tower.py | 77 +++++++++ .../ansible_tower/__init__.py | 0 .../ansible_tower/tower_organization.py | 152 ++++++++++++++++++ 3 files changed, 229 insertions(+) create mode 100644 lib/ansible/module_utils/ansible_tower.py create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/__init__.py create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py new file mode 100644 index 0000000000..3055ddfd83 --- /dev/null +++ b/lib/ansible/module_utils/ansible_tower.py @@ -0,0 +1,77 @@ +# This code is part of Ansible, but is an independent component. +# This particular file snippet, and this file snippet only, is BSD licensed. +# Modules you write using this snippet, which is embedded dynamically by Ansible +# still belong to the author of the module, and may assign their own license +# to the complete work. +# +# Copyright (c), Wayne Witzel III +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE +# USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import os + +import tower_cli.utils.exceptions as exc +from tower_cli.utils import parser +from tower_cli.api import client + + +def tower_auth_config(module): + '''tower_auth_config attempts to load the tower-cli.cfg file + specified from the `tower_config_file` parameter. If found, + if returns the contents of the file as a dictionary, else + it will attempt to fetch values from the module pararms and + only pass those values that have been set. + ''' + config_file = module.params.get('tower_config_file') + if config_file: + config_file = os.path.expanduser(config_file) + if not os.path.exists(config_file): + module.fail_json(msg='file not found: %s' % config_file) + if os.path.isdir(config_file): + module.fail_json(msg='directory can not be used as config file: %s' % config_file) + + with open(config_file, 'rb') as f: + return parser.string_to_dict(f.read()) + else: + auth_config = {} + host = module.params.get('host') + if host: + auth_config['host'] = host + username = module.params.get('username') + if username: + auth_config['username'] = username + password = module.params.get('password') + if password: + auth_config['password'] = password + verify_ssl = module.params.get('verify_ssl') + if verify_ssl: + auth_config['verify_ssl'] = verify_ssl + return auth_config + + +def tower_check_mode(module): + '''Execute check mode logic for Ansible Tower modules''' + if module.check_mode: + try: + result = client.get('/ping').json() + module.exit_json(changed=True, tower_version='{0}'.format(result['version'])) + except (exc.ServerError, exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(changed=False, msg='Failed check mode: {0}'.format(excinfo)) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/__init__.py b/lib/ansible/modules/web_infrastructure/ansible_tower/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py new file mode 100644 index 0000000000..f661bc4fee --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -0,0 +1,152 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +DOCUMENTATION = ''' +--- +module: tower_organization +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower organizations +description: + - Create, update, or destroy Ansible Tower organizations. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - Name to use for the organization. + required: True + description: + description: + - String to use for the organization. + required: False + default: null + state: + description: + - Desired state of the resource. + required: False + default: "present" + choices: ["present", "absent"] + host: + description: + - URL to your Tower instance. + required: False + default: null + username: + description: + - Username for your Tower instance. + required: False + default: null + password: + description: + - Password for your Tower instance. + required: False + default: null + 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: 'yes' + 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(tower_config_file) is provided we will attempt to use the tower-cli library + defaults to find your Tower host information. + - I(tower_config_file) should contain Tower configuration in the following format + host=hostname + username=username + password=password +''' + + +EXAMPLES = ''' + - tasks + - name: Create organization + tower_organization: + name: "Foo" + description: "Foo bar organization" + state: present + tower_config_file: "~/tower_cli.cfg" +''' + +import os + +try: + 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(), + host = dict(), + username = dict(), + password = dict(no_log=True), + verify_ssl = dict(type='bool', default='yes'), + 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') + state = module.params.get('state') + + json_output = {'organization': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + organization = tower_cli.get_resource('organization') + try: + if state == 'present': + result = organization.modify(name=name, description=description, create_on_missing=True) + json_output['id'] = result['id'] + elif state == 'absent': + result = organization.delete(name=name) + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to update the organization: {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() From 16e6b3f148eb2795b7da70b8482cb1044a86f4c6 Mon Sep 17 00:00:00 2001 From: Brian Coca Date: Mon, 30 Jan 2017 13:42:58 -0500 Subject: [PATCH 002/103] updated friendlier description --- .../web_infrastructure/ansible_tower/tower_organization.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index f661bc4fee..8788f58ef0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -31,7 +31,7 @@ options: required: True description: description: - - String to use for the organization. + - The description to use for the organization. required: False default: null state: From 788a2e5fc89ab50fb6cf43d12d1de0e8d222b6c3 Mon Sep 17 00:00:00 2001 From: Matt Martz Date: Thu, 2 Feb 2017 13:45:22 -0600 Subject: [PATCH 003/103] Update validate-modules (#20932) * Update validate-modules * Validates ANSIBLE_METADATA * Ensures imports happen after documentation vars * Some pep8 cleanup * Clean up some left over unneeded code * Update modules for new module guidelines and validate-modules checks * Update imports for ec2_vpc_route_table and ec2_vpc_nat_gateway --- .../web_infrastructure/ansible_tower/tower_organization.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 8788f58ef0..7c1d3397ac 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -16,6 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + DOCUMENTATION = ''' --- module: tower_organization From 0699e44b53074bac826f8ffabedccecf4fbda153 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Wed, 15 Feb 2017 11:59:03 -0500 Subject: [PATCH 004/103] Ansible Tower user and credential module (#21020) * rename tower config module parameters to avoid conflicts * add Ansible Tower user module * add Ansible Tower credential module * remove errant hash from interpreter line * friendlier error messages * Update tower_verify_ssl defaults and module examples * Update tower_verify_ssl default documentation * Tower expects satellite6 not foreman --- lib/ansible/module_utils/ansible_tower.py | 8 +- .../ansible_tower/tower_credential.py | 298 ++++++++++++++++++ .../ansible_tower/tower_organization.py | 33 +- .../ansible_tower/tower_user.py | 199 ++++++++++++ 4 files changed, 516 insertions(+), 22 deletions(-) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index 3055ddfd83..85980c3469 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -52,16 +52,16 @@ def tower_auth_config(module): return parser.string_to_dict(f.read()) else: auth_config = {} - host = module.params.get('host') + host = module.params.get('tower_host') if host: auth_config['host'] = host - username = module.params.get('username') + username = module.params.get('tower_username') if username: auth_config['username'] = username - password = module.params.get('password') + password = module.params.get('tower_password') if password: auth_config['password'] = password - verify_ssl = module.params.get('verify_ssl') + verify_ssl = module.params.get('tower_verify_ssl') if verify_ssl: auth_config['verify_ssl'] = verify_ssl return auth_config diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py new file mode 100644 index 0000000000..9b17e0bd8d --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -0,0 +1,298 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_credential +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower credential. +description: + - Create, update, or destroy Ansible Tower credentials. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - The name to use for the credential. + required: True + description: + description: + - The description to use for the credential. + user: + description: + - User that should own this credential. + required: False + default: null + team: + description: + - Team that should own this credential. + required: False + default: null + project: + description: + - Project that should for this credential. + required: False + default: null + organization: + description: + - Organization that should own the credential. + required: False + default: null + kind: + description: + - Type of credential being added. + required: True + choices: ["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", "cloudforms", "gce", "azure", "azure_rm", "openstack"] + host: + description: + - Host for this credential. + required: False + default: null + username: + description: + - Username for this credential. access_key for AWS. + required: False + default: null + password: + description: + - Password for this credential. Use ASK for prompting. secret_key for AWS. api_key for RAX. + required: False + default: null + ssh_key_data: + description: + - Path to SSH private key. + required: False + default: null + ssh_key_unlock: + description: + - Unlock password for ssh_key. Use ASK for prompting. + authorize: + description: + - Should use authroize for net type. + required: False + default: False + authorize_password: + description: + - Password for net credentials that require authroize. + required: False + default: null + client: + description: + - Client or application ID for azure_rm type. + required: False + default: null + secret: + description: + - Secret token for azure_rm type. + required: False + default: null + subscription: + description: + - Subscription ID for azure_rm type. + required: False + default: null + tenant: + description: + - Tenant ID for azure_rm type. + required: False + default: null + domain: + description: + - Domain for openstack type. + required: False + default: null + become_method: + description: + - Become method to Use for privledge escalation. + required: False + choices: ["None", "sudo", "su", "pbrun", "pfexec"] + default: "None" + become_username: + description: + - Become username. Use ASK for prompting. + required: False + default: null + become_password: + description: + - Become password. Use ASK for prompting. + required: False + default: null + vault_password: + description: + - Valut password. Use ASK for prompting. + 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.2" + +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 credential + tower_credential: + name: Team Name + description: Team Description + organization: test-org + 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), + user = dict(), + team = dict(), + kind = dict(required=True, + choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", + "cloudforms", "gce", "azure", "azure_rm", "openstack"]), + host = dict(), + username = dict(), + password = dict(no_log=True), + ssh_key_data = dict(no_log=True), + ssh_key_unlock = dict(no_log=True), + authorize = dict(type='bool', default=False), + authorize_password = dict(no_log=True), + client = dict(), + secret = dict(), + tenant = dict(), + subscription = dict(), + domain = dict(), + become_method = dict(), + become_username = dict(), + become_password = dict(no_log=True), + vault_password = dict(no_log=True), + description = dict(), + organization = dict(required=True), + project = 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') + organization = module.params.get('organization') + state = module.params.get('state') + + json_output = {'credential': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + credential = tower_cli.get_resource('credential') + try: + params = module.params.copy() + params['create_on_missing'] = True + + if organization: + org_res = tower_cli.get_resource('organization') + org = org_res.get(name=organization) + params['organization'] = org['id'] + + if params['ssh_key_data']: + filename = params['ssh_key_data'] + filename = os.path.expanduser(filename) + if not os.path.exists(filename): + module.fail_json(msg='file not found: %s' % filename) + if os.path.isdir(filename): + module.fail_json(msg='attempted to read contents of directory: %s' % filename) + with open(filename, 'rb') as f: + params['ssh_key_data'] = f.read() + + if state == 'present': + result = credential.modify(**params) + json_output['id'] = result['id'] + elif state == 'absent': + result = credential.delete(**params) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update credential, organization not found: {0}'.format(excinfo), changed=False) + except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update credential: {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() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 7c1d3397ac..406c380434 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -44,27 +44,27 @@ options: required: False default: "present" choices: ["present", "absent"] - host: + tower_host: description: - URL to your Tower instance. required: False default: null - username: + tower_username: description: - Username for your Tower instance. required: False default: null - password: + tower_password: description: - Password for your Tower instance. required: False default: null - verify_ssl: + 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: 'yes' + default: True tower_config_file: description: - Path to the Tower config file. See notes. @@ -87,17 +87,14 @@ notes: EXAMPLES = ''' - - tasks - - name: Create organization - tower_organization: - name: "Foo" - description: "Foo bar organization" - state: present - tower_config_file: "~/tower_cli.cfg" +- name: Create tower organization + tower_organization: + name: "Foo" + description: "Foo bar organization" + state: present + tower_config_file: "~/tower_cli.cfg" ''' -import os - try: import tower_cli import tower_cli.utils.exceptions as exc @@ -115,10 +112,10 @@ def main(): argument_spec = dict( name = dict(required=True), description = dict(), - host = dict(), - username = dict(), - password = dict(no_log=True), - verify_ssl = dict(type='bool', default='yes'), + 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'), ), diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py new file mode 100644 index 0000000000..ad879a7329 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -0,0 +1,199 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_user +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower user. +description: + - Create, update, or destroy Ansible Tower users. See + U(https://www.ansible.com/tower) for an overview. +options: + username: + description: + - The username of the user. + required: True + first_name: + description: + - First name of the user. + required: False + default: null + last_name: + description: + - Last name of the user. + required: False + default: null + email: + description: + - Email address of the user. + required: True + password: + description: + - Password of the user. + required: False + default: null + organization: + description: + - Organization the user should be made a member of. + required: False + default: null + superuser: + description: + - User is a system wide administator. + required: False + default: False + auditor: + description: + - User is a system wide auditor. + required: False + default: False + 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 user + tower_user: + username: jdoe + password: foobarbaz + email: jdoe@example.org + first_name: John + last_name: Doe + state: present + tower_config_file: "~/tower_cli.cfg" +''' + +try: + 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( + username = dict(required=True), + first_name = dict(), + last_name = dict(), + password = dict(no_log=True), + email = dict(required=True), + organization = dict(), + superuser = dict(type='bool', default=False), + auditor = dict(type='bool', default=False), + 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') + + username = module.params.get('username') + first_name = module.params.get('first_name') + last_name = module.params.get('last_name') + password = module.params.get('password') + email = module.params.get('email') + organization = module.params.get('organization') + superuser = module.params.get('superuser') + auditor = module.params.get('auditor') + state = module.params.get('state') + + json_output = {'username': username, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + user = tower_cli.get_resource('user') + try: + if state == 'present': + result = user.modify(username=username, first_name=first_name, last_name=last_name, + email=email, password=password, organization=organization, + is_superuser=superuser, is_auditor=auditor, create_on_missing=True) + json_output['id'] = result['id'] + elif state == 'absent': + result = user.delete(username=username) + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to update the user: {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() From 962668389a767ae16136dd85266020ee7427ea69 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Fri, 17 Feb 2017 11:17:41 -0500 Subject: [PATCH 005/103] Add Tower Label module (#21485) --- .../ansible_tower/tower_label.py | 160 ++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py new file mode 100644 index 0000000000..4ed81f8445 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -0,0 +1,160 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_label +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower label. +description: + - Create, update, or destroy Ansible Tower labels. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - Name to use for the label. + required: True + default: null + organization: + description: + - Organization the label should be applied to. + required: True + default: null + 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 label to tower organization + tower_label + name: Custom Label + organization: My Organization + state: present + tower_config_file: "~/tower_cli.cfg" +''' + +try: + 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), + organization = dict(required=True), + 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') + organization = module.params.get('organization') + state = module.params.get('state') + + json_output = {'label': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + label = tower_cli.get_resource('label') + + try: + org_res = tower_cli.get_resource('organization') + org = org_res.get(name=organization) + + if state == 'present': + result = label.modify(name=name, organization=org['id'], create_on_missing=True) + json_output['id'] = result['id'] + elif state == 'absent': + result = label.delete(name=name, organization=org['id']) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update label, organization not found: {0}'.format(excinfo), changed=False) + except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update label: {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() From 2f9b0733bb4e1aabeebaa06a716aaccda06b97fe Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Fri, 17 Feb 2017 11:18:11 -0500 Subject: [PATCH 006/103] Add Tower Inventory module (#21483) --- .../ansible_tower/tower_inventory.py | 175 ++++++++++++++++++ 1 file changed, 175 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py new file mode 100644 index 0000000000..5eac8724c2 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -0,0 +1,175 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_inventory +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower inventory. +description: + - Create, update, or destroy Ansible Tower inventories. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - The name to use for the inventory. + required: True + description: + description: + - The description to use for the inventory. + required: False + default: null + organization: + description: + - Organization the inventory belongs to. + required: True + variables: + description: + - Inventory variables. Use '@' to get from file. + required: False + default: null + 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 inventory + tower_inventory: + name: "Foo Inventory" + description: "Our Foo Cloud Servers" + organization: "Bar Org" + state: present + tower_config_file: "~/tower_cli.cfg" +''' + + +try: + 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(), + organization = dict(required=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') + organization = module.params.get('organization') + variables = module.params.get('variables') + state = module.params.get('state') + + json_output = {'inventory': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + inventory = tower_cli.get_resource('inventory') + + try: + org_res = tower_cli.get_resource('organization') + org = org_res.get(name=organization) + + if state == 'present': + result = inventory.modify(name=name, organization=org['id'], variables=variables, + description=description, create_on_missing=True) + json_output['id'] = result['id'] + elif state == 'absent': + result = inventory.delete(name=name, organization=org['id']) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update inventory, organization not found: {0}'.format(excinfo), changed=False) + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to update inventory: {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() From 2c825b792f97263dd35d1978d6bd937fe2540ce3 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Fri, 17 Feb 2017 11:18:40 -0500 Subject: [PATCH 007/103] 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 0000000000..12562e999b --- /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 +# +# 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 . + +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() From 150c0a9fdc66ee723fd64dfd62eb01abe33020ca Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Fri, 17 Feb 2017 11:19:06 -0500 Subject: [PATCH 008/103] Add Tower Group module (#21480) --- .../ansible_tower/tower_group.py | 252 ++++++++++++++++++ 1 file changed, 252 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py new file mode 100644 index 0000000000..738b5ea071 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -0,0 +1,252 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_group +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower group. +description: + - Create, update, or destroy Ansible Tower groups. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - The name to use for the group. + required: True + description: + description: + - The description to use for the group. + required: False + default: null + inventory: + description: + - Inventory the group should be made a member of. + required: True + variables: + description: + - Variables to use for the group, use '@' for a file. + required: False + default: null + credential: + description: + - Credential to use for the group. + required: False + default: null + source: + description: + - The source to use for this group. + required: False + default: null, + choices: ["manual", "file", "ec2", "rax", "vmware", "gce", "azure", "azure_rm", "openstack", "satellite6" , "cloudforms", "custom"] + source_regions: + description: + - Regions for cloud provider. + required: False + default: null + source_vars: + description: + - Override variables from source with variables from this field. + required: False + default: null + instance_filters: + description: + - Comma-separated list of filter expressions for matching hosts. + required: False + default: null + group_by: + description: + - Limit groups automatically created from inventory source. + required: False + default: null + source_script: + description: + - Inventory script to be used when group type is "custom". + required: False + default: null + overwrite: + description: + - Delete child roups and hosts not found in source. + required: False + default: False + overwrite_vars: + description: + - Override vars in child groups and hosts with those from external source. + required: False + default: null + update_on_launch: + description: + - Refresh inventory data from its source each time a job is run. + required: False + default: False + 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.2" + +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 group + tower_group: + 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), + variables = dict(), + credential = dict(), + source = dict(choices=["manual", "file", "ec2", "rax", "vmware", + "gce", "azure", "azure_rm", "openstack", + "satellite6" , "cloudforms", "custom"], default="manual"), + source_regions = dict(), + source_vars = dict(), + instance_filters = dict(), + group_by = dict(), + source_script = dict(), + overwrite = dict(type='bool', default=False), + overwrite_vars = dict(), + update_on_launch = dict(type='bool' , default=False), + 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') + inventory = module.params.get('inventory') + credential = module.params.get('credential') + 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 = {'group': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + group = tower_cli.get_resource('group') + try: + params = module.params.copy() + params['create_on_missing'] = True + params['variables'] = variables + + inv_res = tower_cli.get_resource('inventory') + inv = inv_res.get(name=inventory) + params['inventory'] = inv['id'] + + if credential: + cred_res = tower_cli.get_resource('credential') + cred = cred_res.get(name=credential) + params['credential'] = cred['id'] + + if state == 'present': + result = group.modify(**params) + json_output['id'] = result['id'] + elif state == 'absent': + result = group.delete(**params) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update the group, inventory not found: {0}'.format(excinfo), changed=False) + except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update the group: {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() From 99027e4b30b8cda0f66acbccd33bfb2a6b1d7853 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Fri, 17 Feb 2017 11:19:33 -0500 Subject: [PATCH 009/103] Add Tower Project module (#21479) --- .../ansible_tower/tower_project.py | 233 ++++++++++++++++++ 1 file changed, 233 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py new file mode 100644 index 0000000000..dda5435bd6 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -0,0 +1,233 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_project +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower projects +description: + - Create, update, or destroy Ansible Tower projects. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - Name to use for the project. + required: True + default: null + description: + description: + - Description to use for the project. + required: False + default: null + scm_type: + description: + - Type of scm resource. + required: False + default: "manual" + choices: ["manual", "git", "hg", "svn"] + scm_url: + description: + - URL of scm resource. + required: False + default: null + local_path: + description: + - The server playbook directory for manual projects. + required: False + default: null + scm_branch: + description: + - The branch to use for the scm resource. + required: False + default: null + scm_credential: + description: + - Name of the credential to use with this scm resource. + required: False + default: null + scm_clean: + description: + - Remove local modifications before updating. + required: False + default: False + scm_delete_on_update: + description: + - Remove the repository completely before updating. + required: False + default: False + scm_update_on_launch: + description: + - Before an update to the local repository before launching a job with this project. + required: False + default: False + organization: + description: + - Primary key of organization for project. + required: False + default: null + 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 project + tower_project: + name: "Foo" + description: "Foo bar project" + organization: "test" + state: present + tower_config_file: "~/tower_cli.cfg" +''' + +try: + 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(), + description = dict(), + organization = dict(), + scm_type = dict(choices=['manual', 'git', 'hg', 'svn'], default='manual'), + scm_url = dict(), + scm_branch = dict(), + scm_credential = dict(), + scm_clean = dict(type='bool', default=False), + scm_delete_on_update = dict(type='bool', default=False), + scm_update_on_launch = dict(type='bool', default=False), + local_path = 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') + organization = module.params.get('organization') + scm_type = module.params.get('scm_type') + if scm_type == "manual": + scm_type = "" + scm_url = module.params.get('scm_url') + local_path = module.params.get('local_path') + scm_branch = module.params.get('scm_branch') + scm_credential = module.params.get('scm_credential') + scm_clean = module.params.get('scm_clean') + scm_delete_on_update = module.params.get('scm_delete_on_update') + scm_update_on_launch = module.params.get('scm_update_on_launch') + state = module.params.get('state') + + json_output = {'project': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + project = tower_cli.get_resource('project') + try: + if state == 'present': + org_res = tower_cli.get_resource('organization') + org = org_res.get(name=organization) + + result = project.modify(name=name, description=description, + organization=org['id'], + scm_type=scm_type, scm_url=scm_url, local_path=local_path, + scm_branch=scm_branch, scm_clean=scm_clean, scm_credential=scm_credential, + scm_delete_on_update=scm_delete_on_update, + scm_update_on_launch=scm_update_on_launch, + create_on_missing=True) + json_output['id'] = result['id'] + elif state == 'absent': + result = project.delete(name=name) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update project, organization not found: {0}'.format(excinfo), changed=False) + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to update project: {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() From 5f2381e9ad897b6fd701db81994c3bbba1ab793b Mon Sep 17 00:00:00 2001 From: John R Barker Date: Fri, 17 Feb 2017 17:31:05 +0000 Subject: [PATCH 010/103] Correct example --- .../modules/web_infrastructure/ansible_tower/tower_label.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index 4ed81f8445..dc6b232582 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -89,7 +89,7 @@ notes: EXAMPLES = ''' - name: Add label to tower organization - tower_label + tower_label: name: Custom Label organization: My Organization state: present From 979adfd16c430f46295931c8b3c9621be57da31f Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Mon, 20 Feb 2017 15:16:32 -0500 Subject: [PATCH 011/103] add Ansible Tower team module (#21593) --- .../ansible_tower/tower_team.py | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py new file mode 100644 index 0000000000..9dd1da9586 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -0,0 +1,164 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_team +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower team. +description: + - Create, update, or destroy Ansible Tower teams. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - Name to use for the team. + required: True + default: null + organization: + description: + - Organization the team should be made a member of. + required: True + default: null + 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: Create tower team + tower_team: + name: Team Name + description: Team Description + organization: test-org + state: present + tower_config_file: "~/tower_cli.cfg" +''' + +try: + 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(), + organization = dict(required=True), + 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') + organization = module.params.get('organization') + state = module.params.get('state') + + json_output = {'team': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + team = tower_cli.get_resource('team') + + try: + org_res = tower_cli.get_resource('organization') + org = org_res.get(name=organization) + + if state == 'present': + result = team.modify(name=name, organization=org['id'], + description=description, create_on_missing=True) + json_output['id'] = result['id'] + elif state == 'absent': + result = team.delete(name=name, organization=org['id']) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update team, organization not found: {0}'.format(excinfo), changed=False) + except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update team: {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() From 8a5914affd3d5bcaa769201955c164330bc74e9f Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Mon, 20 Feb 2017 15:18:04 -0500 Subject: [PATCH 012/103] add Tower JobTemplate module (#21681) * add Tower JobTemplate module * add host_config_key and remove defaults from required parameters --- .../ansible_tower/tower_job_template.py | 327 ++++++++++++++++++ 1 file changed, 327 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py new file mode 100644 index 0000000000..d50f0fce16 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -0,0 +1,327 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_job_template +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower job_template. +description: + - Create, update, or destroy Ansible Tower job templates. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - Name to use for the job_template. + required: True + description: + description: + - Description to use for the job_template. + required: False + default: null + job_type: + description: + - The job_type to use for the job_template. + required: True + choices: ["run", "check", "scan"] + inventory: + description: + - Inventory to use for the job_template. + required: False + default: null + project: + description: + - Project to use for the job_template. + required: True + playbook: + description: + - Playbook to use for the job_template. + required: True + machine_credential: + description: + - Machine_credential to use for the job_template. + required: False + default: null + cloud_credential: + description: + - Cloud_credential to use for the job_template. + required: False + default: null + network_credential: + description: + - The network_credential to use for the job_template. + required: False + default: null + forks: + description: + - The number of parallel or simultaneous processes to use while executing the playbook. + required: False + default: null + limit: + description: + - A host pattern to further constrain the list of hosts managed or affected by the playbook + required: False + default: null + verbosity: + description: + - Control the output level Ansible produces as the playbook runs. + required: False + choices: ["verbose", "debug"] + default: null + job_tags: + description: + - The job_tags to use for the job_template. + required: False + default: null + skip_tags: + description: + - The skip_tags to use for the job_template. + required: False + default: null + host_config_key: + description: + - Allow provisioning callbacks using this host config key. + required: False + default: null + extra_vars_path: + description: + - Path to the extra_vars yaml file. + required: False + default: null + ask_extra_vars: + description: + - Prompt user for extra_vars on launch. + required: False + default: False + ask_tags: + description: + - Prompt user for job tags on launch. + required: False + default: False + ask_job_type: + description: + - Prompt user for job type on launch. + required: False + default: False + ask_inventory: + description: + - Propmt user for inventory on launch. + required: False + default: False + ask_credential: + description: + - Prompt user for credential on launch. + required: False + default: False + become_enabled: + description: + - Should become_enabled. + required: False + default: False + 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: Create tower Ping job template + tower_job_template: + name: Ping + job_type: run + inventory: Local + project: Demo + playbook: ping.yml + machine_credential: Local + state: present + tower_config_file: "~/tower_cli.cfg" +''' + +try: + 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 update_fields(p): + '''This updates the module field names + to match the field names tower-cli expects to make + calling of the modify/delete methods easier. + ''' + params = p.copy() + field_map = { + 'ask_extra_vars': 'ask_variables_on_launch', + 'ask_limit' :'ask_limit_on_launch', + 'ask_tags': 'ask_tags_on_launch', + 'ask_job_type': 'ask_job_type_on_launch', + 'machine_credential': 'credential', + } + + params_update = {} + for old_k, new_k in field_map.items(): + v = params.pop(old_k) + params_update[new_k] = v + + extra_vars = params.get('extra_vars_path') + if extra_vars is not None: + params_update['extra_vars'] = '@' + extra_vars + + params.update(params_update) + return params + + +def update_resources(module, p): + params = p.copy() + identity_map = { + 'project': 'name', + 'inventory': 'name', + 'machine_credential': 'name', + 'network_credential': 'name', + 'cloud_credential': 'name', + } + for k,v in identity_map.items(): + try: + if params[k]: + key = 'credential' if '_credential' in k else k + result = tower_cli.get_resource(key).get(**{v:params[k]}) + params[k] = result['id'] + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update job template: {0}'.format(excinfo), changed=False) + return params + + +def main(): + module = AnsibleModule( + argument_spec = dict( + name = dict(required=True), + description = dict(), + job_type = dict(choices=['run', 'check', 'scan'], required=True), + inventory = dict(), + project = dict(required=True), + playbook = dict(required=True), + machine_credential = dict(), + cloud_credential = dict(), + network_credential = dict(), + forks = dict(type='int'), + limit = dict(), + verbosity = dict(choices=['verbose', 'debug']), + job_tags = dict(), + skip_tags = dict(), + host_config_key = dict(), + extra_vars_path = dict(type='path', required=False), + ask_extra_vars = dict(type='bool', default=False), + ask_limit = dict(type='bool', default=False), + ask_tags = dict(type='bool', default=False), + ask_job_type = dict(type='bool', default=False), + ask_inventory = dict(type='bool', default=False), + ask_credential = dict(type='bool', default=False), + become_enabled = dict(type='bool', default=False), + 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') + state = module.params.get('state') + json_output = {'job_template': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + jt = tower_cli.get_resource('job_template') + + params = update_resources(module, module.params) + params = update_fields(params) + params['create_on_missing'] = True + + try: + if state == 'present': + result = jt.modify(**params) + json_output['id'] = result['id'] + elif state == 'absent': + result = jt.delete(**params) + except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update job template: {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() From bd6e5c25294da9929b6ab0f85ae4a74d1b61deb0 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Mon, 20 Feb 2017 15:18:43 -0500 Subject: [PATCH 013/103] add Ansible Tower role module (#21592) * add Ansible Tower role module * remove owner as choice from role paramenter --- .../ansible_tower/tower_role.py | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py new file mode 100644 index 0000000000..47982f67d7 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -0,0 +1,226 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_role +version_added: "2.3" +short_description: create, update, or destroy Ansible Tower role. +description: + - Create, update, or destroy Ansible Tower roles. See + U(https://www.ansible.com/tower) for an overview. +options: + user: + description: + - User that receives the permissions specified by the role. + required: False + default: null + team: + description: + - Team that receives the permissions specified by the role. + required: False + default: null + role: + description: + - The role type to grant/revoke. + required: True + choices: ["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"] + target_team: + description: + - Team that the role acts on. + required: False + default: null + inventory: + description: + - Inventory the role acts on. + required: False + default: null + job_template: + description: + - The job_template the role acts on. + required: False + default: null + credential: + description: + - Credential the role acts on. + required: False + default: null + organization: + description: + - Organiation the role acts on. + required: False + default: null + project: + description: + - Project the role acts on. + required: False + default: null + 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 jdoe to the member role of My Team + tower_role: + user: jdoe + target_team: "My Team" + role: member + state: present + tower_config_file: "~/tower_cli.cfg" +''' + +try: + 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 update_resources(module, p): + '''update_resources attempts to fetch any of the resources given + by name using their unique field (identity) + ''' + params = p.copy() + identity_map = { + 'user':'username', + 'team':'name', + 'target_team':'name', + 'inventory':'name', + 'job_template':'name', + 'credential':'name', + 'organization':'name', + 'project':'name', + } + for k,v in identity_map.items(): + try: + if params[k]: + key = 'team' if k == 'target_team' else k + result = tower_cli.get_resource(key).get(**{v:params[k]}) + params[k] = result['id'] + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update role, {0} not found: {1}'.format(k, excinfo), changed=False) + return params + + +def main(): + module = AnsibleModule( + argument_spec = dict( + user = dict(), + team = dict(), + role = dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]), + target_team = dict(), + inventory = dict(), + job_template = dict(), + credential = dict(), + organization = dict(), + project = 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') + + role_type = module.params.pop('role') + state = module.params.get('state') + + json_output = {'role': role_type, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + role = tower_cli.get_resource('role') + + params = update_resources(module, module.params) + params['type'] = role_type + + try: + if state == 'present': + result = role.grant(**params) + json_output['id'] = result['id'] + elif state == 'absent': + result = role.revoke(**params) + except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update role: {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() From 3855393cd3ccc4253c744532f818ea7a2c73c0a8 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Wed, 1 Mar 2017 14:57:35 -0500 Subject: [PATCH 014/103] Ansible Tower job_launch module (#22148) * Ansible Tower job_launch module * Added RETURN documentation and fixed import locations * remove superfluos required attributes, make tags a list, and fix some typos * only join tags if they are actually a list * use isinstance instead of type, cleanup imports --- lib/ansible/module_utils/ansible_tower.py | 10 ++ .../ansible_tower/tower_job_launch.py | 167 ++++++++++++++++++ 2 files changed, 177 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index 85980c3469..eefbf76753 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -75,3 +75,13 @@ def tower_check_mode(module): module.exit_json(changed=True, tower_version='{0}'.format(result['version'])) except (exc.ServerError, exc.ConnectionError, exc.BadRequest) as excinfo: module.fail_json(changed=False, msg='Failed check mode: {0}'.format(excinfo)) + + +def tower_argument_spec(): + return 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'), + ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py new file mode 100644 index 0000000000..3a7679d9d1 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -0,0 +1,167 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_job_launch +version_added: "2.3" +short_description: Launch an Ansible Job. +description: + - Launch an Ansible Tower jobs. See + U(https://www.ansible.com/tower) for an overview. +options: + job_template: + description: + - Name of the job_template to use. + required: True + job_explanation: + description: + - Job explanation field. + default: null + job_type: + description: + - Job_type to use for the job, only used if prompt for job_type is set. + choices: ["run", "check", "scan"] + default: null + inventory: + description: + - Inventory to use for the job, only used if prompt for inventory is set. + default: null + credential: + description: + - Credential to use for job, only used if prompt for credential is set. + default: null + extra_vars: + description: + - Extra_vars to use for the job_template. Use '@' for a file. + default: null + limit: + description: + - Limit to use for the job_template. + default: null + tags: + description: + - Specific tags to use for from playbook. + default: null + use_job_endpoint: + description: + - Disable launching jobs from job template. + default: False +extends_documentation_fragment: tower +''' + +EXAMPLES = ''' +- name: Launch a job + tower_job_launch: + job_template: "My Job Template" + register: job +- name: Wait for job max 120s + tower_job_wait: + job_id: job.id + timeout: 120 +''' + +RETURN = ''' +id: + description: job id of the newly launched job + returned: success + type: int + sample: 86 +status: + description: status of newly launched job + returned: success + type: string + sample: pending +''' + + +from ansible.module_utils.basic import AnsibleModule + +try: + 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, + tower_argument_spec, + ) + + HAS_TOWER_CLI = True +except ImportError: + HAS_TOWER_CLI = False + + +def main(): + argument_spec = tower_argument_spec() + argument_spec.update(dict( + job_template = dict(required=True), + job_type = dict(choices=['run', 'check', 'scan']), + inventory = dict(), + credential = dict(), + limit = dict(), + tags = dict(type='list'), + extra_vars = dict(type='list'), + )) + + module = AnsibleModule( + argument_spec, + supports_check_mode=True + ) + + if not HAS_TOWER_CLI: + module.fail_json(msg='ansible-tower-cli required for this module') + + json_output = {} + tags = module.params.get('tags') + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + try: + params = module.params.copy() + if isinstance(tags, list): + params['tags'] = ','.join(tags) + job = tower_cli.get_resource('job') + + lookup_fields = ('job_template', 'inventory', 'credential') + for field in lookup_fields: + try: + name = params.pop(field) + result = tower_cli.get_resource(field).get(name=name) + params[field] = result['id'] + except exc.NotFound as excinfo: + module.fail_json(msg='Unable to launch job, {0}/{1} was not found: {2}'.format(field, name, excinfo), changed=False) + + result = job.launch(no_input=True, **params) + json_output['id'] = result['id'] + json_output['status'] = result['status'] + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Unable to launch job: {0}'.format(excinfo), changed=False) + + json_output['changed'] = result['changed'] + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From 85977be23c8846f1d2a03382226a765ab61cd154 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Thu, 2 Mar 2017 09:33:39 -0500 Subject: [PATCH 015/103] Ansible Tower job list module (#22164) --- .../ansible_tower/tower_job_list.py | 147 ++++++++++++++++++ 1 file changed, 147 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py new file mode 100644 index 0000000000..5c9c82f7f3 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -0,0 +1,147 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_job_list +version_added: "2.3" +short_description: List Ansible Tower jobs. +description: + - List Ansible Tower jobs. See + U(https://www.ansible.com/tower) for an overview. +options: + status: + description: + - Only list jobs with this status. + default: null + choices: ['pending', 'waiting', 'running', 'error', 'failed', 'canceled', 'successful'] + page: + description: + - Page number of the results to fetch. + default: null + all_pages: + description: + - Fetch all the pages and return a single result. + default: False + query: + description: + - Query used to further filter the list of jobs. {"foo":"bar"} will be passed at ?foo=bar + default: null +extends_documentation_fragment: tower +''' + + +EXAMPLES = ''' +- name: List running jobs for the testing.yml playbook + tower_job_list: + status: running + query: {"playbook": "testing.yml"} + register: testing_jobs + tower_config_file: "~/tower_cli.cfg" +''' + +RETURN = ''' +count: + description: Total count of objects return + returned: success + type: int + sampled: 51 +next: + description: next page available for the listing + returned: success + type: int + sample: 3 +previous: + description: previous page available for the listing + returned: success + type: int + sample: 1 +results: + description: a list of job objects represented as dictionaries + returned: success + type: list + sample: [{"allow_simultaneous": false, "artifacts": {}, "ask_credential_on_launch": false, + "ask_inventory_on_launch": false, "ask_job_type_on_launch": false, "failed": false, + "finished": "2017-02-22T15:09:05.633942Z", "force_handlers": false, "forks": 0, "id": 2, + "inventory": 1, "job_explanation": "", "job_tags": "", "job_template": 5, "job_type": "run"}, ...] +''' + + +from ansible.module_utils.basic import AnsibleModule + +try: + 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, + tower_argument_spec, + ) + + HAS_TOWER_CLI = True +except ImportError: + HAS_TOWER_CLI = False + + +def main(): + argument_spec = tower_argument_spec() + argument_spec.update(dict( + status = dict(choices=['pending', 'waiting', 'running', 'error', 'failed', 'canceled', 'successful']), + page = dict(type='int'), + all_pages = dict(type='bool', default=False), + query = dict(type='dict'), + )) + + module = AnsibleModule( + argument_spec = argument_spec, + supports_check_mode=True + ) + + if not HAS_TOWER_CLI: + module.fail_json(msg='ansible-tower-cli required for this module') + + json_output = {} + + query = module.params.get('query') + status = module.params.get('status') + page = module.params.get('page') + all_pages = module.params.get('all_pages') + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + try: + job = tower_cli.get_resource('job') + params = {'status':status, 'page':page, 'all_pages': all_pages} + if query: + params['query'] = query.items() + json_output = job.list(**params) + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to list jobs: {0}'.format(excinfo), changed=False) + + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From 6a2e3d29157c1c67789511b39d9dbe96d1c75755 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Thu, 2 Mar 2017 09:33:56 -0500 Subject: [PATCH 016/103] Ansible Tower job cancel module (#22161) * Ansible Tower job cancel module * fix interpreter line --- .../ansible_tower/tower_job_cancel.py | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py new file mode 100644 index 0000000000..2f0042bce0 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -0,0 +1,117 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_job_cancel +version_added: "2.3" +short_description: Cancel an Ansible Tower Job. +description: + - Cancel Ansible Tower jobs. See + U(https://www.ansible.com/tower) for an overview. +options: + job_id: + description: + - ID of the job to cancel + required: True + fail_if_not_running: + description: + - Fail loudly if the job_id does not reference a running job. + default: False +extends_documentation_fragment: tower +''' + +EXAMPLES = ''' +- name: Cancel job + tower_job_cancel: + job_id: job.id +''' + +RETURN = ''' +id: + description: job id requesting to cancel + returned: success + type: int + sample: 94 +status: + description: status of the cancel request + returned: success + type: string + sample: canceled +''' + + +from ansible.module_utils.basic import AnsibleModule + +try: + 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, + tower_argument_spec, + ) + + HAS_TOWER_CLI = True +except ImportError: + HAS_TOWER_CLI = False + + +def main(): + argument_spec = tower_argument_spec() + argument_spec.update(dict( + job_id = dict(type='int', required=True), + fail_if_not_running = dict(type='bool', default=False), + )) + + module = AnsibleModule( + argument_spec = argument_spec, + supports_check_mode=True, + ) + + if not HAS_TOWER_CLI: + module.fail_json(msg='ansible-tower-cli required for this module') + + job_id = module.params.get('job_id') + json_output = {} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + job = tower_cli.get_resource('job') + params = module.params.copy() + + try: + result = job.cancel(job_id, **params) + json_output['id'] = job_id + except (exc.ConnectionError, exc.BadRequest, exc.TowerCLIError) as excinfo: + module.fail_json(msg='Unable to cancel job_id/{0}: {1}'.format(job_id, excinfo), changed=False) + + json_output['changed'] = result['changed'] + json_output['status'] = result['status'] + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From 9c6c9c3708515063f9b93c71d516de81fc19a1f2 Mon Sep 17 00:00:00 2001 From: Wayne Witzel III Date: Thu, 2 Mar 2017 09:34:23 -0500 Subject: [PATCH 017/103] Ansible Tower job_wait module (#22160) * Ansible Tower job_wait module * clean up documentation and update code comment --- .../ansible_tower/tower_job_wait.py | 169 ++++++++++++++++++ 1 file changed, 169 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py new file mode 100644 index 0000000000..166d0a277f --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -0,0 +1,169 @@ +#!/usr/bin/python +#coding: utf-8 -*- + +# (c) 2017, Wayne Witzel III +# +# 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 . + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'version': '1.0'} + +DOCUMENTATION = ''' +--- +module: tower_job_wait +version_added: "2.3" +short_description: Wait for Ansible Tower job to finish. +description: + - Wait for Ansible Tower job to finish and report success or failure. See + U(https://www.ansible.com/tower) for an overview. +options: + job_id: + description: + - ID of the job to monitor. + required: True + min_interval: + description: + - Minimum interval in seconds, to request an update from Tower. + default: 1 + max_interval: + description: + - Maximum interval in seconds, to request an update from Tower. + default: 30 + timeout: + description: + - Maximum time in seconds to wait for a job to finish. + default: null +extends_documentation_fragment: tower +''' + +EXAMPLES = ''' +- name: Launch a job + tower_job_launch: + job_template: "My Job Template" + register: job +- name: Wait for job max 120s + tower_job_wait: + job_id: job.id + timeout: 120 +''' + +RETURN = ''' +id: + description: job id that is being waited on + returned: success + type: int + sample: 99 +elapsed: + description: total time in seconds the job took to run + returned: success + type: float + sample: 10.879 +started: + description: timestamp of when the job started running + returned: success + type: string + sample: 2017-03-01T17:03:53.200234Z +finished: + description: timestamp of when the job finished running + returned: success + type: string + sample: 2017-03-01T17:04:04.078782Z +status: + description: current status of job + returned: success + type: string + sample: successful +''' + + +from ansible.module_utils.basic import AnsibleModule + +try: + from cStringIO import StringIO +except ImportError: + from StringIO import StringIO + +try: + 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, + tower_argument_spec, + ) + + HAS_TOWER_CLI = True +except ImportError: + HAS_TOWER_CLI = False + + +def main(): + argument_spec = tower_argument_spec() + argument_spec.update(dict( + job_id = dict(type='int', required=True), + timeout = dict(type='int'), + min_interval = dict(type='float', default=1), + max_interval = dict(type='float', default=30), + )) + + module = AnsibleModule( + argument_spec, + supports_check_mode=True + ) + + if not HAS_TOWER_CLI: + module.fail_json(msg='ansible-tower-cli required for this module') + + json_output = {} + fail_json = None + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + job = tower_cli.get_resource('job') + params = module.params.copy() + + # tower-cli gets very noisy when monitoring. + # We pass in our our outfile to supress the out during our monitor call. + outfile = StringIO() + params['outfile'] = outfile + + job_id = params.get('job_id') + try: + result = job.monitor(job_id, **params) + except exc.Timeout as excinfo: + result = job.status(job_id) + result['id'] = job_id + json_output['msg'] = 'Timeout waiting for job to finish.' + json_output['timeout'] = True + except exc.NotFound as excinfo: + fail_json = dict(msg='Unable to wait, no job_id {0} found: {1}'.format(job_id, excinfo), changed=False) + except (exc.ConnectionError, exc.BadRequest) as excinfo: + fail_json = dict(msg='Unable to wait for job: {0}'.format(excinfo), changed=False) + + if fail_json is not None: + module.fail_json(**fail_json) + + json_output['success'] = True + for k in ('id', 'status', 'elapsed', 'started', 'finished'): + json_output[k] = result.get(k) + + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From bc2a63c4150581073d5b69c5284f38fe2f2fa0df Mon Sep 17 00:00:00 2001 From: John R Barker Date: Thu, 9 Mar 2017 16:20:25 +0000 Subject: [PATCH 018/103] Fix invalid fields in module DOCUMENATION (#22297) * fix module doc fields * More module docs corrections * More module docs corrections * More module docs corrections * More module docs corrections * correct aliases * Review comments * Must quote ':' * More authors * Use suboptions: * restore type: bool * type should be in the same place * More tidyups * authors * Use suboptions * revert * remove duplicate author * More issues post rebase --- .../modules/web_infrastructure/ansible_tower/tower_credential.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_group.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_host.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_inventory.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_job_cancel.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_job_launch.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_job_list.py | 1 + .../web_infrastructure/ansible_tower/tower_job_template.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_job_wait.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_label.py | 1 + .../web_infrastructure/ansible_tower/tower_organization.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_project.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_role.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_team.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_user.py | 1 + 15 files changed, 15 insertions(+) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 9b17e0bd8d..57f66f4bac 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_credential +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: create, update, or destroy Ansible Tower credential. description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 738b5ea071..bb0bafc94d 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_group +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: create, update, or destroy Ansible Tower group. description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 12562e999b..77819f4446 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -24,6 +24,7 @@ DOCUMENTATION = ''' --- module: tower_host version_added: "2.3" +author: "Wayne Witzel III (@wwitzel3)" short_description: create, update, or destroy Ansible Tower host. description: - Create, update, or destroy Ansible Tower hosts. See diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 5eac8724c2..71983e0414 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -24,6 +24,7 @@ DOCUMENTATION = ''' --- module: tower_inventory version_added: "2.3" +author: "Wayne Witzel III (@wwitzel3)" short_description: create, update, or destroy Ansible Tower inventory. description: - Create, update, or destroy Ansible Tower inventories. See diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index 2f0042bce0..70b2f9ec2b 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_job_cancel +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: Cancel an Ansible Tower Job. description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 3a7679d9d1..4d1d5fdf85 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_job_launch +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: Launch an Ansible Job. description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 5c9c82f7f3..3b32b82bb3 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_job_list +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: List Ansible Tower jobs. description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index d50f0fce16..f06e84267c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_job_template +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: create, update, or destroy Ansible Tower job_template. description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 166d0a277f..c1e9db7748 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -24,6 +24,7 @@ DOCUMENTATION = ''' --- module: tower_job_wait version_added: "2.3" +author: "Wayne Witzel III (@wwitzel3)" short_description: Wait for Ansible Tower job to finish. description: - Wait for Ansible Tower job to finish and report success or failure. See diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index dc6b232582..4f8403bab0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_label +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: create, update, or destroy Ansible Tower label. description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 406c380434..721e139770 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -24,6 +24,7 @@ DOCUMENTATION = ''' --- module: tower_organization version_added: "2.3" +author: "Wayne Witzel III (@wwitzel3)" short_description: create, update, or destroy Ansible Tower organizations description: - Create, update, or destroy Ansible Tower organizations. See diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index dda5435bd6..0079fa4a51 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_project +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: create, update, or destroy Ansible Tower projects description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 47982f67d7..4538bb1900 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -24,6 +24,7 @@ DOCUMENTATION = ''' --- module: tower_role version_added: "2.3" +author: "Wayne Witzel III (@wwitzel3)" short_description: create, update, or destroy Ansible Tower role. description: - Create, update, or destroy Ansible Tower roles. See diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index 9dd1da9586..29a3cd8dc1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_team +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: create, update, or destroy Ansible Tower team. description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index ad879a7329..85d3ed6e63 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -23,6 +23,7 @@ ANSIBLE_METADATA = {'status': ['preview'], DOCUMENTATION = ''' --- module: tower_user +author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" short_description: create, update, or destroy Ansible Tower user. description: From 7cdde96c3c5a2419260d06875b1f2adbd8471803 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Tue, 14 Mar 2017 09:07:22 -0700 Subject: [PATCH 019/103] New metadata 1.0 (#22587) Changes to the metadata format were approved here: https://github.com/ansible/proposals/issues/54 * Update documentation to the new metadata format * Changes to metadata-tool to account for new metadata * Add GPL license header * Add upgrade subcommand to upgrade metadata version * Change default metadata to the new format * Fix exclusion of non-modules from the metadata report * Fix ansible-doc for new module metadata * Exclude metadata version from ansible-doc output * Fix website docs generation for the new metadata * Update metadata schema in valiate-modules test * Update the metadata in all modules to the new version --- .../web_infrastructure/ansible_tower/tower_credential.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_group.py | 7 ++++--- .../modules/web_infrastructure/ansible_tower/tower_host.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_inventory.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_job_cancel.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_job_launch.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_job_list.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_job_template.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_job_wait.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_label.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_organization.py | 7 ++++--- .../web_infrastructure/ansible_tower/tower_project.py | 7 ++++--- .../modules/web_infrastructure/ansible_tower/tower_role.py | 7 ++++--- .../modules/web_infrastructure/ansible_tower/tower_team.py | 7 ++++--- .../modules/web_infrastructure/ansible_tower/tower_user.py | 7 ++++--- 15 files changed, 60 insertions(+), 45 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 57f66f4bac..be1fc7f43a 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index bb0bafc94d..646c3f9ca4 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 77819f4446..6d9d129de0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 71983e0414..60af48c7a1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index 70b2f9ec2b..8cb8fabab2 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 4d1d5fdf85..2a0d8ac2f2 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 3b32b82bb3..9f68c845c9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index f06e84267c..13d4e99064 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index c1e9db7748..a9d42a6d49 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index 4f8403bab0..e0a0c6c3ee 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 721e139770..0b537e45cb 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 0079fa4a51..7d5048c95b 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 4538bb1900..49799ab1ff 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index 29a3cd8dc1..d025317afe 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 85d3ed6e63..106ae038ee 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -16,9 +16,10 @@ # You should have received a copy of the GNU General Public License # along with this software. If not, see . -ANSIBLE_METADATA = {'status': ['preview'], - 'supported_by': 'community', - 'version': '1.0'} +ANSIBLE_METADATA = {'metadata_version': '1.0', + 'status': ['preview'], + 'supported_by': 'community'} + DOCUMENTATION = ''' --- From 9469bbc06fa51ab99b4237cf26fde9649076c455 Mon Sep 17 00:00:00 2001 From: Andrea Tartaglia Date: Wed, 26 Apr 2017 15:56:13 +0100 Subject: [PATCH 020/103] fixed RETURN docs for modules (#24011) * fixed RETURN docs for remaining modules * updated proxymysql_mysql_users 'sample' to yaml dict * fixed whitespace errors --- .../web_infrastructure/ansible_tower/tower_job_list.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_wait.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 9f68c845c9..0c259931cd 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -66,7 +66,7 @@ count: description: Total count of objects return returned: success type: int - sampled: 51 + sample: 51 next: description: next page available for the listing returned: success diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index a9d42a6d49..9a9e21dfa2 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -76,12 +76,12 @@ started: description: timestamp of when the job started running returned: success type: string - sample: 2017-03-01T17:03:53.200234Z + sample: "2017-03-01T17:03:53.200234Z" finished: description: timestamp of when the job finished running returned: success type: string - sample: 2017-03-01T17:04:04.078782Z + sample: "2017-03-01T17:04:04.078782Z" status: description: current status of job returned: success From 62bc1a8662ad6e342c344bbac34055f63a8db3f7 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Thu, 11 May 2017 21:56:36 +0530 Subject: [PATCH 021/103] Pep8 fixes for web_infra/ansible_tower (#24479) Signed-off-by: Abhijeet Kasurde --- .../ansible_tower/tower_credential.py | 66 +++++++++--------- .../ansible_tower/tower_group.py | 48 ++++++------- .../ansible_tower/tower_host.py | 28 ++++---- .../ansible_tower/tower_inventory.py | 26 +++---- .../ansible_tower/tower_job_cancel.py | 8 +-- .../ansible_tower/tower_job_launch.py | 16 ++--- .../ansible_tower/tower_job_list.py | 14 ++-- .../ansible_tower/tower_job_template.py | 68 +++++++++---------- .../ansible_tower/tower_job_wait.py | 10 +-- .../ansible_tower/tower_label.py | 20 +++--- .../ansible_tower/tower_organization.py | 20 +++--- .../ansible_tower/tower_project.py | 38 +++++------ .../ansible_tower/tower_role.py | 54 +++++++-------- .../ansible_tower/tower_team.py | 24 +++---- .../ansible_tower/tower_user.py | 36 +++++----- 15 files changed, 238 insertions(+), 238 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index be1fc7f43a..ff796ceca3 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -213,38 +213,38 @@ except ImportError: def main(): module = AnsibleModule( - argument_spec = dict( - name = dict(required=True), - user = dict(), - team = dict(), - kind = dict(required=True, - choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", - "cloudforms", "gce", "azure", "azure_rm", "openstack"]), - host = dict(), - username = dict(), - password = dict(no_log=True), - ssh_key_data = dict(no_log=True), - ssh_key_unlock = dict(no_log=True), - authorize = dict(type='bool', default=False), - authorize_password = dict(no_log=True), - client = dict(), - secret = dict(), - tenant = dict(), - subscription = dict(), - domain = dict(), - become_method = dict(), - become_username = dict(), - become_password = dict(no_log=True), - vault_password = dict(no_log=True), - description = dict(), - organization = dict(required=True), - project = 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'), + argument_spec=dict( + name=dict(required=True), + user=dict(), + team=dict(), + kind=dict(required=True, + choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", + "cloudforms", "gce", "azure", "azure_rm", "openstack"]), + host=dict(), + username=dict(), + password=dict(no_log=True), + ssh_key_data=dict(no_log=True), + ssh_key_unlock=dict(no_log=True), + authorize=dict(type='bool', default=False), + authorize_password=dict(no_log=True), + client=dict(), + secret=dict(), + tenant=dict(), + subscription=dict(), + domain=dict(), + become_method=dict(), + become_username=dict(), + become_password=dict(no_log=True), + vault_password=dict(no_log=True), + description=dict(), + organization=dict(required=True), + project=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 ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 646c3f9ca4..bc36a7f878 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -174,29 +174,29 @@ except ImportError: def main(): module = AnsibleModule( - argument_spec = dict( - name = dict(required=True), - description = dict(), - inventory = dict(required=True), - variables = dict(), - credential = dict(), - source = dict(choices=["manual", "file", "ec2", "rax", "vmware", - "gce", "azure", "azure_rm", "openstack", - "satellite6" , "cloudforms", "custom"], default="manual"), - source_regions = dict(), - source_vars = dict(), - instance_filters = dict(), - group_by = dict(), - source_script = dict(), - overwrite = dict(type='bool', default=False), - overwrite_vars = dict(), - update_on_launch = dict(type='bool' , default=False), - 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'), + argument_spec=dict( + name=dict(required=True), + description=dict(), + inventory=dict(required=True), + variables=dict(), + credential=dict(), + source=dict(choices=["manual", "file", "ec2", "rax", "vmware", + "gce", "azure", "azure_rm", "openstack", + "satellite6", "cloudforms", "custom"], default="manual"), + source_regions=dict(), + source_vars=dict(), + instance_filters=dict(), + group_by=dict(), + source_script=dict(), + overwrite=dict(type='bool', default=False), + overwrite_vars=dict(), + update_on_launch=dict(type='bool', default=False), + 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 ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 6d9d129de0..65dfa6eecd 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -126,18 +126,18 @@ except ImportError: 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'), + 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 ) @@ -170,7 +170,7 @@ def main(): if state == 'present': result = host.modify(name=name, inventory=inv['id'], enabled=enabled, - variables=variables, description=description, create_on_missing=True) + variables=variables, description=description, create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': result = host.delete(name=name, inventory=inv['id']) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 60af48c7a1..0ab5704894 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -122,17 +122,17 @@ except ImportError: def main(): module = AnsibleModule( - argument_spec = dict( - name = dict(required=True), - description = dict(), - organization = dict(required=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'), + argument_spec=dict( + name=dict(required=True), + description=dict(), + organization=dict(required=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 ) @@ -159,7 +159,7 @@ def main(): if state == 'present': result = inventory.modify(name=name, organization=org['id'], variables=variables, - description=description, create_on_missing=True) + description=description, create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': result = inventory.delete(name=name, organization=org['id']) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index 8cb8fabab2..0d99242f5e 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -83,12 +83,12 @@ except ImportError: def main(): argument_spec = tower_argument_spec() argument_spec.update(dict( - job_id = dict(type='int', required=True), - fail_if_not_running = dict(type='bool', default=False), + job_id=dict(type='int', required=True), + fail_if_not_running=dict(type='bool', default=False), )) module = AnsibleModule( - argument_spec = argument_spec, + argument_spec=argument_spec, supports_check_mode=True, ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 2a0d8ac2f2..9d2cedef74 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -117,13 +117,13 @@ except ImportError: def main(): argument_spec = tower_argument_spec() argument_spec.update(dict( - job_template = dict(required=True), - job_type = dict(choices=['run', 'check', 'scan']), - inventory = dict(), - credential = dict(), - limit = dict(), - tags = dict(type='list'), - extra_vars = dict(type='list'), + job_template=dict(required=True), + job_type=dict(choices=['run', 'check', 'scan']), + inventory=dict(), + credential=dict(), + limit=dict(), + tags=dict(type='list'), + extra_vars=dict(type='list'), )) module = AnsibleModule( diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 0c259931cd..bdc1a272c9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -109,14 +109,14 @@ except ImportError: def main(): argument_spec = tower_argument_spec() argument_spec.update(dict( - status = dict(choices=['pending', 'waiting', 'running', 'error', 'failed', 'canceled', 'successful']), - page = dict(type='int'), - all_pages = dict(type='bool', default=False), - query = dict(type='dict'), + status=dict(choices=['pending', 'waiting', 'running', 'error', 'failed', 'canceled', 'successful']), + page=dict(type='int'), + all_pages=dict(type='bool', default=False), + query=dict(type='dict'), )) module = AnsibleModule( - argument_spec = argument_spec, + argument_spec=argument_spec, supports_check_mode=True ) @@ -135,7 +135,7 @@ def main(): tower_check_mode(module) try: job = tower_cli.get_resource('job') - params = {'status':status, 'page':page, 'all_pages': all_pages} + params = {'status': status, 'page': page, 'all_pages': all_pages} if query: params['query'] = query.items() json_output = job.list(**params) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 13d4e99064..aa351d9158 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -220,7 +220,7 @@ def update_fields(p): params = p.copy() field_map = { 'ask_extra_vars': 'ask_variables_on_launch', - 'ask_limit' :'ask_limit_on_launch', + 'ask_limit': 'ask_limit_on_launch', 'ask_tags': 'ask_tags_on_launch', 'ask_job_type': 'ask_job_type_on_launch', 'machine_credential': 'credential', @@ -248,11 +248,11 @@ def update_resources(module, p): 'network_credential': 'name', 'cloud_credential': 'name', } - for k,v in identity_map.items(): + for k, v in identity_map.items(): try: if params[k]: key = 'credential' if '_credential' in k else k - result = tower_cli.get_resource(key).get(**{v:params[k]}) + result = tower_cli.get_resource(key).get(**{v: params[k]}) params[k] = result['id'] except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update job template: {0}'.format(excinfo), changed=False) @@ -261,36 +261,36 @@ def update_resources(module, p): def main(): module = AnsibleModule( - argument_spec = dict( - name = dict(required=True), - description = dict(), - job_type = dict(choices=['run', 'check', 'scan'], required=True), - inventory = dict(), - project = dict(required=True), - playbook = dict(required=True), - machine_credential = dict(), - cloud_credential = dict(), - network_credential = dict(), - forks = dict(type='int'), - limit = dict(), - verbosity = dict(choices=['verbose', 'debug']), - job_tags = dict(), - skip_tags = dict(), - host_config_key = dict(), - extra_vars_path = dict(type='path', required=False), - ask_extra_vars = dict(type='bool', default=False), - ask_limit = dict(type='bool', default=False), - ask_tags = dict(type='bool', default=False), - ask_job_type = dict(type='bool', default=False), - ask_inventory = dict(type='bool', default=False), - ask_credential = dict(type='bool', default=False), - become_enabled = dict(type='bool', default=False), - 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'), + argument_spec=dict( + name=dict(required=True), + description=dict(), + job_type=dict(choices=['run', 'check', 'scan'], required=True), + inventory=dict(), + project=dict(required=True), + playbook=dict(required=True), + machine_credential=dict(), + cloud_credential=dict(), + network_credential=dict(), + forks=dict(type='int'), + limit=dict(), + verbosity=dict(choices=['verbose', 'debug']), + job_tags=dict(), + skip_tags=dict(), + host_config_key=dict(), + extra_vars_path=dict(type='path', required=False), + ask_extra_vars=dict(type='bool', default=False), + ask_limit=dict(type='bool', default=False), + ask_tags=dict(type='bool', default=False), + ask_job_type=dict(type='bool', default=False), + ask_inventory=dict(type='bool', default=False), + ask_credential=dict(type='bool', default=False), + become_enabled=dict(type='bool', default=False), + 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 ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 9a9e21dfa2..7c74e5f1f0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -116,10 +116,10 @@ except ImportError: def main(): argument_spec = tower_argument_spec() argument_spec.update(dict( - job_id = dict(type='int', required=True), - timeout = dict(type='int'), - min_interval = dict(type='float', default=1), - max_interval = dict(type='float', default=30), + job_id=dict(type='int', required=True), + timeout=dict(type='int'), + min_interval=dict(type='float', default=1), + max_interval=dict(type='float', default=30), )) module = AnsibleModule( diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index e0a0c6c3ee..fd1a296b97 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -112,15 +112,15 @@ except ImportError: def main(): module = AnsibleModule( - argument_spec = dict( - name = dict(required=True), - organization = dict(required=True), - 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'), + argument_spec=dict( + name=dict(required=True), + organization=dict(required=True), + 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 ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 0b537e45cb..65741860cc 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -111,15 +111,15 @@ except ImportError: def main(): module = AnsibleModule( - argument_spec = dict( - name = dict(required=True), - description = 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'), + argument_spec=dict( + name=dict(required=True), + description=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 ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 7d5048c95b..30b25d1c08 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -159,25 +159,25 @@ except ImportError: def main(): module = AnsibleModule( - argument_spec = dict( - name = dict(), - description = dict(), - organization = dict(), - scm_type = dict(choices=['manual', 'git', 'hg', 'svn'], default='manual'), - scm_url = dict(), - scm_branch = dict(), - scm_credential = dict(), - scm_clean = dict(type='bool', default=False), - scm_delete_on_update = dict(type='bool', default=False), - scm_update_on_launch = dict(type='bool', default=False), - local_path = 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'), + argument_spec=dict( + name=dict(), + description=dict(), + organization=dict(), + scm_type=dict(choices=['manual', 'git', 'hg', 'svn'], default='manual'), + scm_url=dict(), + scm_branch=dict(), + scm_credential=dict(), + scm_clean=dict(type='bool', default=False), + scm_delete_on_update=dict(type='bool', default=False), + scm_update_on_launch=dict(type='bool', default=False), + local_path=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'), + state=dict(choices=['present', 'absent'], default='present'), ), supports_check_mode=True ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 49799ab1ff..04932d82a6 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -152,20 +152,20 @@ def update_resources(module, p): ''' params = p.copy() identity_map = { - 'user':'username', - 'team':'name', - 'target_team':'name', - 'inventory':'name', - 'job_template':'name', - 'credential':'name', - 'organization':'name', - 'project':'name', + 'user': 'username', + 'team': 'name', + 'target_team': 'name', + 'inventory': 'name', + 'job_template': 'name', + 'credential': 'name', + 'organization': 'name', + 'project': 'name', } - for k,v in identity_map.items(): + for k, v in identity_map.items(): try: if params[k]: key = 'team' if k == 'target_team' else k - result = tower_cli.get_resource(key).get(**{v:params[k]}) + result = tower_cli.get_resource(key).get(**{v: params[k]}) params[k] = result['id'] except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update role, {0} not found: {1}'.format(k, excinfo), changed=False) @@ -174,22 +174,22 @@ def update_resources(module, p): def main(): module = AnsibleModule( - argument_spec = dict( - user = dict(), - team = dict(), - role = dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]), - target_team = dict(), - inventory = dict(), - job_template = dict(), - credential = dict(), - organization = dict(), - project = 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'), + argument_spec=dict( + user=dict(), + team=dict(), + role=dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]), + target_team=dict(), + inventory=dict(), + job_template=dict(), + credential=dict(), + organization=dict(), + project=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 ) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index d025317afe..3eaefa036c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -113,16 +113,16 @@ except ImportError: def main(): module = AnsibleModule( - argument_spec = dict( - name = dict(required=True), - description = dict(), - organization = dict(required=True), - 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'), + argument_spec=dict( + name=dict(required=True), + description=dict(), + organization=dict(required=True), + 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 ) @@ -148,7 +148,7 @@ def main(): if state == 'present': result = team.modify(name=name, organization=org['id'], - description=description, create_on_missing=True) + description=description, create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': result = team.delete(name=name, organization=org['id']) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 106ae038ee..fe04fde5ab 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -1,5 +1,5 @@ #!/usr/bin/python -#coding: utf-8 -*- +# coding: utf-8 -*- # (c) 2017, Wayne Witzel III # @@ -143,21 +143,21 @@ except ImportError: def main(): module = AnsibleModule( - argument_spec = dict( - username = dict(required=True), - first_name = dict(), - last_name = dict(), - password = dict(no_log=True), - email = dict(required=True), - organization = dict(), - superuser = dict(type='bool', default=False), - auditor = dict(type='bool', default=False), - 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'), + argument_spec=dict( + username=dict(required=True), + first_name=dict(), + last_name=dict(), + password=dict(no_log=True), + email=dict(required=True), + organization=dict(), + superuser=dict(type='bool', default=False), + auditor=dict(type='bool', default=False), + 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 ) @@ -184,8 +184,8 @@ def main(): try: if state == 'present': result = user.modify(username=username, first_name=first_name, last_name=last_name, - email=email, password=password, organization=organization, - is_superuser=superuser, is_auditor=auditor, create_on_missing=True) + email=email, password=password, organization=organization, + is_superuser=superuser, is_auditor=auditor, create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': result = user.delete(username=username) From 74c7c7b5326cde06a75e6ea99c327ae9eeb57cc2 Mon Sep 17 00:00:00 2001 From: Lee Shakespeare Date: Wed, 17 May 2017 19:30:14 +0100 Subject: [PATCH 022/103] Tower user remove organization (#24544) * Remove organization field from the tower_user module re: issue #24510 * Fix trailing spaces. * Fixes for Shippable errors, pep8 * Remove a random inserted space. --- .../web_infrastructure/ansible_tower/tower_user.py | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index fe04fde5ab..3b86cd0172 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -54,11 +54,6 @@ options: - Password of the user. required: False default: null - organization: - description: - - Organization the user should be made a member of. - required: False - default: null superuser: description: - User is a system wide administator. @@ -149,7 +144,6 @@ def main(): last_name=dict(), password=dict(no_log=True), email=dict(required=True), - organization=dict(), superuser=dict(type='bool', default=False), auditor=dict(type='bool', default=False), tower_host=dict(), @@ -170,7 +164,6 @@ def main(): last_name = module.params.get('last_name') password = module.params.get('password') email = module.params.get('email') - organization = module.params.get('organization') superuser = module.params.get('superuser') auditor = module.params.get('auditor') state = module.params.get('state') @@ -184,8 +177,8 @@ def main(): try: if state == 'present': result = user.modify(username=username, first_name=first_name, last_name=last_name, - email=email, password=password, organization=organization, - is_superuser=superuser, is_auditor=auditor, create_on_missing=True) + email=email, password=password, is_superuser=superuser, + is_auditor=auditor, create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': result = user.delete(username=username) From 06e09550af26b6467b550209dcf45f8d8644f140 Mon Sep 17 00:00:00 2001 From: Lee Shakespeare Date: Thu, 18 May 2017 23:44:33 +0100 Subject: [PATCH 023/103] Lookup credential id and pass in credential rather than scm_credential (#24624) * Lookup credential id and pass in credential rather than scm_credential * Change the excepting handling to catch missing credentials * Make error messages for not found lookups more useful --- .../ansible_tower/tower_project.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 30b25d1c08..6aeabe7187 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -208,21 +208,27 @@ def main(): project = tower_cli.get_resource('project') try: if state == 'present': - org_res = tower_cli.get_resource('organization') - org = org_res.get(name=organization) + try: + org_res = tower_cli.get_resource('organization') + org = org_res.get(name=organization) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update project, organization not found: {0}'.format(organization), changed=False) + try: + cred_res = tower_cli.get_resource('credential') + cred = cred_res.get(name=scm_credential) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update project, credential not found: {0}'.format(scm_credential), changed=False) result = project.modify(name=name, description=description, organization=org['id'], scm_type=scm_type, scm_url=scm_url, local_path=local_path, - scm_branch=scm_branch, scm_clean=scm_clean, scm_credential=scm_credential, + scm_branch=scm_branch, scm_clean=scm_clean, credential=cred['id'], scm_delete_on_update=scm_delete_on_update, scm_update_on_launch=scm_update_on_launch, create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': result = project.delete(name=name) - except (exc.NotFound) as excinfo: - module.fail_json(msg='Failed to update project, organization not found: {0}'.format(excinfo), changed=False) except (exc.ConnectionError, exc.BadRequest) as excinfo: module.fail_json(msg='Failed to update project: {0}'.format(excinfo), changed=False) From 640e528fdc62451bba2e781908b61207c64a773d Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Fri, 19 May 2017 14:24:54 -0700 Subject: [PATCH 024/103] adds privilege escalation method for pmrun(Unix Privilege Manager 6.0) --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index ff796ceca3..7f87b1d622 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -125,7 +125,7 @@ options: description: - Become method to Use for privledge escalation. required: False - choices: ["None", "sudo", "su", "pbrun", "pfexec"] + choices: ["None", "sudo", "su", "pbrun", "pfexec", "pmrun"] default: "None" become_username: description: From 5ef70033959a4349160b46484c91a88d761a57d6 Mon Sep 17 00:00:00 2001 From: James Labocki Date: Thu, 1 Jun 2017 17:22:22 -0400 Subject: [PATCH 025/103] Fix indentation for register module in example (#25274) --- .../web_infrastructure/ansible_tower/tower_job_launch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 9d2cedef74..1fa3d236b0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -75,7 +75,7 @@ EXAMPLES = ''' - name: Launch a job tower_job_launch: job_template: "My Job Template" - register: job + register: job - name: Wait for job max 120s tower_job_wait: job_id: job.id From 49df11d47856318935c53126eb0e33ad12ce525e Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Fri, 2 Jun 2017 13:14:11 +0200 Subject: [PATCH 026/103] Collated PEP8 fixes (#25293) - Make PEP8 compliant --- lib/ansible/module_utils/ansible_tower.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index eefbf76753..90de99b64f 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -79,9 +79,9 @@ def tower_check_mode(module): def tower_argument_spec(): return 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'), + 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'), ) From 7c0554bf7b74b1a579b41b5899ab4921b51aa6a0 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Fri, 2 Jun 2017 09:29:53 -0400 Subject: [PATCH 027/103] Fix handling of extra_vars_path parameter. (#25272) tower-cli process_extra_vars takes a list. --- .../web_infrastructure/ansible_tower/tower_job_template.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index aa351d9158..2158c5c729 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -233,7 +233,7 @@ def update_fields(p): extra_vars = params.get('extra_vars_path') if extra_vars is not None: - params_update['extra_vars'] = '@' + extra_vars + params_update['extra_vars'] = ['@' + extra_vars] params.update(params_update) return params From fdbafe42aba5bb1de12443f27d2afdc1c135f6af Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Mon, 12 Jun 2017 12:25:19 +0530 Subject: [PATCH 028/103] Fix spelling mistakes (comments only) (#25564) Original Author : klemens Taking over previous PR as per https://github.com/ansible/ansible/pull/23644#issuecomment-307334525 Signed-off-by: Abhijeet Kasurde --- .../modules/web_infrastructure/ansible_tower/tower_job_wait.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 7c74e5f1f0..f36784261b 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -140,7 +140,7 @@ def main(): params = module.params.copy() # tower-cli gets very noisy when monitoring. - # We pass in our our outfile to supress the out during our monitor call. + # We pass in our our outfile to suppress the out during our monitor call. outfile = StringIO() params['outfile'] = outfile From 56723c32030a89921f84553cef7127e718eb9787 Mon Sep 17 00:00:00 2001 From: Christopher Galtenberg Date: Tue, 16 May 2017 18:11:12 -0700 Subject: [PATCH 029/103] Improve help text for extra-vars requiring @ for filename (cherry picked from commit 1b34de89ee1d75cb7f616b5a34cd5043bf7dfd2b) --- .../web_infrastructure/ansible_tower/tower_job_launch.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 1fa3d236b0..648e260632 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -54,7 +54,7 @@ options: default: null extra_vars: description: - - Extra_vars to use for the job_template. Use '@' for a file. + - Extra_vars to use for the job_template. Prepend '@' if a file. default: null limit: description: From e9ec80d86bc4ccc2fc58d6d2a50a7d13a72446a1 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Thu, 27 Jul 2017 22:55:24 -0700 Subject: [PATCH 030/103] Remove wildcard imports Made the following changes: * Removed wildcard imports * Replaced long form of GPL header with short form * Removed get_exception usage * Added from __future__ boilerplate * Adjust division operator to // where necessary For the following files: * web_infrastructure modules * system modules * linode, lxc, lxd, atomic, cloudscale, dimensiondata, ovh, packet, profitbricks, pubnub, smartos, softlayer, univention modules * compat dirs (disabled as its used intentionally) --- .../ansible_tower/tower_credential.py | 18 +++++------------- .../ansible_tower/tower_group.py | 18 +++++------------- .../ansible_tower/tower_host.py | 18 +++++------------- .../ansible_tower/tower_inventory.py | 18 +++++------------- .../ansible_tower/tower_job_cancel.py | 18 +++++------------- .../ansible_tower/tower_job_launch.py | 18 +++++------------- .../ansible_tower/tower_job_list.py | 18 +++++------------- .../ansible_tower/tower_job_template.py | 18 +++++------------- .../ansible_tower/tower_job_wait.py | 18 +++++------------- .../ansible_tower/tower_label.py | 18 +++++------------- .../ansible_tower/tower_organization.py | 18 +++++------------- .../ansible_tower/tower_project.py | 18 +++++------------- .../ansible_tower/tower_role.py | 18 +++++------------- .../ansible_tower/tower_team.py | 18 +++++------------- .../ansible_tower/tower_user.py | 18 +++++------------- 15 files changed, 75 insertions(+), 195 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 7f87b1d622..dc54b7e174 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index bc36a7f878..eb66ba1660 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 65dfa6eecd..e317f7d38f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 0ab5704894..753351a3db 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index 0d99242f5e..569b81313a 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 648e260632..c5204f2aa4 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index bdc1a272c9..cd23abb479 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 2158c5c729..0535e22b70 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index f36784261b..5ac4731f22 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index fd1a296b97..3cf3ac7b09 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 65741860cc..a334c1f1f1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 6aeabe7187..9fd7a73648 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 04932d82a6..a2cfedb53f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index 3eaefa036c..90b23b7a30 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 3b86cd0172..61a8aa5010 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -2,19 +2,11 @@ # coding: utf-8 -*- # (c) 2017, Wayne Witzel III -# -# 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 . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], From d0ffc3f62677955c42f8029d1f78dcd21a42118c Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Tue, 15 Aug 2017 20:16:38 -0700 Subject: [PATCH 031/103] Update metadata to 1.1 --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_group.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_host.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_inventory.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_cancel.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_launch.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_job_list.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_template.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_job_wait.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_label.py | 2 +- .../web_infrastructure/ansible_tower/tower_organization.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_project.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_role.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_team.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_user.py | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index dc54b7e174..eb2734ffc6 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index eb66ba1660..39d392378d 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index e317f7d38f..33ea923dd8 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 753351a3db..6c1326e7bd 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index 569b81313a..c4b83c6186 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index c5204f2aa4..b332edf36e 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index cd23abb479..612e7ba2ad 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 0535e22b70..b907c42fbe 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 5ac4731f22..797450189f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index 3cf3ac7b09..4b3a0196a3 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index a334c1f1f1..249ac7280d 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 9fd7a73648..9ae0d8a70c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index a2cfedb53f..df3340f8fc 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index 90b23b7a30..4df1884947 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 61a8aa5010..8d35776ba1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -8,7 +8,7 @@ from __future__ import absolute_import, division, print_function __metaclass__ = type -ANSIBLE_METADATA = {'metadata_version': '1.0', +ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported_by': 'community'} From f46db65badfcb60d669dede20ca0f65f487aa5d8 Mon Sep 17 00:00:00 2001 From: ethackal Date: Thu, 14 Sep 2017 10:03:33 +0000 Subject: [PATCH 032/103] Fixes verify_ssl option when False in ansible_tower module util (#30308) * Fixes verify_ssl option when False in ansible_tower module util * fixed comparison to None per PEP-8 standards --- lib/ansible/module_utils/ansible_tower.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index 90de99b64f..6835ea9227 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -62,7 +62,7 @@ def tower_auth_config(module): if password: auth_config['password'] = password verify_ssl = module.params.get('tower_verify_ssl') - if verify_ssl: + if verify_ssl is not None: auth_config['verify_ssl'] = verify_ssl return auth_config From ac82751dfa1388cad127beb0b0e76f40db304155 Mon Sep 17 00:00:00 2001 From: Pilou Date: Mon, 2 Oct 2017 22:21:24 +0200 Subject: [PATCH 033/103] ansible_tower: fix broken import, reuse tower_argument_spec and documentation fragment (#29115) * module_utils/ansible_tower: fix broken import * tower_*: use tower_argument_spec & doc fragment * tower doc fragment: Ansible requires Python 2.6+ * tower_job_wait: fix broken import (Py3 compat) --- lib/ansible/module_utils/ansible_tower.py | 11 +- .../ansible_tower/tower_credential.py | 118 ++++++------------ .../ansible_tower/tower_group.py | 98 ++++----------- .../ansible_tower/tower_host.py | 76 +++-------- .../ansible_tower/tower_inventory.py | 72 +++-------- .../ansible_tower/tower_job_cancel.py | 11 +- .../ansible_tower/tower_job_launch.py | 11 +- .../ansible_tower/tower_job_list.py | 11 +- .../ansible_tower/tower_job_template.py | 110 +++++----------- .../ansible_tower/tower_job_wait.py | 15 +-- .../ansible_tower/tower_label.py | 68 ++-------- .../ansible_tower/tower_organization.py | 68 ++-------- .../ansible_tower/tower_project.py | 86 ++++--------- .../ansible_tower/tower_role.py | 83 +++--------- .../ansible_tower/tower_team.py | 71 +++-------- .../ansible_tower/tower_user.py | 78 +++--------- 16 files changed, 244 insertions(+), 743 deletions(-) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index 6835ea9227..eab1bac3b9 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -28,9 +28,14 @@ import os -import tower_cli.utils.exceptions as exc -from tower_cli.utils import parser -from tower_cli.api import client +try: + import tower_cli.utils.exceptions as exc + from tower_cli.utils import parser + from tower_cli.api import client + + HAS_TOWER_CLI = True +except ImportError: + HAS_TOWER_CLI = False def tower_auth_config(module): diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index eb2734ffc6..5b503f0692 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -138,45 +138,7 @@ options: 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.2" - -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 +extends_documentation_fragment: tower ''' @@ -190,56 +152,52 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +import os + +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + 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 + pass def main(): - module = AnsibleModule( - argument_spec=dict( - name=dict(required=True), - user=dict(), - team=dict(), - kind=dict(required=True, - choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", - "cloudforms", "gce", "azure", "azure_rm", "openstack"]), - host=dict(), - username=dict(), - password=dict(no_log=True), - ssh_key_data=dict(no_log=True), - ssh_key_unlock=dict(no_log=True), - authorize=dict(type='bool', default=False), - authorize_password=dict(no_log=True), - client=dict(), - secret=dict(), - tenant=dict(), - subscription=dict(), - domain=dict(), - become_method=dict(), - become_username=dict(), - become_password=dict(no_log=True), - vault_password=dict(no_log=True), - description=dict(), - organization=dict(required=True), - project=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 - ) + + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + user=dict(), + team=dict(), + kind=dict(required=True, + choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", + "cloudforms", "gce", "azure", "azure_rm", "openstack"]), + host=dict(), + username=dict(), + password=dict(no_log=True), + ssh_key_data=dict(no_log=True), + ssh_key_unlock=dict(no_log=True), + authorize=dict(type='bool', default=False), + authorize_password=dict(no_log=True), + client=dict(), + secret=dict(), + tenant=dict(), + subscription=dict(), + domain=dict(), + become_method=dict(), + become_username=dict(), + become_password=dict(no_log=True), + vault_password=dict(no_log=True), + description=dict(), + organization=dict(required=True), + project=dict(), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 39d392378d..1950c2798d 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -98,45 +98,7 @@ options: 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.2" - -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 +extends_documentation_fragment: tower ''' @@ -150,48 +112,42 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +import os + +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI 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 + pass def main(): - module = AnsibleModule( - argument_spec=dict( - name=dict(required=True), - description=dict(), - inventory=dict(required=True), - variables=dict(), - credential=dict(), - source=dict(choices=["manual", "file", "ec2", "rax", "vmware", - "gce", "azure", "azure_rm", "openstack", - "satellite6", "cloudforms", "custom"], default="manual"), - source_regions=dict(), - source_vars=dict(), - instance_filters=dict(), - group_by=dict(), - source_script=dict(), - overwrite=dict(type='bool', default=False), - overwrite_vars=dict(), - update_on_launch=dict(type='bool', default=False), - 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 - ) + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + description=dict(), + inventory=dict(required=True), + variables=dict(), + credential=dict(), + source=dict(choices=["manual", "file", "ec2", "rax", "vmware", + "gce", "azure", "azure_rm", "openstack", + "satellite6", "cloudforms", "custom"], default="manual"), + source_regions=dict(), + source_vars=dict(), + instance_filters=dict(), + group_by=dict(), + source_script=dict(), + overwrite=dict(type='bool', default=False), + overwrite_vars=dict(), + update_on_launch=dict(type='bool', default=False), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 33ea923dd8..da4ad4f323 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -50,45 +50,7 @@ options: 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 +extends_documentation_fragment: tower ''' @@ -103,36 +65,30 @@ EXAMPLES = ''' ''' +import os + +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + 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 + pass 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 - ) + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + description=dict(), + inventory=dict(required=True), + enabled=dict(type='bool', default=True), + variables=dict(), + state=dict(choices=['present', 'absent'], default='present'), + )) + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 6c1326e7bd..4dff1e16c5 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -47,45 +47,7 @@ options: 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 +extends_documentation_fragment: tower ''' @@ -100,34 +62,28 @@ EXAMPLES = ''' ''' +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + try: 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 + pass def main(): - module = AnsibleModule( - argument_spec=dict( - name=dict(required=True), - description=dict(), - organization=dict(required=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 - ) + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + description=dict(), + organization=dict(required=True), + variables=dict(), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index c4b83c6186..128e3ae12c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -56,20 +56,15 @@ status: from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI + try: 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, - tower_argument_spec, - ) - - HAS_TOWER_CLI = True except ImportError: - HAS_TOWER_CLI = False + pass def main(): diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index b332edf36e..58b53d780f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -90,20 +90,15 @@ status: from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI + try: 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, - tower_argument_spec, - ) - - HAS_TOWER_CLI = True except ImportError: - HAS_TOWER_CLI = False + pass def main(): diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 612e7ba2ad..26b45ed0eb 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -82,20 +82,15 @@ results: from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI + try: 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, - tower_argument_spec, - ) - - HAS_TOWER_CLI = True except ImportError: - HAS_TOWER_CLI = False + pass def main(): diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index b907c42fbe..3eab6caad9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -137,45 +137,7 @@ options: 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 +extends_documentation_fragment: tower ''' @@ -192,16 +154,15 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + try: 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 + pass def update_fields(p): @@ -252,40 +213,35 @@ def update_resources(module, p): def main(): - module = AnsibleModule( - argument_spec=dict( - name=dict(required=True), - description=dict(), - job_type=dict(choices=['run', 'check', 'scan'], required=True), - inventory=dict(), - project=dict(required=True), - playbook=dict(required=True), - machine_credential=dict(), - cloud_credential=dict(), - network_credential=dict(), - forks=dict(type='int'), - limit=dict(), - verbosity=dict(choices=['verbose', 'debug']), - job_tags=dict(), - skip_tags=dict(), - host_config_key=dict(), - extra_vars_path=dict(type='path', required=False), - ask_extra_vars=dict(type='bool', default=False), - ask_limit=dict(type='bool', default=False), - ask_tags=dict(type='bool', default=False), - ask_job_type=dict(type='bool', default=False), - ask_inventory=dict(type='bool', default=False), - ask_credential=dict(type='bool', default=False), - become_enabled=dict(type='bool', default=False), - 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 - ) + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + description=dict(), + job_type=dict(choices=['run', 'check', 'scan'], required=True), + inventory=dict(), + project=dict(required=True), + playbook=dict(required=True), + machine_credential=dict(), + cloud_credential=dict(), + network_credential=dict(), + forks=dict(type='int'), + limit=dict(), + verbosity=dict(choices=['verbose', 'debug']), + job_tags=dict(), + skip_tags=dict(), + host_config_key=dict(), + extra_vars_path=dict(type='path', required=False), + ask_extra_vars=dict(type='bool', default=False), + ask_limit=dict(type='bool', default=False), + ask_tags=dict(type='bool', default=False), + ask_job_type=dict(type='bool', default=False), + ask_inventory=dict(type='bool', default=False), + ask_credential=dict(type='bool', default=False), + become_enabled=dict(type='bool', default=False), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 797450189f..1747e26b0a 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -82,27 +82,18 @@ status: ''' +from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six.moves import cStringIO as StringIO -try: - from cStringIO import StringIO -except ImportError: - from StringIO import StringIO try: 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, - tower_argument_spec, - ) - - HAS_TOWER_CLI = True except ImportError: - HAS_TOWER_CLI = False + pass def main(): diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index 4b3a0196a3..95f63d1f3c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -39,45 +39,7 @@ options: 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 +extends_documentation_fragment: tower ''' @@ -90,32 +52,26 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + try: 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 + pass def main(): - module = AnsibleModule( - argument_spec=dict( - name=dict(required=True), - organization=dict(required=True), - 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 - ) + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + organization=dict(required=True), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 249ac7280d..fa6daa7833 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -38,45 +38,7 @@ options: 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(tower_config_file) is provided we will attempt to use the tower-cli library - defaults to find your Tower host information. - - I(tower_config_file) should contain Tower configuration in the following format - host=hostname - username=username - password=password +extends_documentation_fragment: tower ''' @@ -89,32 +51,26 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + try: 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 + pass def main(): - module = AnsibleModule( - argument_spec=dict( - name=dict(required=True), - description=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 - ) + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + description=dict(), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 9ae0d8a70c..6cfd104adf 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -85,45 +85,7 @@ options: 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 +extends_documentation_fragment: tower ''' @@ -137,42 +99,36 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + try: 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 + pass def main(): - module = AnsibleModule( - argument_spec=dict( - name=dict(), - description=dict(), - organization=dict(), - scm_type=dict(choices=['manual', 'git', 'hg', 'svn'], default='manual'), - scm_url=dict(), - scm_branch=dict(), - scm_credential=dict(), - scm_clean=dict(type='bool', default=False), - scm_delete_on_update=dict(type='bool', default=False), - scm_update_on_launch=dict(type='bool', default=False), - local_path=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'), + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(), + description=dict(), + organization=dict(), + scm_type=dict(choices=['manual', 'git', 'hg', 'svn'], default='manual'), + scm_url=dict(), + scm_branch=dict(), + scm_credential=dict(), + scm_clean=dict(type='bool', default=False), + scm_delete_on_update=dict(type='bool', default=False), + scm_update_on_launch=dict(type='bool', default=False), + local_path=dict(), - state=dict(choices=['present', 'absent'], default='present'), - ), - supports_check_mode=True - ) + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index df3340f8fc..7224ad087e 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -74,45 +74,7 @@ options: 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 +extends_documentation_fragment: tower ''' @@ -126,16 +88,15 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + try: 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 + pass def update_resources(module, p): @@ -165,26 +126,22 @@ def update_resources(module, p): def main(): - module = AnsibleModule( - argument_spec=dict( - user=dict(), - team=dict(), - role=dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]), - target_team=dict(), - inventory=dict(), - job_template=dict(), - credential=dict(), - organization=dict(), - project=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 - ) + + argument_spec = tower_argument_spec() + argument_spec.update(dict( + user=dict(), + team=dict(), + role=dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]), + target_team=dict(), + inventory=dict(), + job_template=dict(), + credential=dict(), + organization=dict(), + project=dict(), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index 4df1884947..390771f02b 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -39,45 +39,7 @@ options: 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 +extends_documentation_fragment: tower ''' @@ -91,33 +53,28 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + try: 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 + pass def main(): - module = AnsibleModule( - argument_spec=dict( - name=dict(required=True), - description=dict(), - organization=dict(required=True), - 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 - ) + + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + description=dict(), + organization=dict(required=True), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 8d35776ba1..9fb8c639d1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -62,45 +62,7 @@ options: 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 +extends_documentation_fragment: tower ''' @@ -116,37 +78,31 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' +from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI + try: 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 + pass def main(): - module = AnsibleModule( - argument_spec=dict( - username=dict(required=True), - first_name=dict(), - last_name=dict(), - password=dict(no_log=True), - email=dict(required=True), - superuser=dict(type='bool', default=False), - auditor=dict(type='bool', default=False), - 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 - ) + argument_spec = tower_argument_spec() + argument_spec.update(dict( + username=dict(required=True), + first_name=dict(), + last_name=dict(), + password=dict(no_log=True), + email=dict(required=True), + superuser=dict(type='bool', default=False), + auditor=dict(type='bool', default=False), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) if not HAS_TOWER_CLI: module.fail_json(msg='ansible-tower-cli required for this module') From f7592f6ae73709a2bf07e5075d1e95dedc1f3b15 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Sat, 7 Oct 2017 14:57:13 -0700 Subject: [PATCH 034/103] Port arg specs from type='str' to type='path' --- .../web_infrastructure/ansible_tower/tower_credential.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 5b503f0692..97f6c4f2fb 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -178,7 +178,7 @@ def main(): host=dict(), username=dict(), password=dict(no_log=True), - ssh_key_data=dict(no_log=True), + ssh_key_data=dict(no_log=True, type='path'), ssh_key_unlock=dict(no_log=True), authorize=dict(type='bool', default=False), authorize_password=dict(no_log=True), @@ -223,7 +223,6 @@ def main(): if params['ssh_key_data']: filename = params['ssh_key_data'] - filename = os.path.expanduser(filename) if not os.path.exists(filename): module.fail_json(msg='file not found: %s' % filename) if os.path.isdir(filename): From 3db34301293bb1076e31f4ee6aa6546bc41ab85f Mon Sep 17 00:00:00 2001 From: Thierry Bouvet Date: Mon, 15 Jan 2018 16:39:11 +0100 Subject: [PATCH 035/103] Fix credentials for Tower API V2 --- .../ansible_tower/tower_credential.py | 48 +++++++++++++++++-- 1 file changed, 44 insertions(+), 4 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 97f6c4f2fb..127e72de3d 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -165,6 +165,11 @@ except ImportError: pass +def _add_input_(module, param, results): + if module.params.get(param): + results[param] = module.params.get(param) + + def main(): argument_spec = tower_argument_spec() @@ -213,22 +218,57 @@ def main(): tower_check_mode(module) credential = tower_cli.get_resource('credential') try: - params = module.params.copy() + params = {} params['create_on_missing'] = True + params['name'] = name if organization: org_res = tower_cli.get_resource('organization') org = org_res.get(name=organization) params['organization'] = org['id'] - if params['ssh_key_data']: - filename = params['ssh_key_data'] + credential_type_res = tower_cli.get_resource('credential_type') + credential_type = credential_type_res.get(kind=module.params.get('kind')) + params['credential_type'] = credential_type['id'] + + if module.params.get('description'): + params['description'] = module.params.get('description') + + if module.params.get('user'): + user_res = tower_cli.get_resource('user') + user = user_res.get(name=module.params.get('user')) + params['user'] = user['id'] + + if module.params.get('team'): + team_res = tower_cli.get_resource('team') + team = team_res.get(name=module.params.get('team')) + params['team'] = team['id'] + + params['inputs'] = {} + if module.params.get('ssh_key_data'): + filename = module.params.get('ssh_key_data') if not os.path.exists(filename): module.fail_json(msg='file not found: %s' % filename) if os.path.isdir(filename): module.fail_json(msg='attempted to read contents of directory: %s' % filename) with open(filename, 'rb') as f: - params['ssh_key_data'] = f.read() + params['inputs']['ssh_key_data'] = f.read() + + _add_input_(module, 'authorize', params['inputs']) + _add_input_(module, 'authorize_password', params['inputs']) + _add_input_(module, 'client', params['inputs']) + _add_input_(module, 'secret', params['inputs']) + _add_input_(module, 'tenant', params['inputs']) + _add_input_(module, 'subscription', params['inputs']) + _add_input_(module, 'domain', params['inputs']) + _add_input_(module, 'become_method', params['inputs']) + _add_input_(module, 'become_username', params['inputs']) + _add_input_(module, 'become_password', params['inputs']) + _add_input_(module, 'vault_password', params['inputs']) + _add_input_(module, 'project', params['inputs']) + _add_input_(module, 'host', params['inputs']) + _add_input_(module, 'username', params['inputs']) + _add_input_(module, 'password', params['inputs']) if state == 'present': result = credential.modify(**params) From 4213ca1424c0c5dd3d32b367758b1aa3f5fffdf5 Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Thu, 22 Feb 2018 11:17:56 -0500 Subject: [PATCH 036/103] tower cred: implement credential /api/v1/ kind compatability --- .../ansible_tower/tower_credential.py | 66 ++++++++++++------- 1 file changed, 44 insertions(+), 22 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 127e72de3d..ffccc645ec 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -165,9 +165,41 @@ except ImportError: pass -def _add_input_(module, param, results): - if module.params.get(param): - results[param] = module.params.get(param) +KIND_CHOICES = { + 'ssh': 'Machine', + 'vault': 'Ansible Vault', + 'net': 'Network', + 'scm': 'Source Control', + 'aws': 'Amazon Web Services', + 'vmware': 'VMware vCenter', + 'satellite6': 'Red Hat Satellite 6', + 'cloudforms': 'Red Hat CloudForms', + 'gce': 'Google Compute Engine', + 'azure_rm': 'Microsoft Azure Resource Manager', + 'openstack': 'OpenStack', + 'rhv': 'Red Hat Virtualization', + 'insights': 'Insights', + 'tower': 'Ansible Tower', +} + + +def credential_type_for_v1_kind(params, module): + credential_type_res = tower_cli.get_resource('credential_type') + kind = params.pop('kind') + arguments = {'managed_by_tower': True} + if kind == 'ssh': + if params.get('vault_password'): + arguments['kind'] = 'vault' + else: + arguments['kind'] = 'ssh' + elif kind in ('net', 'scm', 'insights', 'vault'): + arguments['kind'] = kind + elif kind in KIND_CHOICES: + arguments.update(dict( + kind='cloud', + name=KIND_CHOICES[kind] + )) + return credential_type_res.get(**arguments) def main(): @@ -178,8 +210,7 @@ def main(): user=dict(), team=dict(), kind=dict(required=True, - choices=["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", - "cloudforms", "gce", "azure", "azure_rm", "openstack"]), + choices=KIND_CHOICES.keys()), host=dict(), username=dict(), password=dict(no_log=True), @@ -227,8 +258,7 @@ def main(): org = org_res.get(name=organization) params['organization'] = org['id'] - credential_type_res = tower_cli.get_resource('credential_type') - credential_type = credential_type_res.get(kind=module.params.get('kind')) + credential_type = credential_type_for_v1_kind(module.params, module) params['credential_type'] = credential_type['id'] if module.params.get('description'): @@ -254,21 +284,13 @@ def main(): with open(filename, 'rb') as f: params['inputs']['ssh_key_data'] = f.read() - _add_input_(module, 'authorize', params['inputs']) - _add_input_(module, 'authorize_password', params['inputs']) - _add_input_(module, 'client', params['inputs']) - _add_input_(module, 'secret', params['inputs']) - _add_input_(module, 'tenant', params['inputs']) - _add_input_(module, 'subscription', params['inputs']) - _add_input_(module, 'domain', params['inputs']) - _add_input_(module, 'become_method', params['inputs']) - _add_input_(module, 'become_username', params['inputs']) - _add_input_(module, 'become_password', params['inputs']) - _add_input_(module, 'vault_password', params['inputs']) - _add_input_(module, 'project', params['inputs']) - _add_input_(module, 'host', params['inputs']) - _add_input_(module, 'username', params['inputs']) - _add_input_(module, 'password', params['inputs']) + for key in ('authorize', 'authorize_password', 'client', 'secret', + 'tenant', 'subscription', 'domain', 'become_method', + 'become_username', 'become_password', 'vault_password', + 'project', 'host', 'username', 'password', + 'ssh_key_unlock'): + if module.params.get(key): + params['inputs'][key] = module.params.get(key) if state == 'present': result = credential.modify(**params) From 0bb7e06761be04f8e3708d4852153695d527cadb Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Thu, 22 Feb 2018 11:23:38 -0500 Subject: [PATCH 037/103] tower cred: filter user name lookup by the proper key --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index ffccc645ec..3851f5fe7f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -266,7 +266,7 @@ def main(): if module.params.get('user'): user_res = tower_cli.get_resource('user') - user = user_res.get(name=module.params.get('user')) + user = user_res.get(username=module.params.get('user')) params['user'] = user['id'] if module.params.get('team'): From d192297987ebd2c97a6390638a92591990638ffd Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Thu, 22 Feb 2018 13:01:08 -0500 Subject: [PATCH 038/103] tower cred: update kind options in documentation --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 3851f5fe7f..9555538df0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -54,7 +54,7 @@ options: description: - Type of credential being added. required: True - choices: ["ssh", "net", "scm", "aws", "rax", "vmware", "satellite6", "cloudforms", "gce", "azure", "azure_rm", "openstack"] + choices: ["ssh", "vault", "net", "scm", "aws", "vmware", "satellite6", "cloudforms", "gce", "azure_rm", "openstack", "rhv", "insights", "tower"] host: description: - Host for this credential. From 2edca4f357b45ab6b34928bd1312aad1c59dd161 Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Mon, 26 Feb 2018 13:12:54 -0500 Subject: [PATCH 039/103] tower cred: support credential kind/type for /api/v1/ and /api/v2/ (#36662) older versions of Tower (3.1) don't have a concept of CredentialTypes (this was introduced in Tower 3.2). This change detects older versions of pre-3.2 tower-cli that *only* support the deprecated `kind` attribute. --- .../ansible_tower/tower_credential.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 9555538df0..ded57cc19c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -258,8 +258,16 @@ def main(): org = org_res.get(name=organization) params['organization'] = org['id'] - credential_type = credential_type_for_v1_kind(module.params, module) - params['credential_type'] = credential_type['id'] + try: + tower_cli.get_resource('credential_type') + except (AttributeError): + # /api/v1/ backwards compat + # older versions of tower-cli don't *have* a credential_type + # resource + params['kind'] = module.params['kind'] + else: + credential_type = credential_type_for_v1_kind(module.params, module) + params['credential_type'] = credential_type['id'] if module.params.get('description'): params['description'] = module.params.get('description') From 2e04969f178a67ecbe2de8146b5ed42ee878c705 Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Thu, 1 Mar 2018 10:36:18 -0500 Subject: [PATCH 040/103] properly detect the absence of credential_type in older tower-cli (#36908) --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index ded57cc19c..b0d1c0d7d3 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -260,7 +260,7 @@ def main(): try: tower_cli.get_resource('credential_type') - except (AttributeError): + except (ImportError, AttributeError): # /api/v1/ backwards compat # older versions of tower-cli don't *have* a credential_type # resource From b14323c98533e36b9115f485ee83728ffa45398e Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Thu, 1 Mar 2018 15:22:29 -0500 Subject: [PATCH 041/103] properly pass /api/v1/ credential fields for older Towers (#36917) --- .../ansible_tower/tower_credential.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index b0d1c0d7d3..35d9d3410c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -282,7 +282,6 @@ def main(): team = team_res.get(name=module.params.get('team')) params['team'] = team['id'] - params['inputs'] = {} if module.params.get('ssh_key_data'): filename = module.params.get('ssh_key_data') if not os.path.exists(filename): @@ -290,15 +289,17 @@ def main(): if os.path.isdir(filename): module.fail_json(msg='attempted to read contents of directory: %s' % filename) with open(filename, 'rb') as f: - params['inputs']['ssh_key_data'] = f.read() + module.params['ssh_key_data'] = f.read() for key in ('authorize', 'authorize_password', 'client', 'secret', 'tenant', 'subscription', 'domain', 'become_method', 'become_username', 'become_password', 'vault_password', 'project', 'host', 'username', 'password', - 'ssh_key_unlock'): - if module.params.get(key): - params['inputs'][key] = module.params.get(key) + 'ssh_key_data', 'ssh_key_unlock'): + if 'kind' in params: + params[key] = module.params.get(key) + elif module.params.get(key): + params.setdefault('inputs', {})[key] = module.params.get(key) if state == 'present': result = credential.modify(**params) From 3e8de196ac366848b65bff3b8dc85559cbd22dad Mon Sep 17 00:00:00 2001 From: Pilou Date: Thu, 15 Mar 2018 04:58:50 +0100 Subject: [PATCH 042/103] ansible_tower modules doc: fix typos, use formatting functions (#37414) * fix typos * use formatting functions * use 'job template' instead of 'job_template' * acronyms: user uppercase * become_enabled param is about privilege escalation --- .../ansible_tower/tower_credential.py | 4 +-- .../ansible_tower/tower_group.py | 6 ++-- .../ansible_tower/tower_host.py | 2 +- .../ansible_tower/tower_inventory.py | 2 +- .../ansible_tower/tower_job_cancel.py | 2 +- .../ansible_tower/tower_job_launch.py | 6 ++-- .../ansible_tower/tower_job_list.py | 2 +- .../ansible_tower/tower_job_template.py | 28 +++++++++---------- .../ansible_tower/tower_project.py | 8 +++--- .../ansible_tower/tower_role.py | 4 +-- 10 files changed, 32 insertions(+), 32 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 35d9d3410c..37fd10ce97 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -80,12 +80,12 @@ options: - Unlock password for ssh_key. Use ASK for prompting. authorize: description: - - Should use authroize for net type. + - Should use authorize for net type. required: False default: False authorize_password: description: - - Password for net credentials that require authroize. + - Password for net credentials that require authorize. required: False default: null client: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 1950c2798d..d2183017ab 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -38,7 +38,7 @@ options: required: True variables: description: - - Variables to use for the group, use '@' for a file. + - Variables to use for the group, use C(@) for a file. required: False default: null credential: @@ -74,12 +74,12 @@ options: default: null source_script: description: - - Inventory script to be used when group type is "custom". + - Inventory script to be used when group type is C(custom). required: False default: null overwrite: description: - - Delete child roups and hosts not found in source. + - Delete child groups and hosts not found in source. required: False default: False overwrite_vars: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index da4ad4f323..1c625ef3ca 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -43,7 +43,7 @@ options: default: True variables: description: - - Variables to use for the host. Use '@' for a file. + - Variables to use for the host. Use C(@) for a file. state: description: - Desired state of the resource. diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 4dff1e16c5..fb8bafc3f9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -38,7 +38,7 @@ options: required: True variables: description: - - Inventory variables. Use '@' to get from file. + - Inventory variables. Use C(@) to get from file. required: False default: null state: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index 128e3ae12c..e81531c68a 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -29,7 +29,7 @@ options: required: True fail_if_not_running: description: - - Fail loudly if the job_id does not reference a running job. + - Fail loudly if the I(job_id) does not reference a running job. default: False extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 58b53d780f..af6804bd28 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -25,7 +25,7 @@ description: options: job_template: description: - - Name of the job_template to use. + - Name of the job template to use. required: True job_explanation: description: @@ -46,11 +46,11 @@ options: default: null extra_vars: description: - - Extra_vars to use for the job_template. Prepend '@' if a file. + - Extra_vars to use for the job_template. Prepend C(@) if a file. default: null limit: description: - - Limit to use for the job_template. + - Limit to use for the I(job_template). default: null tags: description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 26b45ed0eb..93737ad189 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -38,7 +38,7 @@ options: default: False query: description: - - Query used to further filter the list of jobs. {"foo":"bar"} will be passed at ?foo=bar + - Query used to further filter the list of jobs. C({"foo":"bar"}) will be passed at C(?foo=bar) default: null extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 3eab6caad9..e8e2a07a4e 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -18,7 +18,7 @@ DOCUMENTATION = ''' module: tower_job_template author: "Wayne Witzel III (@wwitzel3)" version_added: "2.3" -short_description: create, update, or destroy Ansible Tower job_template. +short_description: create, update, or destroy Ansible Tower job template. description: - Create, update, or destroy Ansible Tower job templates. See U(https://www.ansible.com/tower) for an overview. @@ -29,40 +29,40 @@ options: required: True description: description: - - Description to use for the job_template. + - Description to use for the job template. required: False default: null job_type: description: - - The job_type to use for the job_template. + - The job_type to use for the job template. required: True choices: ["run", "check", "scan"] inventory: description: - - Inventory to use for the job_template. + - Inventory to use for the job template. required: False default: null project: description: - - Project to use for the job_template. + - Project to use for the job template. required: True playbook: description: - - Playbook to use for the job_template. + - Playbook to use for the job template. required: True machine_credential: description: - - Machine_credential to use for the job_template. + - Machine_credential to use for the job template. required: False default: null cloud_credential: description: - - Cloud_credential to use for the job_template. + - Cloud_credential to use for the job template. required: False default: null network_credential: description: - - The network_credential to use for the job_template. + - The network_credential to use for the job template. required: False default: null forks: @@ -83,12 +83,12 @@ options: default: null job_tags: description: - - The job_tags to use for the job_template. + - The job_tags to use for the job template. required: False default: null skip_tags: description: - - The skip_tags to use for the job_template. + - The skip_tags to use for the job template. required: False default: null host_config_key: @@ -98,12 +98,12 @@ options: default: null extra_vars_path: description: - - Path to the extra_vars yaml file. + - Path to the C(extra_vars) YAML file. required: False default: null ask_extra_vars: description: - - Prompt user for extra_vars on launch. + - Prompt user for C(extra_vars) on launch. required: False default: False ask_tags: @@ -128,7 +128,7 @@ options: default: False become_enabled: description: - - Should become_enabled. + - Activate privilege escalation. required: False default: False state: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 6cfd104adf..f6726a187b 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -35,13 +35,13 @@ options: default: null scm_type: description: - - Type of scm resource. + - Type of SCM resource. required: False default: "manual" choices: ["manual", "git", "hg", "svn"] scm_url: description: - - URL of scm resource. + - URL of SCM resource. required: False default: null local_path: @@ -51,12 +51,12 @@ options: default: null scm_branch: description: - - The branch to use for the scm resource. + - The branch to use for the SCM resource. required: False default: null scm_credential: description: - - Name of the credential to use with this scm resource. + - Name of the credential to use with this SCM resource. required: False default: null scm_clean: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 7224ad087e..9210a9fa9f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -50,7 +50,7 @@ options: default: null job_template: description: - - The job_template the role acts on. + - The job template the role acts on. required: False default: null credential: @@ -60,7 +60,7 @@ options: default: null organization: description: - - Organiation the role acts on. + - Organization the role acts on. required: False default: null project: From 0b26297177ce42a3b4c77d663f1c89fc750cc975 Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Thu, 15 Mar 2018 22:15:24 +0100 Subject: [PATCH 043/103] Clean up module documentation (#36909) * Clean up module documentation This PR includes: - Removal of `default: None` (and variations) - Removal of `required: false` - Fixing booleans and `type: bool` where required * Fix remaining (new) validation issues --- .../ansible_tower/tower_credential.py | 41 ++-------------- .../ansible_tower/tower_group.py | 29 ++--------- .../ansible_tower/tower_host.py | 9 ++-- .../ansible_tower/tower_inventory.py | 5 -- .../ansible_tower/tower_job_launch.py | 10 +--- .../ansible_tower/tower_job_list.py | 6 +-- .../ansible_tower/tower_job_template.py | 49 +++++-------------- .../ansible_tower/tower_job_wait.py | 1 - .../ansible_tower/tower_label.py | 3 -- .../ansible_tower/tower_organization.py | 3 -- .../ansible_tower/tower_project.py | 29 +++-------- .../ansible_tower/tower_role.py | 17 ------- .../ansible_tower/tower_team.py | 5 +- .../ansible_tower/tower_user.py | 15 ++---- 14 files changed, 38 insertions(+), 184 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 37fd10ce97..37380d1330 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -33,23 +33,15 @@ options: user: description: - User that should own this credential. - required: False - default: null team: description: - Team that should own this credential. - required: False - default: null project: description: - Project that should for this credential. - required: False - default: null organization: description: - Organization that should own the credential. - required: False - default: null kind: description: - Type of credential being added. @@ -58,86 +50,59 @@ options: host: description: - Host for this credential. - required: False - default: null username: description: - Username for this credential. access_key for AWS. - required: False - default: null password: description: - Password for this credential. Use ASK for prompting. secret_key for AWS. api_key for RAX. - required: False - default: null ssh_key_data: description: - Path to SSH private key. - required: False - default: null ssh_key_unlock: description: - Unlock password for ssh_key. Use ASK for prompting. authorize: description: - Should use authorize for net type. - required: False - default: False + type: bool + default: 'no' authorize_password: description: - Password for net credentials that require authorize. - required: False - default: null client: description: - Client or application ID for azure_rm type. - required: False - default: null secret: description: - Secret token for azure_rm type. - required: False - default: null subscription: description: - Subscription ID for azure_rm type. - required: False - default: null tenant: description: - Tenant ID for azure_rm type. - required: False - default: null domain: description: - Domain for openstack type. - required: False - default: null become_method: description: - Become method to Use for privledge escalation. - required: False choices: ["None", "sudo", "su", "pbrun", "pfexec", "pmrun"] - default: "None" become_username: description: - Become username. Use ASK for prompting. - required: False - default: null become_password: description: - Become password. Use ASK for prompting. - required: False - default: null vault_password: description: - Valut password. Use ASK for prompting. state: description: - Desired state of the resource. - required: False - default: "present" choices: ["present", "absent"] + default: "present" extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index d2183017ab..0afdeeace1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -30,8 +30,6 @@ options: description: description: - The description to use for the group. - required: False - default: null inventory: description: - Inventory the group should be made a member of. @@ -39,63 +37,44 @@ options: variables: description: - Variables to use for the group, use C(@) for a file. - required: False - default: null credential: description: - Credential to use for the group. - required: False - default: null source: description: - The source to use for this group. - required: False - default: null, choices: ["manual", "file", "ec2", "rax", "vmware", "gce", "azure", "azure_rm", "openstack", "satellite6" , "cloudforms", "custom"] source_regions: description: - Regions for cloud provider. - required: False - default: null source_vars: description: - Override variables from source with variables from this field. - required: False - default: null instance_filters: description: - Comma-separated list of filter expressions for matching hosts. - required: False - default: null group_by: description: - Limit groups automatically created from inventory source. - required: False - default: null source_script: description: - Inventory script to be used when group type is C(custom). - required: False - default: null overwrite: description: - Delete child groups and hosts not found in source. - required: False - default: False + type: bool + default: 'no' overwrite_vars: description: - Override vars in child groups and hosts with those from external source. - required: False - default: null update_on_launch: description: - Refresh inventory data from its source each time a job is run. - required: False - default: False + type: bool + default: 'no' state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 1c625ef3ca..8f028c8755 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -30,8 +30,6 @@ options: description: description: - The description to use for the host. - required: False - default: null inventory: description: - Inventory the host should be made a member of. @@ -39,17 +37,16 @@ options: enabled: description: - If the host should be enabled. - required: False - default: True + type: bool + default: 'yes' variables: description: - Variables to use for the host. Use C(@) for a file. state: description: - Desired state of the resource. - required: False - default: "present" choices: ["present", "absent"] + default: "present" extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index fb8bafc3f9..c05d93e665 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -30,8 +30,6 @@ options: description: description: - The description to use for the inventory. - required: False - default: null organization: description: - Organization the inventory belongs to. @@ -39,12 +37,9 @@ options: variables: description: - Inventory variables. Use C(@) to get from file. - required: False - default: null state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index af6804bd28..350a7adf8c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -30,36 +30,30 @@ options: job_explanation: description: - Job explanation field. - default: null job_type: description: - Job_type to use for the job, only used if prompt for job_type is set. choices: ["run", "check", "scan"] - default: null inventory: description: - Inventory to use for the job, only used if prompt for inventory is set. - default: null credential: description: - Credential to use for job, only used if prompt for credential is set. - default: null extra_vars: description: - Extra_vars to use for the job_template. Prepend C(@) if a file. - default: null limit: description: - Limit to use for the I(job_template). - default: null tags: description: - Specific tags to use for from playbook. - default: null use_job_endpoint: description: - Disable launching jobs from job template. - default: False + type: bool + default: 'no' extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 93737ad189..8f0f373c14 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -26,20 +26,18 @@ options: status: description: - Only list jobs with this status. - default: null choices: ['pending', 'waiting', 'running', 'error', 'failed', 'canceled', 'successful'] page: description: - Page number of the results to fetch. - default: null all_pages: description: - Fetch all the pages and return a single result. - default: False + type: bool + default: 'no' query: description: - Query used to further filter the list of jobs. C({"foo":"bar"}) will be passed at C(?foo=bar) - default: null extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index e8e2a07a4e..703db940d9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -30,8 +30,6 @@ options: description: description: - Description to use for the job template. - required: False - default: null job_type: description: - The job_type to use for the job template. @@ -40,8 +38,6 @@ options: inventory: description: - Inventory to use for the job template. - required: False - default: null project: description: - Project to use for the job template. @@ -53,88 +49,67 @@ options: machine_credential: description: - Machine_credential to use for the job template. - required: False - default: null cloud_credential: description: - Cloud_credential to use for the job template. - required: False - default: null network_credential: description: - The network_credential to use for the job template. - required: False - default: null forks: description: - The number of parallel or simultaneous processes to use while executing the playbook. - required: False - default: null limit: description: - A host pattern to further constrain the list of hosts managed or affected by the playbook - required: False - default: null verbosity: description: - Control the output level Ansible produces as the playbook runs. - required: False choices: ["verbose", "debug"] - default: null job_tags: description: - The job_tags to use for the job template. - required: False - default: null skip_tags: description: - The skip_tags to use for the job template. - required: False - default: null host_config_key: description: - Allow provisioning callbacks using this host config key. - required: False - default: null extra_vars_path: description: - Path to the C(extra_vars) YAML file. - required: False - default: null ask_extra_vars: description: - Prompt user for C(extra_vars) on launch. - required: False - default: False + type: bool + default: 'no' ask_tags: description: - Prompt user for job tags on launch. - required: False - default: False + type: bool + default: 'no' ask_job_type: description: - Prompt user for job type on launch. - required: False - default: False + type: bool + default: 'no' ask_inventory: description: - Propmt user for inventory on launch. - required: False - default: False + type: bool + default: 'no' ask_credential: description: - Prompt user for credential on launch. - required: False - default: False + type: bool + default: 'no' become_enabled: description: - Activate privilege escalation. - required: False - default: False + type: bool + default: 'no' state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 1747e26b0a..4a455ccb6f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -38,7 +38,6 @@ options: timeout: description: - Maximum time in seconds to wait for a job to finish. - default: null extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index 95f63d1f3c..618b209cf1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -27,16 +27,13 @@ options: description: - Name to use for the label. required: True - default: null organization: description: - Organization the label should be applied to. required: True - default: null state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index fa6daa7833..cf944cf969 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -30,12 +30,9 @@ options: description: description: - The description to use for the organization. - required: False - default: null state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index f6726a187b..73f252bfa9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -27,62 +27,47 @@ options: description: - Name to use for the project. required: True - default: null description: description: - Description to use for the project. - required: False - default: null scm_type: description: - Type of SCM resource. - required: False - default: "manual" choices: ["manual", "git", "hg", "svn"] + default: "manual" scm_url: description: - URL of SCM resource. - required: False - default: null local_path: description: - The server playbook directory for manual projects. - required: False - default: null scm_branch: description: - The branch to use for the SCM resource. - required: False - default: null scm_credential: description: - Name of the credential to use with this SCM resource. - required: False - default: null scm_clean: description: - Remove local modifications before updating. - required: False - default: False + type: bool + default: 'no' scm_delete_on_update: description: - Remove the repository completely before updating. - required: False - default: False + type: bool + default: 'no' scm_update_on_launch: description: - Before an update to the local repository before launching a job with this project. - required: False - default: False + type: bool + default: 'no' organization: description: - Primary key of organization for project. - required: False - default: null state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 9210a9fa9f..46940ab1ec 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -26,13 +26,9 @@ options: user: description: - User that receives the permissions specified by the role. - required: False - default: null team: description: - Team that receives the permissions specified by the role. - required: False - default: null role: description: - The role type to grant/revoke. @@ -41,37 +37,24 @@ options: target_team: description: - Team that the role acts on. - required: False - default: null inventory: description: - Inventory the role acts on. - required: False - default: null job_template: description: - The job template the role acts on. - required: False - default: null credential: description: - Credential the role acts on. - required: False - default: null organization: description: - Organization the role acts on. - required: False - default: null project: description: - Project the role acts on. - required: False - default: null state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index 390771f02b..cd0469f773 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -27,18 +27,15 @@ options: description: - Name to use for the team. required: True - default: null organization: description: - Organization the team should be made a member of. required: True - default: null state: description: - Desired state of the resource. - required: False - default: "present" choices: ["present", "absent"] + default: "present" extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 9fb8c639d1..7c66f5a7a5 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -30,13 +30,9 @@ options: first_name: description: - First name of the user. - required: False - default: null last_name: description: - Last name of the user. - required: False - default: null email: description: - Email address of the user. @@ -44,22 +40,19 @@ options: password: description: - Password of the user. - required: False - default: null superuser: description: - User is a system wide administator. - required: False - default: False + type: bool + default: 'no' auditor: description: - User is a system wide auditor. - required: False - default: False + type: bool + default: 'no' state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower From 65aeb2b68aa2acf6e34023ca4d0abc48bd448700 Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Fri, 16 Mar 2018 13:28:19 -0400 Subject: [PATCH 044/103] add some Tower module integration tests (and fix a bug or two) (#37421) * add additional test coverage for tower modules * add test coverage for the tower_credential module * add test coverage for the tower_user module * fix a bug in py3 for tower_credential when ssh_key_data is specified * add test coverage for tower_host, tower_label, and tower_project * add test coverage for tower_inventory and tower_job_template * add more test coverage for tower modules - tower_job_launch - tower_job_list - tower_job_wait - tower_job_cancel * add a check mode/version assertion for tower module integration tests * add test coverage for the tower_role module * add test coverage for the tower_group module * add more integration test edge cases for various tower modules * give the job_wait module more time before failing * randomize passwords in the tower_user and tower_group tests --- .../ansible_tower/tower_credential.py | 23 ++++++++++++++----- .../ansible_tower/tower_group.py | 3 ++- .../ansible_tower/tower_host.py | 3 ++- .../ansible_tower/tower_role.py | 4 ++++ 4 files changed, 25 insertions(+), 8 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 37380d1330..6932d3ad69 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -73,6 +73,14 @@ options: client: description: - Client or application ID for azure_rm type. + required: False + default: null + security_token: + description: + - STS token for aws type. + required: False + default: null + version_added: "2.6" secret: description: - Secret token for azure_rm type. @@ -119,6 +127,7 @@ EXAMPLES = ''' import os +from ansible.module_utils._text import to_text from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI try: @@ -184,6 +193,7 @@ def main(): authorize=dict(type='bool', default=False), authorize_password=dict(no_log=True), client=dict(), + security_token=dict(), secret=dict(), tenant=dict(), subscription=dict(), @@ -254,13 +264,14 @@ def main(): if os.path.isdir(filename): module.fail_json(msg='attempted to read contents of directory: %s' % filename) with open(filename, 'rb') as f: - module.params['ssh_key_data'] = f.read() + module.params['ssh_key_data'] = to_text(f.read()) - for key in ('authorize', 'authorize_password', 'client', 'secret', - 'tenant', 'subscription', 'domain', 'become_method', - 'become_username', 'become_password', 'vault_password', - 'project', 'host', 'username', 'password', - 'ssh_key_data', 'ssh_key_unlock'): + for key in ('authorize', 'authorize_password', 'client', + 'security_token', 'secret', 'tenant', 'subscription', + 'domain', 'become_method', 'become_username', + 'become_password', 'vault_password', 'project', 'host', + 'username', 'password', 'ssh_key_data', + 'ssh_key_unlock'): if 'kind' in params: params[key] = module.params.get(key) elif module.params.get(key): diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 0afdeeace1..7818c92b04 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -140,7 +140,8 @@ def main(): if variables: if variables.startswith('@'): filename = os.path.expanduser(variables[1:]) - variables = module.contents_from_file(filename) + with open(filename, 'r') as f: + variables = f.read() json_output = {'group': name, 'state': state} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 8f028c8755..05eec7556c 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -100,7 +100,8 @@ def main(): if variables: if variables.startswith('@'): filename = os.path.expanduser(variables[1:]) - variables = module.contents_from_file(filename) + with open(filename, 'r') as f: + variables = f.read() json_output = {'host': name, 'state': state} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 46940ab1ec..096f6173f5 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -87,6 +87,10 @@ def update_resources(module, p): by name using their unique field (identity) ''' params = p.copy() + for key in p: + if key.startswith('tower_'): + params.pop(key) + params.pop('state', None) identity_map = { 'user': 'username', 'team': 'name', From 139703aafb6dd7e9e2772c86b7269b7bf1ff9f26 Mon Sep 17 00:00:00 2001 From: Pierre Roux Date: Sat, 26 May 2018 01:03:12 +0200 Subject: [PATCH 045/103] Fix tower_* modules **params kwargs (#40137) * Add cleaning function to handle **params The cleaning function is only added to tower modules which pass a `**params` argument as an unpacked dictionnary to the tower-cli method calls. Fix #39745 * Remove previous code added only for tower_role In 872a7b4, the `update_resources` function was modified so that it would clear unwanted parameters. However, this behaviour is desired for other modules too, modified in another commit. (see tower_clean_params). --- lib/ansible/module_utils/ansible_tower.py | 10 +++++----- .../web_infrastructure/ansible_tower/tower_group.py | 2 +- .../ansible_tower/tower_job_template.py | 2 +- .../web_infrastructure/ansible_tower/tower_role.py | 6 +----- 4 files changed, 8 insertions(+), 12 deletions(-) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index eab1bac3b9..690df47609 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -45,7 +45,7 @@ def tower_auth_config(module): it will attempt to fetch values from the module pararms and only pass those values that have been set. ''' - config_file = module.params.get('tower_config_file') + config_file = module.params.pop('tower_config_file', None) if config_file: config_file = os.path.expanduser(config_file) if not os.path.exists(config_file): @@ -57,16 +57,16 @@ def tower_auth_config(module): return parser.string_to_dict(f.read()) else: auth_config = {} - host = module.params.get('tower_host') + host = module.params.pop('tower_host', None) if host: auth_config['host'] = host - username = module.params.get('tower_username') + username = module.params.pop('tower_username', None) if username: auth_config['username'] = username - password = module.params.get('tower_password') + password = module.params.pop('tower_password', None) if password: auth_config['password'] = password - verify_ssl = module.params.get('tower_verify_ssl') + verify_ssl = module.params.pop('tower_verify_ssl', None) if verify_ssl is not None: auth_config['verify_ssl'] = verify_ssl return auth_config diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 7818c92b04..04180e08d6 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -134,7 +134,7 @@ def main(): name = module.params.get('name') inventory = module.params.get('inventory') credential = module.params.get('credential') - state = module.params.get('state') + state = module.params.pop('state') variables = module.params.get('variables') if variables: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 703db940d9..8c9cd2560a 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -222,7 +222,7 @@ def main(): module.fail_json(msg='ansible-tower-cli required for this module') name = module.params.get('name') - state = module.params.get('state') + state = module.params.pop('state') json_output = {'job_template': name, 'state': state} tower_auth = tower_auth_config(module) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 096f6173f5..95cc59f036 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -87,10 +87,6 @@ def update_resources(module, p): by name using their unique field (identity) ''' params = p.copy() - for key in p: - if key.startswith('tower_'): - params.pop(key) - params.pop('state', None) identity_map = { 'user': 'username', 'team': 'name', @@ -134,7 +130,7 @@ def main(): module.fail_json(msg='ansible-tower-cli required for this module') role_type = module.params.pop('role') - state = module.params.get('state') + state = module.params.pop('state') json_output = {'role': role_type, 'state': state} From 6471481d029f3b0b43fb029a980f379f2f420e8a Mon Sep 17 00:00:00 2001 From: Adrien Fleury Date: Tue, 5 Jun 2018 07:32:54 +0200 Subject: [PATCH 046/103] Module: Tower inventory source module (#37110) * tower_inventory_source: Add support for the inventory source via ansible-tower-cli. * Add test coverage for tower_inventory_source. * Update version_added to 2.7 --- .../ansible_tower/tower_inventory_source.py | 343 ++++++++++++++++++ 1 file changed, 343 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py new file mode 100644 index 0000000000..431ced7082 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py @@ -0,0 +1,343 @@ +#!/usr/bin/python +# coding: utf-8 -*- +# +# (c) 2018, Adrien Fleury +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'metadata_version': '1.1'} + + +DOCUMENTATION = ''' +--- +module: tower_inventory_source +author: "Adrien Fleury (@fleu42)" +version_added: "2.7" +short_description: create, update, or destroy Ansible Tower inventory source. +description: + - Create, update, or destroy Ansible Tower inventories source. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - The name to use for the inventory source. + required: True + description: + description: + - The description to use for the inventory source. + required: False + default: null + inventory: + description: + - The inventory the source is linked to. + required: True + source: + description: + - Types of inventory source. + choices: + - file + - scm + - ec2 + - gce + - azure + - azure_rm + - vmware + - satellite6 + - cloudforms + - openstack + - rhv + - tower + - custom + required: True + credential: + description: + - Credential to use to retrieve the inventory from. + required: False + source_vars: + description: + - >- + The source_vars allow to Override variables found in the source config + file. For example with Openstack, specifying *private: false* would + change the output of the openstack.py script. It has to be YAML or + JSON. + required: False + timeout: + description: + - Number in seconds after which the Tower API methods will time out. + source_project: + description: + - Use a *project* as a source for the *inventory*. + required: False + source_path: + description: + - Path to the file to use as a source in the selected *project*. + required: False + update_on_project_update: + description: + - >- + That parameter will sync the inventory when the project is synced. It + can only be used with a SCM source. + required: False + type: bool + source_regions: + description: + - >- + List of regions for your cloud provider. You can include multiple all + regions. Only Hosts associated with the selected regions will be + updated. Refer to Ansible Tower documentation for more detail. + required: False + instance_filters: + description: + - >- + Provide a comma-separated list of filter expressions. Hosts are + imported when all of the filters match. Refer to Ansible Tower + documentation for more detail. + required: False + group_by: + description: + - >- + Specify which groups to create automatically. Group names will be + created similar to the options selected. If blank, all groups above + are created. Refer to Ansible Tower documentation for more detail. + required: False + source_script: + description: + - >- + The source custom script to use to build the inventory. It needs to + exist. + required: False + overwrite: + description: + - >- + If set, any hosts and groups that were previously present on the + external source but are now removed will be removed from the Tower + inventory. Hosts and groups that were not managed by the inventory + source will be promoted to the next manually created group or if + there is no manually created group to promote them into, they will be + left in the "all" default group for the inventory. When not checked, + local child hosts and groups not found on the external source will + remain untouched by the inventory update process. + required: False + type: bool + overwrite_vars: + description: + - >- + If set, all variables for child groups and hosts will be removed + and replaced by those found on the external source. When not checked, + a merge will be performed, combining local variables with those found + on the external source. + required: False + type: bool + update_on_launch: + description: + - >- + Each time a job runs using this inventory, refresh the inventory from + the selected source before executing job tasks. + required: False + type: bool + update_cache_timeout: + description: + - >- + Time in seconds to consider an inventory sync to be current. During + job runs and callbacks the task system will evaluate the timestamp of + the latest sync. If it is older than Cache Timeout, it is not + considered current, and a new inventory sync will be performed. + required: False + state: + description: + - Desired state of the resource. + required: False + default: "present" + choices: ["present", "absent"] + tower_verify_ssl: + description: + - Tower option to avoid certificates check. + required: False + type: bool +extends_documentation_fragment: tower +''' + + +EXAMPLES = ''' +- name: Add tower inventory source + tower_inventory_source: + name: Inventory source + description: My Inventory source + inventory: My inventory + credential: Devstack_credential + source: openstack + update_on_launch: true + overwrite: true + source_vars: '{ private: false }' + state: present + tower_verify_ssl: false +''' + + +RETURN = ''' # ''' + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_tower import ( + tower_argument_spec, + tower_auth_config, + tower_check_mode, + HAS_TOWER_CLI +) + +try: + import tower_cli + import tower_cli.exceptions as exc + from tower_cli.conf import settings +except ImportError: + pass + + +SOURCE_CHOICES = { + 'file': 'Directory or Script', + 'scm': 'Sourced from a Project', + 'ec2': 'Amazon EC2', + 'gce': 'Google Compute Engine', + 'azure': 'Microsoft Azure', + 'azure_rm': 'Microsoft Azure Resource Manager', + 'vmware': 'VMware vCenter', + 'satellite6': 'Red Hat Satellite 6', + 'cloudforms': 'Red Hat CloudForms', + 'openstack': 'OpenStack', + 'rhv': 'Red Hat Virtualization', + 'tower': 'Ansible Tower', + 'custom': 'Custom Script', +} + + +def main(): + argument_spec = tower_argument_spec() + argument_spec.update(dict( + name=dict(required=True), + description=dict(required=False), + inventory=dict(required=True), + source=dict(required=True, + choices=SOURCE_CHOICES.keys()), + credential=dict(required=False), + source_vars=dict(required=False), + timeout=dict(type='int', required=False), + source_project=dict(required=False), + source_path=dict(required=False), + update_on_project_update=dict(type='bool', required=False), + source_regions=dict(required=False), + instance_filters=dict(required=False), + group_by=dict(required=False), + source_script=dict(required=False), + overwrite=dict(type='bool', required=False), + overwrite_vars=dict(type='bool', required=False), + update_on_launch=dict(type='bool', required=False), + update_cache_timeout=dict(type='int', required=False), + state=dict(choices=['present', 'absent'], default='present'), + )) + + module = AnsibleModule(argument_spec=argument_spec, + 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') + inventory = module.params.get('inventory') + source = module.params.get('source') + state = module.params.get('state') + + json_output = {'inventory_source': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + inventory_source = tower_cli.get_resource('inventory_source') + try: + params = {} + params['name'] = name + params['source'] = source + + if module.params.get('description'): + params['description'] = module.params.get('description') + + if module.params.get('credential'): + credential_res = tower_cli.get_resource('credential') + try: + credential = credential_res.get( + name=module.params.get('credential')) + params['credential'] = credential['id'] + except (exc.NotFound) as excinfo: + module.fail_json( + msg='Failed to update credential source,' + 'credential not found: {0}'.format(excinfo), + changed=False + ) + + if module.params.get('source_project'): + source_project_res = tower_cli.get_resource('project') + try: + source_project = source_project_res.get( + name=module.params.get('source_project')) + params['source_project'] = source_project['id'] + except (exc.NotFound) as excinfo: + module.fail_json( + msg='Failed to update source project,' + 'project not found: {0}'.format(excinfo), + changed=False + ) + + if module.params.get('source_script'): + source_script_res = tower_cli.get_resource('inventory_script') + try: + script = source_script_res.get( + name=module.params.get('source_script')) + params['source_script'] = script['id'] + except (exc.NotFound) as excinfo: + module.fail_json( + msg='Failed to update source script,' + 'script not found: {0}'.format(excinfo), + changed=False + ) + + try: + inventory_res = tower_cli.get_resource('inventory') + params['inventory'] = inventory_res.get(name=inventory)['id'] + except (exc.NotFound) as excinfo: + module.fail_json( + msg='Failed to update inventory source, ' + 'inventory not found: {0}'.format(excinfo), + changed=False + ) + + for key in ('source_vars', 'timeout', 'source_path', + 'update_on_project_update', 'source_regions', + 'instance_filters', 'group_by', 'overwrite', + 'overwrite_vars', 'update_on_launch', + 'update_cache_timeout'): + if module.params.get(key): + params[key] = module.params.get(key) + + if state == 'present': + params['create_on_missing'] = True + result = inventory_source.modify(**params) + json_output['id'] = result['id'] + elif state == 'absent': + params['fail_on_missing'] = False + result = inventory_source.delete(**params) + + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to update inventory source: \ + {0}'.format(excinfo), changed=False) + + json_output['changed'] = result['changed'] + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From 8569bf71afab15639ee446db1c815c253758d56e Mon Sep 17 00:00:00 2001 From: Andrew J Huffman Date: Tue, 5 Jun 2018 01:33:51 -0400 Subject: [PATCH 047/103] Updating tower_job_template.py (#38821) * Updating tower_job_template.py * tower_job_template: Update parameter version_added to 2.7 * Ensure that unset credentials aren't passed Passing empty strings for unset credentials causes ValueErrors as the API expects an integer. Don't pass unset credentials --- .../ansible_tower/tower_job_template.py | 161 +++++++++++++----- 1 file changed, 116 insertions(+), 45 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 8c9cd2560a..25f00211b0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -25,36 +25,35 @@ description: options: name: description: - - Name to use for the job_template. + - Name to use for the job template. required: True description: description: - Description to use for the job template. job_type: description: - - The job_type to use for the job template. + - The job type to use for the job template. required: True choices: ["run", "check", "scan"] inventory: description: - - Inventory to use for the job template. + - Name of the inventory to use for the job template. project: description: - - Project to use for the job template. + - Name of the project to use for the job template. required: True playbook: description: - - Playbook to use for the job template. + - Path to the playbook to use for the job template within the project provided. required: True - machine_credential: + credential: description: - - Machine_credential to use for the job template. - cloud_credential: + - Name of the credential to use for the job template. + version_added: 2.7 + vault_credential: description: - - Cloud_credential to use for the job template. - network_credential: - description: - - The network_credential to use for the job template. + - Name of the vault credential to use for the job template. + version_added: 2.7 forks: description: - The number of parallel or simultaneous processes to use while executing the playbook. @@ -63,23 +62,52 @@ options: - A host pattern to further constrain the list of hosts managed or affected by the playbook verbosity: description: - - Control the output level Ansible produces as the playbook runs. - choices: ["verbose", "debug"] - job_tags: - description: - - The job_tags to use for the job template. - skip_tags: - description: - - The skip_tags to use for the job template. - host_config_key: - description: - - Allow provisioning callbacks using this host config key. + - Control the output level Ansible produces as the playbook runs. 0 - Normal, 1 - Verbose, 2 - More Verbose, 3 - Debug, 4 - Connection Debug. + choices: [0, 1, 2, 3, 4] + default: 0 extra_vars_path: description: - Path to the C(extra_vars) YAML file. + job_tags: + description: + - Comma separated list of the tags to use for the job template. + force_handlers_enabled: + description: + - Enable forcing playbook handlers to run even if a task fails. + version_added: 2.7 + type: bool + default: 'no' + skip_tags: + description: + - Comma separated list of the tags to skip for the job template. + start_at_task: + description: + - Start the playbook at the task matching this name. + version_added: 2.7 + fact_caching_enabled: + description: + - Enable use of fact caching for the job template. + version_added: 2.7 + type: bool + default: 'no' + host_config_key: + description: + - Allow provisioning callbacks using this host config key. + ask_diff_mode: + description: + - Prompt user to enable diff mode (show changes) to files when supported by modules. + version_added: 2.7 + type: bool + default: 'no' ask_extra_vars: description: - - Prompt user for C(extra_vars) on launch. + - Prompt user for (extra_vars) on launch. + type: bool + default: 'no' + ask_limit: + description: + - Prompt user for a limit on launch. + version_added: 2.7 type: bool default: 'no' ask_tags: @@ -87,11 +115,23 @@ options: - Prompt user for job tags on launch. type: bool default: 'no' + ask_skip_tags: + description: + - Prompt user for job tags to skip on launch. + version_added: 2.7 + type: bool + default: 'no' ask_job_type: description: - Prompt user for job type on launch. type: bool default: 'no' + ask_verbosity: + description: + - Prompt user to choose a verbosity level on launch. + version_added: 2.7 + type: bool + default: 'no' ask_inventory: description: - Propmt user for inventory on launch. @@ -102,11 +142,23 @@ options: - Prompt user for credential on launch. type: bool default: 'no' + survey_enabled: + description: + - Enable a survey on the job template. + version_added: 2.7 + type: bool + default: 'no' become_enabled: description: - Activate privilege escalation. type: bool default: 'no' + concurrent_jobs_enabled: + description: + - Allow simultaneous runs of the job template. + version_added: 2.7 + type: bool + default: 'no' state: description: - Desired state of the resource. @@ -119,13 +171,13 @@ extends_documentation_fragment: tower EXAMPLES = ''' - name: Create tower Ping job template tower_job_template: - name: Ping - job_type: run - inventory: Local - project: Demo - playbook: ping.yml - machine_credential: Local - state: present + name: "Ping" + job_type: "run" + inventory: "Local" + project: "Demo" + playbook: "ping.yml" + credential: "Local" + state: "present" tower_config_file: "~/tower_cli.cfg" ''' @@ -147,11 +199,19 @@ def update_fields(p): ''' params = p.copy() field_map = { + 'fact_caching_enabled': 'use_fact_cache', + 'ask_diff_mode': 'ask_diff_mode_on_launch', 'ask_extra_vars': 'ask_variables_on_launch', 'ask_limit': 'ask_limit_on_launch', 'ask_tags': 'ask_tags_on_launch', + 'ask_skip_tags': 'ask_skip_tags_on_launch', + 'ask_verbosity': 'ask_verbosity_on_launch', + 'ask_inventory': 'ask_inventory_on_launch', + 'ask_credential': 'ask_credential_on_launch', 'ask_job_type': 'ask_job_type_on_launch', - 'machine_credential': 'credential', + 'diff_mode_enabled': 'diff_mode', + 'concurrent_jobs_enabled': 'allow_simultaneous', + 'force_handlers_enabled': 'force_handlers', } params_update = {} @@ -172,9 +232,8 @@ def update_resources(module, p): identity_map = { 'project': 'name', 'inventory': 'name', - 'machine_credential': 'name', - 'network_credential': 'name', - 'cloud_credential': 'name', + 'credential': 'name', + 'vault_credential': 'name', } for k, v in identity_map.items(): try: @@ -182,6 +241,9 @@ def update_resources(module, p): key = 'credential' if '_credential' in k else k result = tower_cli.get_resource(key).get(**{v: params[k]}) params[k] = result['id'] + elif k in params: + # unset empty parameters to avoid ValueError: invalid literal for int() with base 10: '' + del(params[k]) except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update job template: {0}'.format(excinfo), changed=False) return params @@ -191,28 +253,37 @@ def main(): argument_spec = tower_argument_spec() argument_spec.update(dict( name=dict(required=True), - description=dict(), + description=dict(default=''), job_type=dict(choices=['run', 'check', 'scan'], required=True), - inventory=dict(), + inventory=dict(default=''), project=dict(required=True), playbook=dict(required=True), - machine_credential=dict(), - cloud_credential=dict(), - network_credential=dict(), + credential=dict(default=''), + vault_credential=dict(default=''), forks=dict(type='int'), - limit=dict(), - verbosity=dict(choices=['verbose', 'debug']), - job_tags=dict(), - skip_tags=dict(), - host_config_key=dict(), + limit=dict(default=''), + verbosity=dict(type='int', choices=[0, 1, 2, 3, 4], default=0), extra_vars_path=dict(type='path', required=False), + job_tags=dict(default=''), + force_handlers_enabled=dict(type='bool', default=False), + skip_tags=dict(default=''), + start_at_task=dict(default=''), + timeout=dict(type='int', default=0), + fact_caching_enabled=dict(type='bool', default=False), + host_config_key=dict(default=''), + ask_diff_mode=dict(type='bool', default=False), ask_extra_vars=dict(type='bool', default=False), ask_limit=dict(type='bool', default=False), ask_tags=dict(type='bool', default=False), + ask_skip_tags=dict(type='bool', default=False), ask_job_type=dict(type='bool', default=False), + ask_verbosity=dict(type='bool', default=False), ask_inventory=dict(type='bool', default=False), ask_credential=dict(type='bool', default=False), + survey_enabled=dict(type='bool', default=False), become_enabled=dict(type='bool', default=False), + diff_mode_enabled=dict(type='bool', default=False), + concurrent_jobs_enabled=dict(type='bool', default=False), state=dict(choices=['present', 'absent'], default='present'), )) From 623e0f7cc994b39fc4ce2ce4ec72add6a6d23866 Mon Sep 17 00:00:00 2001 From: jaevans Date: Wed, 13 Jun 2018 10:00:05 -0700 Subject: [PATCH 048/103] Add support for Tower Smart inventories (#41458) * Support Smart Inventories Add kind and host_filter fields and pass through to tower_cli. * Add documentation for new Smart Inventories options * Add missing description header for host_filter documentation * Add version added tags to new options * Bumped vesion_added to 2.7 --- .../ansible_tower/tower_inventory.py | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index c05d93e665..dffbdc37c8 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -37,6 +37,16 @@ options: variables: description: - Inventory variables. Use C(@) to get from file. + kind: + description: + - The kind field. Cannot be modified after created. + default: "" + choices: ["", "smart"] + version_added: "2.7" + host_filter: + description: + - The host_filter field. Only useful when C(kind=smart). + version_added: "2.7" state: description: - Desired state of the resource. @@ -75,6 +85,8 @@ def main(): description=dict(), organization=dict(required=True), variables=dict(), + kind=dict(choices=['', 'smart'], default=''), + host_filter=dict(), state=dict(choices=['present', 'absent'], default='present'), )) @@ -88,6 +100,8 @@ def main(): organization = module.params.get('organization') variables = module.params.get('variables') state = module.params.get('state') + kind = module.params.get('kind') + host_filter = module.params.get('host_filter') json_output = {'inventory': name, 'state': state} @@ -102,7 +116,8 @@ def main(): if state == 'present': result = inventory.modify(name=name, organization=org['id'], variables=variables, - description=description, create_on_missing=True) + description=description, kind=kind, host_filter=host_filter, + create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': result = inventory.delete(name=name, organization=org['id']) From 185e9a09e0b20056db14ae90aa28c935a74360a5 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Fri, 15 Jun 2018 10:38:04 +0530 Subject: [PATCH 049/103] Correct typo from 'Valut' to 'Vault' (#41574) Correct typo from 'Valut' to 'Vault' +label: docsite_pr --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 6932d3ad69..6a7e0bbeb7 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -105,7 +105,7 @@ options: - Become password. Use ASK for prompting. vault_password: description: - - Valut password. Use ASK for prompting. + - Vault password. Use ASK for prompting. state: description: - Desired state of the resource. From 1349449e1e47dc66c2b3cf6842d1c96519851e82 Mon Sep 17 00:00:00 2001 From: Pierre-Louis Bonicoli Date: Fri, 15 Jun 2018 12:36:52 +0200 Subject: [PATCH 050/103] tower_project: manual projects don't require creds --- .../ansible_tower/tower_project.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 73f252bfa9..f59949d559 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -146,16 +146,19 @@ def main(): org = org_res.get(name=organization) except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update project, organization not found: {0}'.format(organization), changed=False) - try: - cred_res = tower_cli.get_resource('credential') - cred = cred_res.get(name=scm_credential) - except (exc.NotFound) as excinfo: - module.fail_json(msg='Failed to update project, credential not found: {0}'.format(scm_credential), changed=False) + if scm_type: + try: + cred_res = tower_cli.get_resource('credential') + cred = cred_res.get(name=scm_credential) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update project, credential not found: {0}'.format(scm_credential), changed=False) + + credential = cred['id'] if scm_type else None result = project.modify(name=name, description=description, organization=org['id'], scm_type=scm_type, scm_url=scm_url, local_path=local_path, - scm_branch=scm_branch, scm_clean=scm_clean, credential=cred['id'], + scm_branch=scm_branch, scm_clean=scm_clean, credential=credential, scm_delete_on_update=scm_delete_on_update, scm_update_on_launch=scm_update_on_launch, create_on_missing=True) From 9b228d7d2d83cacd19f3b5cbccc59206baf7afd9 Mon Sep 17 00:00:00 2001 From: David Moreau Simard Date: Tue, 24 Jul 2018 11:18:50 -0400 Subject: [PATCH 051/103] Properly detect credentials for tower_project It seemed like it was mostly the wrong variables been looked at, making it so a git repository could not be created without a credential. --- .../web_infrastructure/ansible_tower/tower_project.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index f59949d559..d9d747aa94 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -147,18 +147,18 @@ def main(): except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update project, organization not found: {0}'.format(organization), changed=False) - if scm_type: + if scm_credential: try: cred_res = tower_cli.get_resource('credential') cred = cred_res.get(name=scm_credential) + scm_credential = cred['id'] except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update project, credential not found: {0}'.format(scm_credential), changed=False) - credential = cred['id'] if scm_type else None result = project.modify(name=name, description=description, organization=org['id'], scm_type=scm_type, scm_url=scm_url, local_path=local_path, - scm_branch=scm_branch, scm_clean=scm_clean, credential=credential, + scm_branch=scm_branch, scm_clean=scm_clean, credential=scm_credential, scm_delete_on_update=scm_delete_on_update, scm_update_on_launch=scm_update_on_launch, create_on_missing=True) From 64014faf0294bab72cd49e93c70af59dc561c6c2 Mon Sep 17 00:00:00 2001 From: Pilou Date: Thu, 2 Aug 2018 17:17:39 +0200 Subject: [PATCH 052/103] Tower modules: move HAS_TOWER_CLI check in module_utils and minor improvements (#39809) * tower_* modules: move HAS_TOWER_CLI in TowerModule Besides this change allows to define other common parameters such as mutually_exclusive. * tower_*: config file can not be used with auth params * tower module_utils: remove useless call to expanduser 'path' type: expanduser & expandvars are automatically called --- lib/ansible/module_utils/ansible_tower.py | 34 ++++++++++++++----- .../ansible_tower/tower_credential.py | 13 +++---- .../ansible_tower/tower_group.py | 13 +++---- .../ansible_tower/tower_host.py | 13 +++---- .../ansible_tower/tower_inventory.py | 13 +++---- .../ansible_tower/tower_inventory_source.py | 19 +++-------- .../ansible_tower/tower_job_cancel.py | 14 +++----- .../ansible_tower/tower_job_launch.py | 14 +++----- .../ansible_tower/tower_job_list.py | 14 +++----- .../ansible_tower/tower_job_template.py | 13 +++---- .../ansible_tower/tower_job_wait.py | 13 +++---- .../ansible_tower/tower_label.py | 13 +++---- .../ansible_tower/tower_organization.py | 13 +++---- .../ansible_tower/tower_project.py | 13 +++---- .../ansible_tower/tower_role.py | 13 +++---- .../ansible_tower/tower_team.py | 13 +++---- .../ansible_tower/tower_user.py | 13 +++---- 17 files changed, 89 insertions(+), 162 deletions(-) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index 690df47609..0e3d1301c0 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -37,6 +37,8 @@ try: except ImportError: HAS_TOWER_CLI = False +from ansible.module_utils.basic import AnsibleModule + def tower_auth_config(module): '''tower_auth_config attempts to load the tower-cli.cfg file @@ -47,7 +49,6 @@ def tower_auth_config(module): ''' config_file = module.params.pop('tower_config_file', None) if config_file: - config_file = os.path.expanduser(config_file) if not os.path.exists(config_file): module.fail_json(msg='file not found: %s' % config_file) if os.path.isdir(config_file): @@ -82,11 +83,26 @@ def tower_check_mode(module): module.fail_json(changed=False, msg='Failed check mode: {0}'.format(excinfo)) -def tower_argument_spec(): - return 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'), - ) +class TowerModule(AnsibleModule): + def __init__(self, argument_spec, **kwargs): + args = 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'), + ) + args.update(argument_spec) + + mutually_exclusive = kwargs.get('mutually_exclusive', []) + kwargs['mutually_exclusive'] = mutually_exclusive.extend(( + ('tower_config_file', 'tower_host'), + ('tower_config_file', 'tower_username'), + ('tower_config_file', 'tower_password'), + ('tower_config_file', 'tower_verify_ssl'), + )) + + super(TowerModule, self).__init__(argument_spec=args, **kwargs) + + if not HAS_TOWER_CLI: + self.fail_json(msg='ansible-tower-cli required for this module') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 6a7e0bbeb7..d9c7614177 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -128,7 +128,7 @@ EXAMPLES = ''' import os from ansible.module_utils._text import to_text -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -178,8 +178,7 @@ def credential_type_for_v1_kind(params, module): def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), user=dict(), team=dict(), @@ -206,12 +205,9 @@ def main(): organization=dict(required=True), project=dict(), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') organization = module.params.get('organization') @@ -291,6 +287,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 04180e08d6..1e87a408ec 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -93,7 +93,7 @@ EXAMPLES = ''' import os -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -105,8 +105,7 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), description=dict(), inventory=dict(required=True), @@ -124,12 +123,9 @@ def main(): overwrite_vars=dict(), update_on_launch=dict(type='bool', default=False), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') inventory = module.params.get('inventory') @@ -177,6 +173,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 05eec7556c..9736349289 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -64,7 +64,7 @@ EXAMPLES = ''' import os -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode, HAS_TOWER_CLI try: import tower_cli @@ -76,19 +76,15 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), description=dict(), inventory=dict(required=True), enabled=dict(type='bool', default=True), variables=dict(), state=dict(choices=['present', 'absent'], default='present'), - )) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + ) + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') description = module.params.get('description') @@ -129,6 +125,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index dffbdc37c8..6da3928928 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -67,7 +67,7 @@ EXAMPLES = ''' ''' -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -79,8 +79,7 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), description=dict(), organization=dict(required=True), @@ -88,12 +87,9 @@ def main(): kind=dict(choices=['', 'smart'], default=''), host_filter=dict(), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') description = module.params.get('description') @@ -130,6 +126,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py index 431ced7082..46133fe9d9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py @@ -183,13 +183,7 @@ EXAMPLES = ''' RETURN = ''' # ''' -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.ansible_tower import ( - tower_argument_spec, - tower_auth_config, - tower_check_mode, - HAS_TOWER_CLI -) +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -217,8 +211,7 @@ SOURCE_CHOICES = { def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), description=dict(required=False), inventory=dict(required=True), @@ -239,13 +232,9 @@ def main(): update_on_launch=dict(type='bool', required=False), update_cache_timeout=dict(type='int', required=False), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, - supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') inventory = module.params.get('inventory') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index e81531c68a..635ae6624f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -54,9 +54,7 @@ status: ''' -from ansible.module_utils.basic import AnsibleModule - -from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -68,20 +66,16 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( job_id=dict(type='int', required=True), fail_if_not_running=dict(type='bool', default=False), - )) + ) - module = AnsibleModule( + module = TowerModule( argument_spec=argument_spec, supports_check_mode=True, ) - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') - job_id = module.params.get('job_id') json_output = {} diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 350a7adf8c..038ca4f6a3 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -82,9 +82,7 @@ status: ''' -from ansible.module_utils.basic import AnsibleModule - -from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -96,8 +94,7 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( job_template=dict(required=True), job_type=dict(choices=['run', 'check', 'scan']), inventory=dict(), @@ -105,16 +102,13 @@ def main(): limit=dict(), tags=dict(type='list'), extra_vars=dict(type='list'), - )) + ) - module = AnsibleModule( + module = TowerModule( argument_spec, supports_check_mode=True ) - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') - json_output = {} tags = module.params.get('tags') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 8f0f373c14..38ed764011 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -78,9 +78,7 @@ results: ''' -from ansible.module_utils.basic import AnsibleModule - -from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -92,22 +90,18 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( status=dict(choices=['pending', 'waiting', 'running', 'error', 'failed', 'canceled', 'successful']), page=dict(type='int'), all_pages=dict(type='bool', default=False), query=dict(type='dict'), - )) + ) - module = AnsibleModule( + module = TowerModule( argument_spec=argument_spec, supports_check_mode=True ) - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') - json_output = {} query = module.params.get('query') diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 25f00211b0..f32bbf57a3 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -181,7 +181,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -250,8 +250,7 @@ def update_resources(module, p): def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), description=dict(default=''), job_type=dict(choices=['run', 'check', 'scan'], required=True), @@ -285,12 +284,9 @@ def main(): diff_mode_enabled=dict(type='bool', default=False), concurrent_jobs_enabled=dict(type='bool', default=False), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') state = module.params.pop('state') @@ -318,6 +314,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 4a455ccb6f..fc21a202cc 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -81,8 +81,7 @@ status: ''' -from ansible.module_utils.ansible_tower import tower_auth_config, tower_check_mode, tower_argument_spec, HAS_TOWER_CLI -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode from ansible.module_utils.six.moves import cStringIO as StringIO @@ -96,22 +95,18 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( job_id=dict(type='int', required=True), timeout=dict(type='int'), min_interval=dict(type='float', default=1), max_interval=dict(type='float', default=30), - )) + ) - module = AnsibleModule( + module = TowerModule( argument_spec, supports_check_mode=True ) - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') - json_output = {} fail_json = None diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index 618b209cf1..836cb1b43f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -49,7 +49,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -61,17 +61,13 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), organization=dict(required=True), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') organization = module.params.get('organization') @@ -102,6 +98,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index cf944cf969..20e5399675 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -48,7 +48,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -60,17 +60,13 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), description=dict(), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') description = module.params.get('description') @@ -95,6 +91,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index d9d747aa94..ec36390217 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -84,7 +84,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -96,8 +96,7 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(), description=dict(), organization=dict(), @@ -111,12 +110,9 @@ def main(): local_path=dict(), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') description = module.params.get('description') @@ -172,6 +168,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 95cc59f036..2279bc925a 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -71,7 +71,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -110,8 +110,7 @@ def update_resources(module, p): def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( user=dict(), team=dict(), role=dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]), @@ -122,12 +121,9 @@ def main(): organization=dict(), project=dict(), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) role_type = module.params.pop('role') state = module.params.pop('state') @@ -155,6 +151,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index cd0469f773..cd9854f7ee 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -50,7 +50,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -63,18 +63,14 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( name=dict(required=True), description=dict(), organization=dict(required=True), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) name = module.params.get('name') description = module.params.get('description') @@ -107,6 +103,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 7c66f5a7a5..00e8c0fcf0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -71,7 +71,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import tower_argument_spec, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -83,8 +83,7 @@ except ImportError: def main(): - argument_spec = tower_argument_spec() - argument_spec.update(dict( + argument_spec = dict( username=dict(required=True), first_name=dict(), last_name=dict(), @@ -93,12 +92,9 @@ def main(): superuser=dict(type='bool', default=False), auditor=dict(type='bool', default=False), state=dict(choices=['present', 'absent'], default='present'), - )) + ) - module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True) - - if not HAS_TOWER_CLI: - module.fail_json(msg='ansible-tower-cli required for this module') + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) username = module.params.get('username') first_name = module.params.get('first_name') @@ -130,6 +126,5 @@ def main(): module.exit_json(**json_output) -from ansible.module_utils.basic import AnsibleModule if __name__ == '__main__': main() From 24cedcc56055bd238db7d267f03ce127093b8e56 Mon Sep 17 00:00:00 2001 From: Will Thames Date: Tue, 7 Aug 2018 21:19:15 +1000 Subject: [PATCH 053/103] Allow tower_inventory_sources params to be False (#43749) Ensure that params set to False are respected, rather than ignored. --- .../web_infrastructure/ansible_tower/tower_inventory_source.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py index 46133fe9d9..b8f8098fcb 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py @@ -309,7 +309,7 @@ def main(): 'instance_filters', 'group_by', 'overwrite', 'overwrite_vars', 'update_on_launch', 'update_cache_timeout'): - if module.params.get(key): + if module.params.get(key) is not None: params[key] = module.params.get(key) if state == 'present': From d4f4983a89585a44f835597d5eecb596e3d307da Mon Sep 17 00:00:00 2001 From: curry9999 Date: Thu, 9 Aug 2018 08:10:26 +0900 Subject: [PATCH 054/103] To improve readability, we added a line feed. (#43801) * modified: google/gcp_compute_backend_bucket.py modified: google/gcp_compute_backend_service.py modified: google/gcp_compute_forwarding_rule.py modified: google/gcp_compute_global_forwarding_rule.py modified: google/gcp_compute_image.py modified: google/gcp_compute_instance.py modified: google/gcp_compute_instance_group.py modified: google/gcp_compute_instance_group_manager.py modified: google/gcp_compute_instance_template.py modified: google/gcp_compute_route.py modified: google/gcp_compute_subnetwork.py modified: google/gcp_compute_target_http_proxy.py modified: google/gcp_compute_target_https_proxy.py modified: google/gcp_compute_target_ssl_proxy.py modified: google/gcp_compute_target_tcp_proxy.py modified: google/gcp_compute_url_map.py modified: google/gcp_container_node_pool.py modified: google/gcp_dns_resource_record_set.py modified: google/gcp_pubsub_subscription.py modified: google/gcp_storage_bucket_access_control.py * modified: lib/ansible/modules/cloud/amazon/aws_ses_identity.py modified: lib/ansible/modules/cloud/amazon/route53_facts.py modified: lib/ansible/modules/cloud/cloudscale/cloudscale_server.py modified: lib/ansible/modules/network/aos/_aos_logical_device.py modified: lib/ansible/modules/network/aos/_aos_rack_type.py modified: lib/ansible/modules/network/aos/_aos_template.py modified: lib/ansible/modules/network/cumulus/nclu.py modified: lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py modified: lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py --- .../modules/web_infrastructure/ansible_tower/tower_job_launch.py | 1 + .../modules/web_infrastructure/ansible_tower/tower_job_wait.py | 1 + 2 files changed, 2 insertions(+) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 038ca4f6a3..4f5f7d6cb9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -62,6 +62,7 @@ EXAMPLES = ''' tower_job_launch: job_template: "My Job Template" register: job + - name: Wait for job max 120s tower_job_wait: job_id: job.id diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index fc21a202cc..c794454f17 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -46,6 +46,7 @@ EXAMPLES = ''' tower_job_launch: job_template: "My Job Template" register: job + - name: Wait for job max 120s tower_job_wait: job_id: job.id From 7580f9c2b9f4e69c49baeb9f91b18c970e29d726 Mon Sep 17 00:00:00 2001 From: Yunfan Zhang <39713606+YunfanZhang42@users.noreply.github.com> Date: Tue, 21 Aug 2018 14:41:26 -0400 Subject: [PATCH 055/103] Added Ansible Tower inventory plugin. (#41816) Signed-off-by: Yunfan Zhang --- lib/ansible/plugins/inventory/tower.py | 187 +++++++++++++++++++++++++ 1 file changed, 187 insertions(+) create mode 100644 lib/ansible/plugins/inventory/tower.py diff --git a/lib/ansible/plugins/inventory/tower.py b/lib/ansible/plugins/inventory/tower.py new file mode 100644 index 0000000000..dd48514634 --- /dev/null +++ b/lib/ansible/plugins/inventory/tower.py @@ -0,0 +1,187 @@ +# Copyright (c) 2018 Ansible Project +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import (absolute_import, division, print_function) + +__metaclass__ = type + +DOCUMENTATION = ''' + name: tower + plugin_type: inventory + authors: + - Matthew Jones (@matburt) + - Yunfan Zhang (@YunfanZhang42) + short_description: Ansible dynamic inventory plugin for Ansible Tower. + version_added: "2.7" + description: + - Reads inventories from Ansible Tower. + - Supports reading configuration from both YAML config file and environment variables. + - If reading from the YAML file, the file name must end with tower_inventory.(yml|yaml), + the path in the command would be /path/to/tower_inventory.(yml|yaml). If some arguments in the config file + are missing, this plugin will try to fill in missing arguments by reading from environment variables. + - If reading configurations from environment variables, the path in the command must be @tower_inventory. + options: + plugin: + description: the name of this plugin, it should always be set to 'tower' + for this plugin to recognize it as it's own. + env: + - name: ANSIBLE_INVENTORY_ENABLED + required: True + choices: ['tower'] + host: + description: The network address of your Ansible Tower host. + type: string + env: + - name: TOWER_HOST + required: True + username: + description: The user that you plan to use to access inventories on Ansible Tower. + type: string + env: + - name: TOWER_USERNAME + required: True + password: + description: The password for your Ansible Tower user. + type: string + env: + - name: TOWER_PASSWORD + required: True + inventory_id: + description: The ID of the Ansible Tower inventory that you wish to import. + type: string + env: + - name: TOWER_INVENTORY + required: True + verify_ssl: + description: Specify whether Ansible should verify the SSL certificate of Ansible Tower host. + type: bool + default: True + env: + - name: TOWER_VERIFY_SSL + required: False +''' + +EXAMPLES = ''' +# Before you execute the following commands, you should make sure this file is in your plugin path, +# and you enabled this plugin. + +# Example for using tower_inventory.yml file + +plugin: tower +host: your_ansible_tower_server_network_address +username: your_ansible_tower_username +password: your_ansible_tower_password +inventory_id: the_ID_of_targeted_ansible_tower_inventory +# Then you can run the following command. +# If some of the arguments are missing, Ansible will attempt to read them from environment variables. +# ansible-inventory -i /path/to/tower_inventory.yml --list + +# Example for reading from environment variables: + +# Set environment variables: +# export TOWER_HOST=YOUR_TOWER_HOST_ADDRESS +# export TOWER_USERNAME=YOUR_TOWER_USERNAME +# export TOWER_PASSWORD=YOUR_TOWER_PASSWORD +# export TOWER_INVENTORY=THE_ID_OF_TARGETED_INVENTORY +# Read the inventory specified in TOWER_INVENTORY from Ansible Tower, and list them. +# The inventory path must always be @tower_inventory if you are reading all settings from environment variables. +# ansible-inventory -i @tower_inventory --list +''' + +import re +import os +import json +from ansible.module_utils import six +from ansible.module_utils.urls import Request, urllib_error, ConnectionError, socket, httplib +from ansible.module_utils._text import to_native +from ansible.errors import AnsibleParserError +from ansible.plugins.inventory import BaseInventoryPlugin + +# Python 2/3 Compatibility +try: + from urlparse import urljoin +except ImportError: + from urllib.parse import urljoin + + +class InventoryModule(BaseInventoryPlugin): + NAME = 'tower' + # Stays backward compatible with tower inventory script. + # If the user supplies '@tower_inventory' as path, the plugin will read from environment variables. + no_config_file_supplied = False + + def read_tower_inventory(self, tower_host, tower_user, tower_pass, inventory, verify_ssl=True): + if not re.match('(?:http|https)://', tower_host): + tower_host = 'https://{tower_host}'.format(tower_host=tower_host) + inventory_id = inventory.replace('/', '') + inventory_url = '/api/v2/inventories/{inv_id}/script/?hostvars=1&towervars=1&all=1'.format(inv_id=inventory_id) + inventory_url = urljoin(tower_host, inventory_url) + + request_handler = Request(url_username=tower_user, + url_password=tower_pass, + force_basic_auth=True, + validate_certs=verify_ssl) + + try: + response = request_handler.get(inventory_url) + except (ConnectionError, urllib_error.URLError, socket.error, httplib.HTTPException) as e: + error_msg = 'Connection to remote host failed: {err}'.format(err=e) + # If Tower gives a readable error message, display that message to the user. + if callable(getattr(e, 'read', None)): + error_msg += ' with message: {err_msg}'.format(err_msg=e.read()) + raise AnsibleParserError(to_native(error_msg)) + + # Attempt to parse JSON. + try: + return json.loads(response.read()) + except (ValueError, TypeError) as e: + # If the JSON parse fails, print the ValueError + raise AnsibleParserError(to_native('Failed to parse json from host: {err}'.format(err=e))) + + def verify_file(self, path): + if path.endswith('@tower_inventory'): + self.no_config_file_supplied = True + return True + elif super(InventoryModule, self).verify_file(path): + return path.endswith('tower_inventory.yml') or path.endswith('tower_inventory.yaml') + else: + return False + + def parse(self, inventory, loader, path, cache=True): + super(InventoryModule, self).parse(inventory, loader, path) + if not self.no_config_file_supplied and os.path.isfile(path): + self._read_config_data(path) + # Read inventory from tower server. + # Note the environment variables will be handled automatically by InventoryManager. + inventory = self.read_tower_inventory(self.get_option('host'), + self.get_option('username'), + self.get_option('password'), + self.get_option('inventory_id'), + verify_ssl=self.get_option('verify_ssl')) + # To start with, create all the groups. + for group_name in inventory: + if group_name != '_meta': + self.inventory.add_group(group_name) + + # Then, create all hosts and add the host vars. + all_hosts = inventory['_meta']['hostvars'] + for host_name, host_vars in six.iteritems(all_hosts): + self.inventory.add_host(host_name) + for var_name, var_value in six.iteritems(host_vars): + self.inventory.set_variable(host_name, var_name, var_value) + + # Lastly, create to group-host and group-group relationships, and set group vars. + for group_name, group_content in six.iteritems(inventory): + if group_name != 'all' and group_name != '_meta': + # First add hosts to groups + for host_name in group_content.get('hosts', []): + self.inventory.add_host(host_name, group_name) + # Then add the parent-children group relationships. + for child_group_name in group_content.get('children', []): + self.inventory.add_child(group_name, child_group_name) + # Set the group vars. Note we should set group var for 'all', but not '_meta'. + if group_name != '_meta': + for var_name, var_value in six.iteritems(group_content.get('vars', {})): + self.inventory.set_variable(group_name, var_name, var_value) + # Clean up the inventory. + self.inventory.reconcile_inventory() From d9d56b4b507dae1aba46da084061d24ed9aab106 Mon Sep 17 00:00:00 2001 From: jainnikhil30 Date: Tue, 28 Aug 2018 10:12:38 +0530 Subject: [PATCH 056/103] Add 'tower_settings' module for managing Ansible Tower Settings (#43933) * add the tower_settings module --- .../ansible_tower/tower_settings.py | 102 ++++++++++++++++++ 1 file changed, 102 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py new file mode 100644 index 0000000000..b3d07f99b1 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py @@ -0,0 +1,102 @@ +#!/usr/bin/python +# coding: utf-8 -*- + +# (c) 2018, Nikhil Jain +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: tower_settings +author: "Nikhil Jain (@jainnikhil30)" +version_added: "2.7" +short_description: Modify Ansible Tower settings. +description: + - Get, Modify Ansible Tower settings. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - Name of setting to get/modify + value: + description: + - Value to be modified for given setting. +extends_documentation_fragment: tower +''' + +RETURN = ''' # ''' + +EXAMPLES = ''' +- name: Set the value of AWX_PROOT_BASE_PATH + tower_settings: + name: AWX_PROOT_BASE_PATH + value: "/tmp" + register: testing_settings + +- name: Set the value of AWX_PROOT_SHOW_PATHS + tower_settings: + name: "AWX_PROOT_SHOW_PATHS" + value: "'/var/lib/awx/projects/', '/tmp'" + register: testing_settings + +- name: Set the LDAP Auth Bind Password + tower_settings: + name: "AUTH_LDAP_BIND_PASSWORD" + value: "Password" + no_log: true +''' + +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode + +try: + import tower_cli + import tower_cli.utils.exceptions as exc + + from tower_cli.conf import settings +except ImportError: + pass + + +def main(): + argument_spec = dict( + name=dict(Required=True), + value=dict(Required=True), + ) + + module = TowerModule( + argument_spec=argument_spec, + supports_check_mode=False + ) + + json_output = {} + + name = module.params.get('name') + value = module.params.get('value') + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + try: + setting = tower_cli.get_resource('setting') + result = setting.modify(setting=name, value=value) + + json_output['id'] = result['id'] + json_output['value'] = result['value'] + + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to modify the setting: {0}'.format(excinfo), changed=False) + + json_output['changed'] = result['changed'] + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From ee2709a898e3bd697ec496df8f11bb347a30bae6 Mon Sep 17 00:00:00 2001 From: Adrien Fleury Date: Wed, 29 Aug 2018 19:58:35 +0200 Subject: [PATCH 057/103] New module tower_workflow_template. (#37520) * Add new module *tower_workflow_template* Manage Tower workflows and their schemas. --- .../ansible_tower/tower_workflow_template.py | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py new file mode 100644 index 0000000000..3454f432d9 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py @@ -0,0 +1,191 @@ +#!/usr/bin/python +# coding: utf-8 -*- +# +# (c) 2018, Adrien Fleury +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'metadata_version': '1.1'} + + +DOCUMENTATION = ''' +--- +module: tower_workflow_template +author: "Adrien Fleury (@fleu42)" +version_added: "2.7" +short_description: create, update, or destroy Ansible Tower workflow template. +description: + - Create, update, or destroy Ansible Tower workflows. See + U(https://www.ansible.com/tower) for an overview. +options: + allow_simultaneous: + description: + - If enabled, simultaneous runs of this job template will be allowed. + required: False + type: bool + description: + description: + - The description to use for the workflow. + required: False + default: null + extra_vars: + description: + - > + Extra variables used by Ansible in YAML or key=value format. + required: False + name: + description: + - The name to use for the workflow. + required: True + organization: + description: + - The organization the workflow is linked to. + required: False + schema: + description: + - > + The schema is a JSON- or YAML-formatted string defining the + hierarchy structure that connects the nodes. Refer to Tower + documentation for more information. + required: False + survey_enabled: + description: + - Setting that variable will prompt the user for job type on the + workflow launch. + required: False + type: bool + survey: + description: + - The definition of the survey associated to the workflow. + required: False + state: + description: + - Desired state of the resource. + required: False + default: "present" + choices: ["present", "absent"] +extends_documentation_fragment: tower +''' + + +EXAMPLES = ''' +- tower_workflow_template: + name: Workflow Template + description: My very first Worflow Template + organization: My optional Organization + schema: "{{ lookup(file, my_workflow.json }}" + +- tower_worflow_template: + name: Workflow Template + state: absent +''' + + +RETURN = ''' # ''' + + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ansible_tower import ( + TowerModule, + tower_auth_config, + tower_check_mode +) + +try: + import tower_cli + import tower_cli.exceptions as exc + from tower_cli.conf import settings +except ImportError: + pass + + +def main(): + argument_spec = dict( + name=dict(required=True), + description=dict(required=False), + extra_vars=dict(required=False), + organization=dict(required=False), + allow_simultaneous=dict(type='bool', required=False), + schema=dict(required=False), + survey=dict(required=False), + survey_enabled=dict(type='bool', required=False), + state=dict(choices=['present', 'absent'], default='present'), + ) + + module = TowerModule( + argument_spec=argument_spec, + supports_check_mode=False + ) + + name = module.params.get('name') + state = module.params.get('state') + + schema = None + if module.params.get('schema'): + schema = module.params.get('schema') + + if schema and state == 'absent': + module.fail_json( + msg='Setting schema when state is absent is not allowed', + changed=False + ) + + json_output = {'workflow_template': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + wfjt_res = tower_cli.get_resource('workflow') + params = {} + params['name'] = name + + if module.params.get('description'): + params['description'] = module.params.get('description') + + if module.params.get('organization'): + organization_res = tower_cli.get_resource('organization') + try: + organization = organization_res.get( + name=module.params.get('organization')) + params['organization'] = organization['id'] + except exc.NotFound as excinfo: + module.fail_json( + msg='Failed to update organization source,' + 'organization not found: {0}'.format(excinfo), + changed=False + ) + + if module.params.get('survey'): + params['survey_spec'] = module.params.get('survey') + + for key in ('allow_simultaneous', 'extra_vars', 'survey_enabled', + 'description'): + if module.params.get(key): + params[key] = module.params.get(key) + + try: + if state == 'present': + params['create_on_missing'] = True + result = wfjt_res.modify(**params) + json_output['id'] = result['id'] + if schema: + wfjt_res.schema(result['id'], schema) + elif state == 'absent': + params['fail_on_missing'] = False + result = wfjt_res.delete(**params) + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to update workflow template: \ + {0}'.format(excinfo), changed=False) + + json_output['changed'] = result['changed'] + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From 7b6dc130785f02720df153bdd50593cb78fbca51 Mon Sep 17 00:00:00 2001 From: Adrien Fleury Date: Wed, 29 Aug 2018 20:01:19 +0200 Subject: [PATCH 058/103] New module : tower_credential_type (#37243) * Add new module *tower_credential_type* * Add support for credential type creation and/or deletion * Add test coverage for tower_credential_type --- .../ansible_tower/tower_credential_type.py | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py new file mode 100644 index 0000000000..e8f28d9867 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py @@ -0,0 +1,173 @@ +#!/usr/bin/python +# coding: utf-8 -*- +# +# (c) 2018, Adrien Fleury +# GNU General Public License v3.0+ +# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'status': ['preview'], + 'supported_by': 'community', + 'metadata_version': '1.1'} + + +DOCUMENTATION = ''' +--- +module: tower_credential_type +author: "Adrien Fleury (@fleu42)" +version_added: "2.7" +short_description: Create, update, or destroy custom Ansible Tower credential type. +description: + - Create, update, or destroy Ansible Tower credential type. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - The name of the credential type. + required: True + description: + description: + - The description of the credential type to give more detail about it. + required: False + kind: + description: + - >- + The type of credential type being added. Note that only cloud and + net can be used for creating credential types. Refer to the Ansible + for more information. + choices: [ 'ssh', 'vault', 'net', 'scm', 'cloud', 'insights' ] + required: False + inputs: + description: + - >- + Enter inputs using either JSON or YAML syntax. Refer to the Ansible + Tower documentation for example syntax. + required: False + injectors: + description: + - >- + Enter injectors using either JSON or YAML syntax. Refer to the + Ansible Tower documentation for example syntax. + required: False + state: + description: + - Desired state of the resource. + required: False + default: "present" + choices: ["present", "absent"] + tower_verify_ssl: + description: + - Tower option to avoid certificates check. + required: False + type: bool +extends_documentation_fragment: tower +''' + + +EXAMPLES = ''' +- tower_credential_type: + name: Nexus + description: Credentials type for Nexus + kind: cloud + inputs: "{{ lookup('file', 'tower_credential_inputs_nexus.json') }}" + injectors: {'extra_vars': {'nexus_credential': 'test' }} + state: present + tower_verify_ssl: false + +- tower_credential_type: + name: Nexus + state: absent +''' + + +RETURN = ''' # ''' + + +from ansible.module_utils.ansible_tower import ( + TowerModule, + tower_auth_config, + tower_check_mode +) + +try: + import tower_cli + import tower_cli.exceptions as exc + from tower_cli.conf import settings +except ImportError: + pass + + +KIND_CHOICES = { + 'ssh': 'Machine', + 'vault': 'Ansible Vault', + 'net': 'Network', + 'scm': 'Source Control', + 'cloud': 'Lots of others', + 'insights': 'Insights' +} + + +def main(): + argument_spec = dict( + name=dict(required=True), + description=dict(required=False), + kind=dict(required=False, choices=KIND_CHOICES.keys()), + inputs=dict(type='dict', required=False), + injectors=dict(type='dict', required=False), + state=dict(choices=['present', 'absent'], default='present'), + ) + + module = TowerModule( + argument_spec=argument_spec, + supports_check_mode=False + ) + + name = module.params.get('name') + kind = module.params.get('kind') + state = module.params.get('state') + + json_output = {'credential_type': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + credential_type_res = tower_cli.get_resource('credential_type') + + params = {} + params['name'] = name + params['kind'] = kind + params['managed_by_tower'] = False + + if module.params.get('description'): + params['description'] = module.params.get('description') + + if module.params.get('inputs'): + params['inputs'] = module.params.get('inputs') + + if module.params.get('injectors'): + params['injectors'] = module.params.get('injectors') + + try: + if state == 'present': + params['create_on_missing'] = True + result = credential_type_res.modify(**params) + json_output['id'] = result['id'] + elif state == 'absent': + params['fail_on_missing'] = False + result = credential_type_res.delete(**params) + + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json( + msg='Failed to update credential type: {0}'.format(excinfo), + changed=False + ) + + json_output['changed'] = result['changed'] + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From def043c383f197829d056d0fbbf5ada1f8af7870 Mon Sep 17 00:00:00 2001 From: Meecr0b Date: Fri, 7 Sep 2018 19:41:09 +0200 Subject: [PATCH 059/103] tower_credential: expect ssh_key_data to be a string instead of path (#45158) * expect ssh_key_data to be a string instead of path ssh_key_data should be a string filled with the private key the old behavior can be archived with a lookup Fixes #45119 * clarifies ssh_key_data description, adds newline --- .../ansible_tower/tower_credential.py | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index d9c7614177..80fb76e227 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -58,7 +58,8 @@ options: - Password for this credential. Use ASK for prompting. secret_key for AWS. api_key for RAX. ssh_key_data: description: - - Path to SSH private key. + - SSH private key content. To extract the content from a file path, use the lookup function (see examples). + required: False ssh_key_unlock: description: - Unlock password for ssh_key. Use ASK for prompting. @@ -123,6 +124,17 @@ EXAMPLES = ''' organization: test-org state: present tower_config_file: "~/tower_cli.cfg" + +- name: Create a valid SCM credential from a private_key file + tower_credential: + name: SCM Credential + organization: Default + state: present + kind: scm + username: joe + password: secret + ssh_key_data: "{{ lookup('file', '/tmp/id_rsa') }}" + ssh_key_unlock: "passphrase" ''' import os @@ -187,7 +199,7 @@ def main(): host=dict(), username=dict(), password=dict(no_log=True), - ssh_key_data=dict(no_log=True, type='path'), + ssh_key_data=dict(no_log=True, type='str'), ssh_key_unlock=dict(no_log=True), authorize=dict(type='bool', default=False), authorize_password=dict(no_log=True), @@ -254,13 +266,18 @@ def main(): params['team'] = team['id'] if module.params.get('ssh_key_data'): - filename = module.params.get('ssh_key_data') - if not os.path.exists(filename): - module.fail_json(msg='file not found: %s' % filename) - if os.path.isdir(filename): - module.fail_json(msg='attempted to read contents of directory: %s' % filename) - with open(filename, 'rb') as f: - module.params['ssh_key_data'] = to_text(f.read()) + data = module.params.get('ssh_key_data') + if os.path.exists(data): + module.deprecate( + msg='ssh_key_data should be a string, not a path to a file. Use lookup(\'file\', \'/path/to/file\') instead', + version="2.12" + ) + if os.path.isdir(data): + module.fail_json(msg='attempted to read contents of directory: %s' % data) + with open(data, 'rb') as f: + module.params['ssh_key_data'] = to_text(f.read()) + else: + module.params['ssh_key_data'] = data for key in ('authorize', 'authorize_password', 'client', 'security_token', 'secret', 'tenant', 'subscription', From 45a899225442b97d49f940d92e25abb0a98905ba Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Wed, 19 Sep 2018 16:02:27 +0200 Subject: [PATCH 060/103] Docs: Avoid use of 'default: null' (#45795) Various modules document the default 'null' value, but it causes None to be shown in the documentation explicitly. --- .../ansible_tower/tower_credential.py | 6 +---- .../ansible_tower/tower_inventory_source.py | 24 +++---------------- .../ansible_tower/tower_workflow_template.py | 19 ++++----------- 3 files changed, 8 insertions(+), 41 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 80fb76e227..59933ee2f0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -1,7 +1,7 @@ #!/usr/bin/python # coding: utf-8 -*- -# (c) 2017, Wayne Witzel III +# Copyright: (c) 2017, Wayne Witzel III # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function @@ -74,13 +74,9 @@ options: client: description: - Client or application ID for azure_rm type. - required: False - default: null security_token: description: - STS token for aws type. - required: False - default: null version_added: "2.6" secret: description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py index b8f8098fcb..11c6439a1d 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py @@ -1,9 +1,8 @@ #!/usr/bin/python # coding: utf-8 -*- -# -# (c) 2018, Adrien Fleury -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Copyright: (c) 2018, Adrien Fleury +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type @@ -31,8 +30,6 @@ options: description: description: - The description to use for the inventory source. - required: False - default: null inventory: description: - The inventory the source is linked to. @@ -58,7 +55,6 @@ options: credential: description: - Credential to use to retrieve the inventory from. - required: False source_vars: description: - >- @@ -66,24 +62,20 @@ options: file. For example with Openstack, specifying *private: false* would change the output of the openstack.py script. It has to be YAML or JSON. - required: False timeout: description: - Number in seconds after which the Tower API methods will time out. source_project: description: - Use a *project* as a source for the *inventory*. - required: False source_path: description: - Path to the file to use as a source in the selected *project*. - required: False update_on_project_update: description: - >- That parameter will sync the inventory when the project is synced. It can only be used with a SCM source. - required: False type: bool source_regions: description: @@ -91,27 +83,23 @@ options: List of regions for your cloud provider. You can include multiple all regions. Only Hosts associated with the selected regions will be updated. Refer to Ansible Tower documentation for more detail. - required: False instance_filters: description: - >- Provide a comma-separated list of filter expressions. Hosts are imported when all of the filters match. Refer to Ansible Tower documentation for more detail. - required: False group_by: description: - >- Specify which groups to create automatically. Group names will be created similar to the options selected. If blank, all groups above are created. Refer to Ansible Tower documentation for more detail. - required: False source_script: description: - >- The source custom script to use to build the inventory. It needs to exist. - required: False overwrite: description: - >- @@ -123,7 +111,6 @@ options: left in the "all" default group for the inventory. When not checked, local child hosts and groups not found on the external source will remain untouched by the inventory update process. - required: False type: bool overwrite_vars: description: @@ -132,14 +119,12 @@ options: and replaced by those found on the external source. When not checked, a merge will be performed, combining local variables with those found on the external source. - required: False type: bool update_on_launch: description: - >- Each time a job runs using this inventory, refresh the inventory from the selected source before executing job tasks. - required: False type: bool update_cache_timeout: description: @@ -148,17 +133,14 @@ options: job runs and callbacks the task system will evaluate the timestamp of the latest sync. If it is older than Cache Timeout, it is not considered current, and a new inventory sync will be performed. - required: False state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] tower_verify_ssl: description: - Tower option to avoid certificates check. - required: False type: bool extends_documentation_fragment: tower ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py index 3454f432d9..4e70ca1a16 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py @@ -1,9 +1,8 @@ #!/usr/bin/python # coding: utf-8 -*- -# -# (c) 2018, Adrien Fleury -# GNU General Public License v3.0+ -# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +# Copyright: (c) 2018, Adrien Fleury +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) from __future__ import absolute_import, division, print_function __metaclass__ = type @@ -27,18 +26,13 @@ options: allow_simultaneous: description: - If enabled, simultaneous runs of this job template will be allowed. - required: False type: bool description: description: - The description to use for the workflow. - required: False - default: null extra_vars: description: - - > - Extra variables used by Ansible in YAML or key=value format. - required: False + - Extra variables used by Ansible in YAML or key=value format. name: description: - The name to use for the workflow. @@ -46,28 +40,23 @@ options: organization: description: - The organization the workflow is linked to. - required: False schema: description: - > The schema is a JSON- or YAML-formatted string defining the hierarchy structure that connects the nodes. Refer to Tower documentation for more information. - required: False survey_enabled: description: - Setting that variable will prompt the user for job type on the workflow launch. - required: False type: bool survey: description: - The definition of the survey associated to the workflow. - required: False state: description: - Desired state of the resource. - required: False default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower From 79166209ee20b9c799cad9237f1e6129a83e9464 Mon Sep 17 00:00:00 2001 From: Yanis Guenane Date: Thu, 20 Sep 2018 23:44:22 +0200 Subject: [PATCH 061/103] inventory/tower: authors -< author so Doc can pick it up (#45936) --- lib/ansible/plugins/inventory/tower.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/plugins/inventory/tower.py b/lib/ansible/plugins/inventory/tower.py index dd48514634..38f04ac50f 100644 --- a/lib/ansible/plugins/inventory/tower.py +++ b/lib/ansible/plugins/inventory/tower.py @@ -8,7 +8,7 @@ __metaclass__ = type DOCUMENTATION = ''' name: tower plugin_type: inventory - authors: + author: - Matthew Jones (@matburt) - Yunfan Zhang (@YunfanZhang42) short_description: Ansible dynamic inventory plugin for Ansible Tower. From 5dc9ca222fd0c2d0651cb86ce5185eec973dc7aa Mon Sep 17 00:00:00 2001 From: Sloane Hertel Date: Thu, 11 Oct 2018 12:06:52 -0400 Subject: [PATCH 062/103] add more consistent extension matching for inventory plugins (#46786) * Add consistent extension matching for inventory plugins that support YAML configuration files * Document extension matching expectations --- lib/ansible/plugins/inventory/tower.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ansible/plugins/inventory/tower.py b/lib/ansible/plugins/inventory/tower.py index 38f04ac50f..79b2776a4d 100644 --- a/lib/ansible/plugins/inventory/tower.py +++ b/lib/ansible/plugins/inventory/tower.py @@ -16,7 +16,7 @@ DOCUMENTATION = ''' description: - Reads inventories from Ansible Tower. - Supports reading configuration from both YAML config file and environment variables. - - If reading from the YAML file, the file name must end with tower_inventory.(yml|yaml), + - If reading from the YAML file, the file name must end with tower.(yml|yaml) or tower_inventory.(yml|yaml), the path in the command would be /path/to/tower_inventory.(yml|yaml). If some arguments in the config file are missing, this plugin will try to fill in missing arguments by reading from environment variables. - If reading configurations from environment variables, the path in the command must be @tower_inventory. @@ -143,7 +143,7 @@ class InventoryModule(BaseInventoryPlugin): self.no_config_file_supplied = True return True elif super(InventoryModule, self).verify_file(path): - return path.endswith('tower_inventory.yml') or path.endswith('tower_inventory.yaml') + return path.endswith(('tower_inventory.yml', 'tower_inventory.yaml', 'tower.yml', 'tower.yaml')) else: return False From 94b557d8aaafd1b2ef9db4bd8d46619afc557068 Mon Sep 17 00:00:00 2001 From: Sean Cavanaugh Date: Thu, 18 Oct 2018 16:21:35 -0400 Subject: [PATCH 063/103] adding additional example and clarification (#47224) The kind: paramter is missing from the original example (which won't actually work). The organization needs to be listed as required (if you don't list it, you will get an error). Also adding additional example using the tower_username and tower_password method. --- .../ansible_tower/tower_credential.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 59933ee2f0..fe912745ac 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -42,9 +42,10 @@ options: organization: description: - Organization that should own the credential. + required: True kind: description: - - Type of credential being added. + - Type of credential being added. The ssh choice refers to a Tower Machine credential. required: True choices: ["ssh", "vault", "net", "scm", "aws", "vmware", "satellite6", "cloudforms", "gce", "azure_rm", "openstack", "rhv", "insights", "tower"] host: @@ -118,6 +119,7 @@ EXAMPLES = ''' name: Team Name description: Team Description organization: test-org + kind: ssh state: present tower_config_file: "~/tower_cli.cfg" @@ -131,6 +133,18 @@ EXAMPLES = ''' password: secret ssh_key_data: "{{ lookup('file', '/tmp/id_rsa') }}" ssh_key_unlock: "passphrase" + +- name: Add Credential Into Tower + tower_credential: + name: Workshop Credential + ssh_key_data: "/home/{{ansible_user}}/.ssh/aws-private.pem" + kind: ssh + organization: Default + tower_username: admin + tower_password: ansible + tower_host: https://localhost + run_once: true + delegate_to: localhost ''' import os From ae980b9a829ae6911ebb30bb97313605fe2aad2f Mon Sep 17 00:00:00 2001 From: Hugh Ma Date: Wed, 7 Nov 2018 04:09:40 -0800 Subject: [PATCH 064/103] Add survey_spec parameter to module. (#48182) * Add survey_spec parameter to module. Fixes #48011 * Removed trailing white space. Added integration test. --- .../ansible_tower/tower_job_template.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index f32bbf57a3..fb811d11ce 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -148,6 +148,12 @@ options: version_added: 2.7 type: bool default: 'no' + survey_spec: + description: + - JSON/YAML dict formatted survey definition. + version_added: 2.8 + type: dict + required: False become_enabled: description: - Activate privilege escalation. @@ -165,6 +171,10 @@ options: default: "present" choices: ["present", "absent"] extends_documentation_fragment: tower +notes: + - JSON for survey_spec can be found in Tower API Documentation. See + U(https://docs.ansible.com/ansible-tower/latest/html/towerapi/api_ref.html#/Job_Templates/Job_Templates_job_templates_survey_spec_create) + for POST operation payload example. ''' @@ -179,6 +189,8 @@ EXAMPLES = ''' credential: "Local" state: "present" tower_config_file: "~/tower_cli.cfg" + survey_enabled: yes + survey_spec: "{{ lookup('file', 'my_survey.json') }}" ''' from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode @@ -280,6 +292,7 @@ def main(): ask_inventory=dict(type='bool', default=False), ask_credential=dict(type='bool', default=False), survey_enabled=dict(type='bool', default=False), + survey_spec=dict(type='dict', required=False), become_enabled=dict(type='bool', default=False), diff_mode_enabled=dict(type='bool', default=False), concurrent_jobs_enabled=dict(type='bool', default=False), From 590341ed7d942a566633f35502b525b861fe33db Mon Sep 17 00:00:00 2001 From: seag-rvc Date: Tue, 27 Nov 2018 13:10:18 +0000 Subject: [PATCH 065/103] Update tower_host.py (#49186) Current example does not show how to declare variables +label: docsite_pr --- .../modules/web_infrastructure/ansible_tower/tower_host.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 9736349289..16a92b1120 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -59,6 +59,8 @@ EXAMPLES = ''' inventory: "Local Inventory" state: present tower_config_file: "~/tower_cli.cfg" + variables: + example_var: 123 ''' From 2d6743635e522ece5e2c7684dcff7f3ce86b4265 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Wed, 28 Nov 2018 13:55:52 +0530 Subject: [PATCH 066/103] E325 Removal - Part II (#49196) Signed-off-by: Abhijeet Kasurde --- .../modules/web_infrastructure/ansible_tower/tower_job_cancel.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index 635ae6624f..acbc92f906 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -31,6 +31,7 @@ options: description: - Fail loudly if the I(job_id) does not reference a running job. default: False + type: bool extends_documentation_fragment: tower ''' From b11374157d72bb40527158b45a556291810c641f Mon Sep 17 00:00:00 2001 From: Dag Wieers Date: Tue, 18 Dec 2018 22:25:30 +0100 Subject: [PATCH 067/103] Convert to reduced list of known types (#50010) --- .../web_infrastructure/ansible_tower/tower_job_cancel.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_launch.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_wait.py | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index acbc92f906..51258a31de 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -50,7 +50,7 @@ id: status: description: status of the cancel request returned: success - type: string + type: str sample: canceled ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 4f5f7d6cb9..cb997abdb2 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -78,7 +78,7 @@ id: status: description: status of newly launched job returned: success - type: string + type: str sample: pending ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index c794454f17..519adc8403 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -67,17 +67,17 @@ elapsed: started: description: timestamp of when the job started running returned: success - type: string + type: str sample: "2017-03-01T17:03:53.200234Z" finished: description: timestamp of when the job finished running returned: success - type: string + type: str sample: "2017-03-01T17:04:04.078782Z" status: description: current status of job returned: success - type: string + type: str sample: successful ''' From a37a18c0bff254a31b24d6f48ad0cd5b4fd2fdd7 Mon Sep 17 00:00:00 2001 From: Andrea Tartaglia Date: Wed, 19 Dec 2018 12:01:12 +0000 Subject: [PATCH 068/103] Added organization in the scm_credential get (#49884) * Added organization in the scm_credential get * Fallback looking for cred in project org * Tests project with multi org credential * Fixed CI issue * Added changelog fragment --- .../web_infrastructure/ansible_tower/tower_project.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index ec36390217..6d6a80260a 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -146,7 +146,11 @@ def main(): if scm_credential: try: cred_res = tower_cli.get_resource('credential') - cred = cred_res.get(name=scm_credential) + try: + cred = cred_res.get(name=scm_credential) + except (tower_cli.exceptions.MultipleResults) as multi_res_excinfo: + module.warn('Multiple credentials found for {0}, falling back looking in project organization'.format(scm_credential)) + cred = cred_res.get(name=scm_credential, organization=org['id']) scm_credential = cred['id'] except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update project, credential not found: {0}'.format(scm_credential), changed=False) From c82199605182d4aada97915afc29e46c0f775223 Mon Sep 17 00:00:00 2001 From: Alicia Cozine <879121+acozine@users.noreply.github.com> Date: Wed, 9 Jan 2019 08:21:26 -0600 Subject: [PATCH 069/103] fix docs for tower modules (#50710) --- .../modules/web_infrastructure/ansible_tower/tower_job_list.py | 2 +- .../web_infrastructure/ansible_tower/tower_workflow_template.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 38ed764011..47b4ed6b06 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -47,8 +47,8 @@ EXAMPLES = ''' tower_job_list: status: running query: {"playbook": "testing.yml"} - register: testing_jobs tower_config_file: "~/tower_cli.cfg" + register: testing_jobs ''' RETURN = ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py index 4e70ca1a16..89e0744411 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py @@ -68,7 +68,7 @@ EXAMPLES = ''' name: Workflow Template description: My very first Worflow Template organization: My optional Organization - schema: "{{ lookup(file, my_workflow.json }}" + schema: "{{ lookup('file', 'my_workflow.json') }}" - tower_worflow_template: name: Workflow Template From a32981242b8b18c3af7d027e202bc812525f25c3 Mon Sep 17 00:00:00 2001 From: jainnikhil30 Date: Wed, 9 Jan 2019 20:01:21 +0530 Subject: [PATCH 070/103] Fixing exception import for tower modules (#50447) * fixing the exception import from tower modules * Adding tests for checking tower modules are failing with correct msg * fixed failing tests * fixed failing test in tower_team --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_group.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_host.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_inventory.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_cancel.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_launch.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_job_list.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_template.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_job_wait.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_label.py | 2 +- .../web_infrastructure/ansible_tower/tower_organization.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_project.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_role.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_settings.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_team.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_user.py | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index fe912745ac..2b30355363 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -154,7 +154,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 1e87a408ec..50772891ff 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -97,7 +97,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 16a92b1120..492c4842c0 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -70,7 +70,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 6da3928928..1be2477321 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -71,7 +71,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index 51258a31de..f2f5f8eada 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -59,7 +59,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index cb997abdb2..c34ec3dd23 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -87,7 +87,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 47b4ed6b06..51eda5ecdb 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -82,7 +82,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index fb811d11ce..4f69ec99d5 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -197,7 +197,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 519adc8403..8974289157 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -88,7 +88,7 @@ from ansible.module_utils.six.moves import cStringIO as StringIO try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index 836cb1b43f..554d154cb1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -53,7 +53,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 20e5399675..8acbfd5108 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -52,7 +52,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 6d6a80260a..c1b4a0c972 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -88,7 +88,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 2279bc925a..38a56514b9 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -75,7 +75,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py index b3d07f99b1..1a2acbfb9e 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py @@ -58,7 +58,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index cd9854f7ee..4c49fd5447 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -54,7 +54,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 00e8c0fcf0..86baf18e90 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -75,7 +75,7 @@ from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, t try: import tower_cli - import tower_cli.utils.exceptions as exc + import tower_cli.exceptions as exc from tower_cli.conf import settings except ImportError: From 5ef995cd7d994798b946042ef266f04232bdf50c Mon Sep 17 00:00:00 2001 From: John Westcott IV <32551173+john-westcott-iv@users.noreply.github.com> Date: Fri, 18 Jan 2019 06:05:54 -0500 Subject: [PATCH 071/103] Adding TowerCLI send module (#37843) --- .../ansible_tower/tower_send.py | 167 ++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py new file mode 100644 index 0000000000..387e82bcb7 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py @@ -0,0 +1,167 @@ +#!/usr/bin/python +# coding: utf-8 -*- + +# (c) 2017, John Westcott IV +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: tower_send +author: "John Westcott IV (@john-westcott-iv)" +version_added: "2.8" +short_description: Send assets to Ansible Tower. +description: + - Send assets to Ansible Tower. See + U(https://www.ansible.com/tower) for an overview. +options: + assets: + description: + - The assets to import. + - This can be the output of tower_receive or loaded from a file + required: False + files: + description: + - List of files to import. + required: False + default: [] + prevent: + description: + - A list of asset types to prevent import for + required: false + default: [] + password_management: + description: + - The password management option to use. + - The prompt option is not supported. + required: false + default: 'default' + choices: ["default", "random"] + +notes: + - One of assets or files needs to be passed in + +requirements: + - "ansible-tower-cli >= 3.3.0" + - six.moves.StringIO + - sys + +extends_documentation_fragment: tower +''' + +EXAMPLES = ''' +- name: Import all tower assets + tower_send: + assets: "{{ export_output.assets }}" + tower_config_file: "~/tower_cli.cfg" +''' + +RETURN = ''' +output: + description: The import messages + returned: success, fail + type: list + sample: [ 'Message 1', 'Messag 2' ] +''' + +import os +import sys + +from ansible.module_utils.six.moves import StringIO +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, HAS_TOWER_CLI + +from tempfile import mkstemp + +try: + from tower_cli.cli.transfer.send import Sender + from tower_cli.utils.exceptions import TowerCLIError + + from tower_cli.conf import settings + TOWER_CLI_HAS_EXPORT = True +except ImportError: + TOWER_CLI_HAS_EXPORT = False + + +def main(): + argument_spec = dict( + assets=dict(required=False), + files=dict(required=False, default=[], type='list'), + prevent=dict(required=False, default=[], type='list'), + password_management=dict(required=False, default='default', choices=['default', 'random']), + ) + + module = TowerModule(argument_spec=argument_spec, supports_check_mode=False) + + if not HAS_TOWER_CLI: + module.fail_json(msg='ansible-tower-cli required for this module') + + if not TOWER_CLI_HAS_EXPORT: + module.fail_json(msg='ansible-tower-cli version does not support export') + + assets = module.params.get('assets') + prevent = module.params.get('prevent') + password_management = module.params.get('password_management') + files = module.params.get('files') + + result = dict( + changed=False, + msg='', + output='', + ) + + if not assets and not files: + result['msg'] = "Assets or files must be specified" + module.fail_json(**result) + + path = None + if assets: + # We got assets so we need to dump this out to a temp file and append that to files + handle, path = mkstemp(prefix='', suffix='', dir='') + with open(path, 'w') as f: + f.write(assets) + files.append(path) + + tower_auth = tower_auth_config(module) + failed = False + with settings.runtime_values(**tower_auth): + try: + sender = Sender(no_color=False) + old_stdout = sys.stdout + sys.stdout = captured_stdout = StringIO() + try: + sender.send(files, prevent, password_management) + except TypeError as e: + # Newer versions of TowerCLI require 4 parameters + sender.send(files, prevent, [], password_management) + + if sender.error_messages > 0: + failed = True + result['msg'] = "Transfer Failed with %d errors" % sender.error_messages + if sender.changed_messages > 0: + result['changed'] = True + except TowerCLIError as e: + result['msg'] = e + failed = True + finally: + if path is not None: + os.remove(path) + result['output'] = captured_stdout.getvalue().split("\n") + sys.stdout = old_stdout + + # Return stdout so that module returns will work + if failed: + module.fail_json(**result) + else: + module.exit_json(**result) + + +if __name__ == '__main__': + main() From 41f649b5a273fb6065d60e77455a315d51624302 Mon Sep 17 00:00:00 2001 From: John Westcott IV <32551173+john-westcott-iv@users.noreply.github.com> Date: Fri, 18 Jan 2019 06:08:04 -0500 Subject: [PATCH 072/103] Adding tower_workflow_launch (#42701) --- .../ansible_tower/tower_workflow_launch.py | 164 ++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py new file mode 100644 index 0000000000..a7174ec3b2 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py @@ -0,0 +1,164 @@ +#!/usr/bin/python +# coding: utf-8 -*- + +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + +DOCUMENTATION = ''' +--- +module: tower_workflow_launch +author: "John Westcott IV (@john-westcott-iv)" +version_added: "2.8" +short_description: Run a workflow in Ansible Tower +description: + - Launch an Ansible Tower workflows. See + U(https://www.ansible.com/tower) for an overview. +options: + workflow_template: + description: + - The name of the workflow template to run. + required: True + extra_vars: + description: + - Any extra vars required to launch the job. + required: False + wait: + description: + - Wait for the workflow to complete. + required: False + default: True + type: bool + timeout: + description: + - If waiting for the workflow to complete this will abort after this + - ammount of seconds + +requirements: + - "python >= 2.6" +extends_documentation_fragment: tower +''' + +RETURN = ''' +tower_version: + description: The version of Tower we connected to + returned: If connection to Tower works + type: str + sample: '3.4.0' +job_info: + description: dictionnary containing information about the workflow executed + returned: If workflow launched + type: dict +''' + + +EXAMPLES = ''' +- name: Launch a workflow + tower_workflow_launch: + name: "Test Workflow" + delegate_to: localhost + run_once: true + register: workflow_results + +- name: Launch a Workflow with parameters without waiting + tower_workflow_launch: + workflow_template: "Test workflow" + extra_vars: "---\nmy: var" + wait: False + delegate_to: localhost + run_once: true + register: workflow_task_info +''' + +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config + +try: + import tower_cli + from tower_cli.api import client + from tower_cli.conf import settings + from tower_cli.exceptions import ServerError, ConnectionError, BadRequest, TowerCLIError +except ImportError: + pass + + +def main(): + argument_spec = dict( + workflow_template=dict(required=True), + extra_vars=dict(required=False), + wait=dict(required=False, default=True, type='bool'), + timeout=dict(required=False, default=None, type='int'), + ) + + module = TowerModule( + argument_spec=argument_spec, + supports_check_mode=True + ) + + workflow_template = module.params.get('workflow_template') + extra_vars = module.params.get('extra_vars') + wait = module.params.get('wait') + timeout = module.params.get('timeout') + + # If we are going to use this result to return we can consider ourselfs changed + result = dict( + changed=False, + msg='initial message' + ) + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + # First we will test the connection. This will be a test for both check and run mode + # Note, we are not using the tower_check_mode method here because we want to do more than just a ping test + # If we are in check mode we also want to validate that we can find the workflow + try: + ping_result = client.get('/ping').json() + # Stuff the version into the results as an FYI + result['tower_version'] = ping_result['version'] + except(ServerError, ConnectionError, BadRequest) as excinfo: + result['msg'] = "Failed to reach Tower: {0}".format(excinfo) + module.fail_json(**result) + + # Now that we know we can connect, lets verify that we can resolve the workflow_template + try: + workflow = tower_cli.get_resource("workflow").get(**{'name': workflow_template}) + except TowerCLIError as e: + result['msg'] = "Failed to find workflow: {0}".format(e) + module.fail_json(**result) + + # Since we were able to find the workflow, if we are in check mode we can return now + if module.check_mode: + result['msg'] = "Check mode passed" + module.exit_json(**result) + + # We are no ready to run the workflow + try: + result['job_info'] = tower_cli.get_resource('workflow_job').launch( + workflow_job_template=workflow['id'], + monitor=False, + wait=wait, + timeout=timeout, + extra_vars=extra_vars + ) + if wait: + # If we were waiting for a result we will fail if the workflow failed + if result['job_info']['failed']: + result['msg'] = "Workflow execution failed" + module.fail_json(**result) + else: + module.exit_json(**result) + + # We were not waiting and there should be no way we can make it here without the workflow fired off so we can return a success + module.exit_json(**result) + + except TowerCLIError as e: + result['msg'] = "Failed to execute workflow: {0}".format(e) + module.fail_json(**result) + + +if __name__ == '__main__': + main() From 37509af8683be790dd1901682db5ba51b57f1789 Mon Sep 17 00:00:00 2001 From: John Westcott IV <32551173+john-westcott-iv@users.noreply.github.com> Date: Fri, 18 Jan 2019 06:11:17 -0500 Subject: [PATCH 073/103] Adding TowerCLI receive module (#51023) --- .../ansible_tower/tower_receive.py | 172 ++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py new file mode 100644 index 0000000000..1bbb006737 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py @@ -0,0 +1,172 @@ +#!/usr/bin/python +# coding: utf-8 -*- + +# (c) 2017, John Westcott IV +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: tower_receive +author: "John Westcott IV (@john-westcott-iv)" +version_added: "2.8" +short_description: Receive assets from Ansible Tower. +description: + - Receive assets from Ansible Tower. See + U(https://www.ansible.com/tower) for an overview. +options: + all: + description: + - Export all assets + type: bool + default: 'False' + organization: + description: + - List of organization names to export + default: [] + user: + description: + - List of user names to export + default: [] + team: + description: + - List of team names to export + default: [] + credential_type: + description: + - List of credential type names to export + default: [] + credential: + description: + - List of credential names to export + default: [] + notification_template: + description: + - List of notification template names to export + default: [] + inventory_script: + description: + - List of inventory script names to export + default: [] + inventory: + description: + - List of inventory names to export + default: [] + project: + description: + - List of project names to export + default: [] + job_template: + description: + - List of job template names to export + default: [] + workflow: + description: + - List of workflow names to export + default: [] + +requirements: + - "ansible-tower-cli >= 3.3.0" + +notes: + - Specifying a name of "all" for any asset type will export all items of that asset type. + +extends_documentation_fragment: tower +''' + +EXAMPLES = ''' +- name: Export all tower assets + tower_receive: + all: True + tower_config_file: "~/tower_cli.cfg" + +- name: Export all inventories + tower_receive: + inventory: + - all + +- name: Export a job template named "My Template" and all Credentials + tower_receive: + job_template: + - "My Template" + credential: + - all +''' + +RETURN = ''' +assets: + description: The exported assets + returned: success + type: dict + sample: [ {}, {} ] +''' + +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, HAS_TOWER_CLI + +try: + from tower_cli.cli.transfer.receive import Receiver + from tower_cli.cli.transfer.common import SEND_ORDER + from tower_cli.utils.exceptions import TowerCLIError + + from tower_cli.conf import settings + TOWER_CLI_HAS_EXPORT = True +except ImportError: + TOWER_CLI_HAS_EXPORT = False + + +def main(): + argument_spec = dict( + all=dict(type='bool', default=False), + credential=dict(type='list', default=[]), + credential_type=dict(type='list', default=[]), + inventory=dict(type='list', default=[]), + inventory_script=dict(type='list', default=[]), + job_template=dict(type='list', default=[]), + notification_template=dict(type='list', default=[]), + organization=dict(type='list', default=[]), + project=dict(type='list', default=[]), + team=dict(type='list', default=[]), + user=dict(type='list', default=[]), + workflow=dict(type='list', default=[]), + ) + + module = TowerModule(argument_spec=argument_spec, supports_check_mode=False) + + if not HAS_TOWER_CLI: + module.fail_json(msg='ansible-tower-cli required for this module') + + if not TOWER_CLI_HAS_EXPORT: + module.fail_json(msg='ansible-tower-cli version does not support export') + + export_all = module.params.get('all') + assets_to_export = {} + for asset_type in SEND_ORDER: + assets_to_export[asset_type] = module.params.get(asset_type) + + result = dict( + assets=None, + changed=False, + message='', + ) + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + try: + receiver = Receiver() + result['assets'] = receiver.export_assets(all=export_all, asset_input=assets_to_export) + module.exit_json(**result) + except TowerCLIError as e: + result['message'] = e + module.fail_json(msg='Receive Failed', **result) + + +if __name__ == '__main__': + main() From 58c4ae6a001dbc0d9bdff6d383b2b46444a935ce Mon Sep 17 00:00:00 2001 From: jainnikhil30 Date: Fri, 25 Jan 2019 19:12:14 +0530 Subject: [PATCH 074/103] Add scm_update_cache_timeout, job_timeout and custom_virtualenv to tower_project (#51330) * adding scm_update_cache_timeout and job_timeout to tower_project module * add support for cache_timeout, job_timeout and custom_venv for tower_project module * add the version_added --- .../ansible_tower/tower_project.py | 39 ++++++++++++++++++- 1 file changed, 38 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index c1b4a0c972..38adfd4a36 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -62,6 +62,21 @@ options: - Before an update to the local repository before launching a job with this project. type: bool default: 'no' + scm_update_cache_timeout: + version_added: "2.8" + description: + - Cache Timeout to cache prior project syncs for a certain number of seconds. + Only valid if scm_update_on_launch is to True, otherwise ignored. + default: 0 + job_timeout: + version_added: "2.8" + description: + - The amount of time (in seconds) to run before the SCM Update is canceled. A value of 0 means no timeout. + default: 0 + custom_virtualenv: + version_added: "2.8" + description: + - Local absolute file path containing a custom Python virtualenv to use organization: description: - Primary key of organization for project. @@ -82,6 +97,17 @@ EXAMPLES = ''' organization: "test" state: present tower_config_file: "~/tower_cli.cfg" + +- name: Add Tower Project with cache timeout and custom virtualenv + tower_project: + name: "Foo" + description: "Foo bar project" + organization: "test" + scm_update_on_launch: True + scm_update_cache_timeout: 60 + custom_virtualenv: "/var/lib/awx/venv/ansible-2.2" + state: present + tower_config_file: "~/tower_cli.cfg" ''' from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode @@ -107,8 +133,10 @@ def main(): scm_clean=dict(type='bool', default=False), scm_delete_on_update=dict(type='bool', default=False), scm_update_on_launch=dict(type='bool', default=False), + scm_update_cache_timeout=dict(type='int', default=0), + job_timeout=dict(type='int', default=0), + custom_virtualenv=dict(), local_path=dict(), - state=dict(choices=['present', 'absent'], default='present'), ) @@ -127,6 +155,9 @@ def main(): scm_clean = module.params.get('scm_clean') scm_delete_on_update = module.params.get('scm_delete_on_update') scm_update_on_launch = module.params.get('scm_update_on_launch') + scm_update_cache_timeout = module.params.get('scm_update_cache_timeout') + job_timeout = module.params.get('job_timeout') + custom_virtualenv = module.params.get('custom_virtualenv') state = module.params.get('state') json_output = {'project': name, 'state': state} @@ -155,12 +186,18 @@ def main(): except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update project, credential not found: {0}'.format(scm_credential), changed=False) + if (scm_update_cache_timeout is not None) and (scm_update_on_launch is not True): + module.warn('scm_update_cache_timeout will be ignored since scm_update_on_launch was not set to true') + result = project.modify(name=name, description=description, organization=org['id'], scm_type=scm_type, scm_url=scm_url, local_path=local_path, scm_branch=scm_branch, scm_clean=scm_clean, credential=scm_credential, scm_delete_on_update=scm_delete_on_update, scm_update_on_launch=scm_update_on_launch, + scm_update_cache_timeout=scm_update_cache_timeout, + job_timeout=job_timeout, + custom_virtualenv=custom_virtualenv, create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': From 5c2bc09f9dcbd2a953112aa60f7811e8481e2dfc Mon Sep 17 00:00:00 2001 From: Samuel Carpentier Date: Sun, 27 Jan 2019 11:28:49 -0500 Subject: [PATCH 075/103] New module: tower_notification (#50512) * New module: tower_notification * Fix CI check failures * Add integration tests and extend examples * Add missing required field for deletion tests and examples * Add missing required field for deletion tests and examples * Set port type to int * Add missing field for Slack notification * Add missing field types for IRC notification * Update module documentation * Correct field name and type for IRC notification * Uniformize 'targets' field * Uniformize 'targets' field --- .../ansible_tower/tower_notification.py | 393 ++++++++++++++++++ 1 file changed, 393 insertions(+) create mode 100644 lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py new file mode 100644 index 0000000000..4b6d74a233 --- /dev/null +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py @@ -0,0 +1,393 @@ +#!/usr/bin/python +# coding: utf-8 -*- + +# (c) 2018, Samuel Carpentier +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + +from __future__ import absolute_import, division, print_function +__metaclass__ = type + + +ANSIBLE_METADATA = {'metadata_version': '1.1', + 'status': ['preview'], + 'supported_by': 'community'} + + +DOCUMENTATION = ''' +--- +module: tower_notification +author: "Samuel Carpentier (@samcarpentier)" +version_added: "2.8" +short_description: create, update, or destroy Ansible Tower notification. +description: + - Create, update, or destroy Ansible Tower notifications. See + U(https://www.ansible.com/tower) for an overview. +options: + name: + description: + - The name of the notification. + required: True + description: + description: + - The description of the notification. + required: False + organization: + description: + - The organization the notification belongs to. + required: False + notification_type: + description: + - The type of notification to be sent. + required: True + choices: ["email", "slack", "twilio", "pagerduty", "hipchat", "webhook", "irc"] + notification_configuration: + description: + - The notification configuration file. Note providing this field would disable all notification-configuration-related fields. + required: False + username: + description: + - The mail server username. Required if I(notification_type=email). + required: False + sender: + description: + - The sender email address. Required if I(notification_type=email). + required: False + recipients: + description: + - The recipients email addresses. Required if I(notification_type=email). + required: False + use_tls: + description: + - The TLS trigger. Required if I(notification_type=email). + required: False + type: bool + host: + description: + - The mail server host. Required if I(notification_type=email). + required: False + use_ssl: + description: + - The SSL trigger. Required if I(notification_type=email) or if I(notification_type=irc). + required: False + type: bool + password: + description: + - The mail server password. Required if I(notification_type=email) or if I(notification_type=irc). + required: False + port: + description: + - The mail server port. Required if I(notification_type=email) or if I(notification_type=irc). + required: False + channels: + description: + - The destination Slack channels. Required if I(notification_type=slack). + required: False + type: list + token: + description: + - The access token. Required if I(notification_type=slack), if I(notification_type=pagerduty) or if I(notification_type=hipchat). + required: False + account_token: + description: + - The Twillio account token. Required if I(notification_type=twillio). + required: False + from_number: + description: + - The source phone number. Required if I(notification_type=twillio). + required: False + to_numbers: + description: + - The destination phone numbers. Required if I(notification_type=twillio). + required: False + account_sid: + description: + - The Twillio accound SID. Required if I(notification_type=twillio). + required: False + subdomain: + description: + - The PagerDuty subdomain. Required if I(notification_type=pagerduty). + required: False + service_key: + description: + - The PagerDuty service/integration API key. Required if I(notification_type=pagerduty). + required: False + client_name: + description: + - The PagerDuty client identifier. Required if I(notification_type=pagerduty). + required: False + message_from: + description: + - The label to be shown with the notification. Required if I(notification_type=hipchat). + required: False + api_url: + description: + - The HipChat API URL. Required if I(notification_type=hipchat). + required: False + color: + description: + - The notification color. Required if I(notification_type=hipchat). + required: False + choices: ["yellow", "green", "red", "purple", "gray", "random"] + rooms: + description: + - HipChat rooms to send the notification to. Required if I(notification_type=hipchat). + required: False + type: list + notify: + description: + - The notify channel trigger. Required if I(notification_type=hipchat). + required: False + type: bool + url: + description: + - The target URL. Required if I(notification_type=webhook). + required: False + headers: + description: + - The HTTP headers as JSON string. Required if I(notification_type=webhook). + required: False + server: + description: + - The IRC server address. Required if I(notification_type=irc). + required: False + nickname: + description: + - The IRC nickname. Required if I(notification_type=irc). + required: False + targets: + description: + - The destination channels or users. Required if I(notification_type=irc). + required: False + type: list + state: + description: + - Desired state of the resource. + default: "present" + choices: ["present", "absent"] +extends_documentation_fragment: tower +''' + + +EXAMPLES = ''' +- name: Add Slack notification + tower_notification: + name: slack notification + notification_type: slack + channels: + - general + token: cefda9e2be1f21d11cdd9452f5b7f97fda977f42 + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Add webhook notification + tower_notification: + name: webhook notification + notification_type: webhook + url: http://www.example.com/hook + headers: + X-Custom-Header: value123 + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Add email notification + tower_notification: + name: email notification + notification_type: email + username: user + password: s3cr3t + sender: tower@example.com + recipients: + - user1@example.com + host: smtp.example.com + port: 25 + use_tls: no + use_ssl: no + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Add twilio notification + tower_notification: + name: twilio notification + notification_type: twilio + account_token: a_token + account_sid: a_sid + from_number: '+15551112222' + to_numbers: + - '+15553334444' + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Add PagerDuty notification + tower_notification: + name: pagerduty notification + notification_type: pagerduty + token: a_token + subdomain: sub + client_name: client + service_key: a_key + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Add HipChat notification + tower_notification: + name: hipchat notification + notification_type: hipchat + token: a_token + message_from: user1 + api_url: https://hipchat.example.com + color: red + rooms: + - room-A + notify: yes + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Add IRC notification + tower_notification: + name: irc notification + notification_type: irc + nickname: tower + password: s3cr3t + targets: + - user1 + port: 8080 + server: irc.example.com + use_ssl: no + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Delete notification + tower_notification: + name: old notification + notification_type: email + state: absent + tower_config_file: "~/tower_cli.cfg" +''' + + +RETURN = ''' # ''' + + +from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode + +try: + import tower_cli + import tower_cli.utils.exceptions as exc + + from tower_cli.conf import settings +except ImportError: + pass + + +def main(): + argument_spec = dict( + name=dict(required=True), + description=dict(required=False), + organization=dict(required=False), + notification_type=dict(required=True, choices=['email', 'slack', 'twilio', 'pagerduty', 'hipchat', 'webhook', 'irc']), + notification_configuration=dict(required=False), + username=dict(required=False), + sender=dict(required=False), + recipients=dict(required=False, type='list'), + use_tls=dict(required=False, type='bool'), + host=dict(required=False), + use_ssl=dict(required=False, type='bool'), + password=dict(required=False, no_log=True), + port=dict(required=False, type='int'), + channels=dict(required=False, type='list'), + token=dict(required=False, no_log=True), + account_token=dict(required=False, no_log=True), + from_number=dict(required=False), + to_numbers=dict(required=False, type='list'), + account_sid=dict(required=False), + subdomain=dict(required=False), + service_key=dict(required=False, no_log=True), + client_name=dict(required=False), + message_from=dict(required=False), + api_url=dict(required=False), + color=dict(required=False, choices=['yellow', 'green', 'red', 'purple', 'gray', 'random']), + rooms=dict(required=False, type='list'), + notify=dict(required=False, type='bool'), + url=dict(required=False), + headers=dict(required=False, type='dict', default={}), + server=dict(required=False), + nickname=dict(required=False), + targets=dict(required=False, type='list'), + state=dict(choices=['present', 'absent'], default='present'), + ) + + module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) + + name = module.params.get('name') + description = module.params.get('description') + organization = module.params.get('organization') + notification_type = module.params.get('notification_type') + notification_configuration = module.params.get('notification_configuration') + username = module.params.get('username') + sender = module.params.get('sender') + recipients = module.params.get('recipients') + use_tls = module.params.get('use_tls') + host = module.params.get('host') + use_ssl = module.params.get('use_ssl') + password = module.params.get('password') + port = module.params.get('port') + channels = module.params.get('channels') + token = module.params.get('token') + account_token = module.params.get('account_token') + from_number = module.params.get('from_number') + to_numbers = module.params.get('to_numbers') + account_sid = module.params.get('account_sid') + subdomain = module.params.get('subdomain') + service_key = module.params.get('service_key') + client_name = module.params.get('client_name') + message_from = module.params.get('message_from') + api_url = module.params.get('api_url') + color = module.params.get('color') + rooms = module.params.get('rooms') + notify = module.params.get('notify') + url = module.params.get('url') + headers = module.params.get('headers') + server = module.params.get('server') + nickname = module.params.get('nickname') + targets = module.params.get('targets') + state = module.params.get('state') + + json_output = {'notification': name, 'state': state} + + tower_auth = tower_auth_config(module) + with settings.runtime_values(**tower_auth): + tower_check_mode(module) + notification_template = tower_cli.get_resource('notification_template') + + try: + org_res = tower_cli.get_resource('organization') + org = org_res.get(name=organization) + + if state == 'present': + result = notification_template.modify(name=name, description=description, organization=org['id'], + notification_type=notification_type, + notification_configuration=notification_configuration, + username=username, sender=sender, recipients=recipients, + use_tls=use_tls, host=host, use_ssl=use_ssl, password=password, + port=port, channels=channels, token=token, + account_token=account_token, from_number=from_number, + to_numbers=to_numbers, account_sid=account_sid, + subdomain=subdomain, service_key=service_key, + client_name=client_name, message_from=message_from, + api_url=api_url, color=color, rooms=rooms, notify=notify, + url=url, headers=headers, server=server, nickname=nickname, + targets=targets, create_on_missing=True) + json_output['id'] = result['id'] + elif state == 'absent': + result = notification_template.delete(name=name) + except (exc.NotFound) as excinfo: + module.fail_json(msg='Failed to update notification template, organization not found: {0}'.format(excinfo), changed=False) + except (exc.ConnectionError, exc.BadRequest) as excinfo: + module.fail_json(msg='Failed to update notification template: {0}'.format(excinfo), changed=False) + + json_output['changed'] = result['changed'] + module.exit_json(**json_output) + + +if __name__ == '__main__': + main() From 71c625bd839513d6ccd958efb9a65b3ca52ab9e3 Mon Sep 17 00:00:00 2001 From: Dennis Lerch <45554796+dlerch-tpgroup@users.noreply.github.com> Date: Fri, 1 Feb 2019 08:18:18 +0100 Subject: [PATCH 076/103] add diff_mode_enabled to documentation option 'diff_mode_enabled' is not mentioned in documentation +label: docsite_pr --- .../web_infrastructure/ansible_tower/tower_job_template.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 4f69ec99d5..36106998a3 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -84,6 +84,12 @@ options: description: - Start the playbook at the task matching this name. version_added: 2.7 + diff_mode_enabled: + description: + - Enable diff mode for the job template. + version_added: 2.7 + type: bool + default: 'no' fact_caching_enabled: description: - Enable use of fact caching for the job template. From ca782a495d22ee3f83b341581283f216b5ea68a0 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Fri, 8 Feb 2019 10:07:01 +1000 Subject: [PATCH 077/103] Final round of moving modules to new import error msg (#51852) * Final round of moving modules to new import error msg * readd URL to jenkins install guide * fix unit tests --- lib/ansible/module_utils/ansible_tower.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index 0e3d1301c0..9caf3e3e65 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -27,7 +27,9 @@ # USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. import os +import traceback +TOWER_CLI_IMP_ERR = None try: import tower_cli.utils.exceptions as exc from tower_cli.utils import parser @@ -35,9 +37,10 @@ try: HAS_TOWER_CLI = True except ImportError: + TOWER_CLI_IMP_ERR = traceback.format_exc() HAS_TOWER_CLI = False -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.basic import AnsibleModule, missing_required_lib def tower_auth_config(module): @@ -105,4 +108,5 @@ class TowerModule(AnsibleModule): super(TowerModule, self).__init__(argument_spec=args, **kwargs) if not HAS_TOWER_CLI: - self.fail_json(msg='ansible-tower-cli required for this module') + self.fail_json(msg=missing_required_lib('ansible-tower-cli'), + exception=TOWER_CLI_IMP_ERR) From c6e47a0a16ff0262e2654bfa2c1935b2ee842d18 Mon Sep 17 00:00:00 2001 From: Pilou Date: Wed, 13 Feb 2019 11:26:43 +0100 Subject: [PATCH 078/103] tower modules: check that 'verify_ssl' defined in ~/.tower_cli.cfg isn't ignored (#50687) * Check that verify_ssl defined in tower_cli.cfg isn't ignored * Avoid to override verify_ssl value defined in tower_cli.cfg By default, tower-cli library enables SSL certificates check. But verify_ssl false value defined in config files read by default by tower-cli library (for example /etc/tower/tower_cli.cfg) was ignored because overriden by the tower_verify_ssl parameter default value. * fix a typo in comment --- lib/ansible/module_utils/ansible_tower.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index 9caf3e3e65..a0aed73a54 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -47,7 +47,7 @@ def tower_auth_config(module): '''tower_auth_config attempts to load the tower-cli.cfg file specified from the `tower_config_file` parameter. If found, if returns the contents of the file as a dictionary, else - it will attempt to fetch values from the module pararms and + it will attempt to fetch values from the module params and only pass those values that have been set. ''' config_file = module.params.pop('tower_config_file', None) @@ -92,7 +92,7 @@ class TowerModule(AnsibleModule): tower_host=dict(), tower_username=dict(), tower_password=dict(no_log=True), - tower_verify_ssl=dict(type='bool', default=True), + tower_verify_ssl=dict(type='bool'), tower_config_file=dict(type='path'), ) args.update(argument_spec) From b034295c994962b8304ca502be32f4e1588130b6 Mon Sep 17 00:00:00 2001 From: David Medberry Date: Mon, 18 Feb 2019 08:49:11 -0700 Subject: [PATCH 079/103] Update tower_credential.py (#51469) misspelled word and poor capitalization (in the same sentence of the doc string) +label: docsite_pr --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 2b30355363..46152baebf 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -93,7 +93,7 @@ options: - Domain for openstack type. become_method: description: - - Become method to Use for privledge escalation. + - Become method to use for privilege escalation. choices: ["None", "sudo", "su", "pbrun", "pfexec", "pmrun"] become_username: description: From b96b69360fa7ca3570ee32051d9594513ff9c45b Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Wed, 6 Mar 2019 16:48:43 +0530 Subject: [PATCH 080/103] tower: Handle AuthError (#53377) Handle AuthError raised when user provides incorrect password for Tower admin user. Fixes: #50535 Signed-off-by: Abhijeet Kasurde --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- .../web_infrastructure/ansible_tower/tower_credential_type.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_group.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_host.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_inventory.py | 2 +- .../web_infrastructure/ansible_tower/tower_inventory_source.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_cancel.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_launch.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_job_list.py | 2 +- .../web_infrastructure/ansible_tower/tower_job_template.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_job_wait.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_label.py | 2 +- .../web_infrastructure/ansible_tower/tower_notification.py | 2 +- .../web_infrastructure/ansible_tower/tower_organization.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_project.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_receive.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_role.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_send.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_settings.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_team.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_user.py | 2 +- .../web_infrastructure/ansible_tower/tower_workflow_launch.py | 2 +- .../web_infrastructure/ansible_tower/tower_workflow_template.py | 2 +- 23 files changed, 23 insertions(+), 23 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 46152baebf..6fe95e59cb 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -307,7 +307,7 @@ def main(): result = credential.delete(**params) except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update credential, organization not found: {0}'.format(excinfo), changed=False) - except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.NotFound, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update credential: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py index e8f28d9867..12b75a4029 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py @@ -159,7 +159,7 @@ def main(): params['fail_on_missing'] = False result = credential_type_res.delete(**params) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json( msg='Failed to update credential type: {0}'.format(excinfo), changed=False diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py index 50772891ff..666b7386b8 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py @@ -166,7 +166,7 @@ def main(): result = group.delete(**params) except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update the group, inventory not found: {0}'.format(excinfo), changed=False) - except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.NotFound, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update the group: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py index 492c4842c0..6fd411a636 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py @@ -120,7 +120,7 @@ def main(): 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: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update host: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py index 1be2477321..c709ab7c8a 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py @@ -119,7 +119,7 @@ def main(): result = inventory.delete(name=name, organization=org['id']) except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update inventory, organization not found: {0}'.format(excinfo), changed=False) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update inventory: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py index 11c6439a1d..48a1e9ce1d 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py @@ -302,7 +302,7 @@ def main(): params['fail_on_missing'] = False result = inventory_source.delete(**params) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update inventory source: \ {0}'.format(excinfo), changed=False) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py index f2f5f8eada..02fa3b7b19 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py @@ -89,7 +89,7 @@ def main(): try: result = job.cancel(job_id, **params) json_output['id'] = job_id - except (exc.ConnectionError, exc.BadRequest, exc.TowerCLIError) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.TowerCLIError, exc.AuthError) as excinfo: module.fail_json(msg='Unable to cancel job_id/{0}: {1}'.format(job_id, excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index c34ec3dd23..d05abba097 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -134,7 +134,7 @@ def main(): result = job.launch(no_input=True, **params) json_output['id'] = result['id'] json_output['status'] = result['status'] - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Unable to launch job: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py index 51eda5ecdb..5665f8d935 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py @@ -118,7 +118,7 @@ def main(): if query: params['query'] = query.items() json_output = job.list(**params) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to list jobs: {0}'.format(excinfo), changed=False) module.exit_json(**json_output) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 36106998a3..8e18195cb8 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -326,7 +326,7 @@ def main(): json_output['id'] = result['id'] elif state == 'absent': result = jt.delete(**params) - except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.NotFound, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update job template: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 8974289157..42bbbb68ee 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -132,7 +132,7 @@ def main(): json_output['timeout'] = True except exc.NotFound as excinfo: fail_json = dict(msg='Unable to wait, no job_id {0} found: {1}'.format(job_id, excinfo), changed=False) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: fail_json = dict(msg='Unable to wait for job: {0}'.format(excinfo), changed=False) if fail_json is not None: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py index 554d154cb1..eca8ea1b55 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py @@ -91,7 +91,7 @@ def main(): result = label.delete(name=name, organization=org['id']) except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update label, organization not found: {0}'.format(excinfo), changed=False) - except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.NotFound, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update label: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py index 4b6d74a233..ae3ab87f7e 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py @@ -382,7 +382,7 @@ def main(): result = notification_template.delete(name=name) except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update notification template, organization not found: {0}'.format(excinfo), changed=False) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update notification template: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py index 8acbfd5108..bba58d8894 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py @@ -84,7 +84,7 @@ def main(): json_output['id'] = result['id'] elif state == 'absent': result = organization.delete(name=name) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update the organization: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py index 38adfd4a36..f8c380ce79 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py @@ -202,7 +202,7 @@ def main(): json_output['id'] = result['id'] elif state == 'absent': result = project.delete(name=name) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update project: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py index 1bbb006737..57fdd16df4 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py @@ -164,7 +164,7 @@ def main(): result['assets'] = receiver.export_assets(all=export_all, asset_input=assets_to_export) module.exit_json(**result) except TowerCLIError as e: - result['message'] = e + result['message'] = e.message module.fail_json(msg='Receive Failed', **result) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index 38a56514b9..cc3ce15577 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -144,7 +144,7 @@ def main(): json_output['id'] = result['id'] elif state == 'absent': result = role.revoke(**params) - except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.NotFound, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update role: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py index 387e82bcb7..4010ee7a1b 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py @@ -148,7 +148,7 @@ def main(): if sender.changed_messages > 0: result['changed'] = True except TowerCLIError as e: - result['msg'] = e + result['msg'] = e.message failed = True finally: if path is not None: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py index 1a2acbfb9e..6695fdf302 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py @@ -91,7 +91,7 @@ def main(): json_output['id'] = result['id'] json_output['value'] = result['value'] - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to modify the setting: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py index 4c49fd5447..5174d39ba7 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py @@ -96,7 +96,7 @@ def main(): result = team.delete(name=name, organization=org['id']) except (exc.NotFound) as excinfo: module.fail_json(msg='Failed to update team, organization not found: {0}'.format(excinfo), changed=False) - except (exc.ConnectionError, exc.BadRequest, exc.NotFound) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.NotFound, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update team: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 86baf18e90..a16a44d823 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -119,7 +119,7 @@ def main(): json_output['id'] = result['id'] elif state == 'absent': result = user.delete(username=username) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update the user: {0}'.format(excinfo), changed=False) json_output['changed'] = result['changed'] diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py index a7174ec3b2..e55e800482 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py @@ -51,7 +51,7 @@ tower_version: type: str sample: '3.4.0' job_info: - description: dictionnary containing information about the workflow executed + description: dictionary containing information about the workflow executed returned: If workflow launched type: dict ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py index 89e0744411..ef8565c05e 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py @@ -168,7 +168,7 @@ def main(): elif state == 'absent': params['fail_on_missing'] = False result = wfjt_res.delete(**params) - except (exc.ConnectionError, exc.BadRequest) as excinfo: + except (exc.ConnectionError, exc.BadRequest, exc.AuthError) as excinfo: module.fail_json(msg='Failed to update workflow template: \ {0}'.format(excinfo), changed=False) From 91d0c471202dcf2376cb64063ce57b4a7f842f27 Mon Sep 17 00:00:00 2001 From: Alan Rominger Date: Wed, 6 Mar 2019 10:32:05 -0500 Subject: [PATCH 081/103] Add option for tower inventory to give general metadata (#52747) --- lib/ansible/plugins/inventory/tower.py | 52 +++++++++++++++++--------- 1 file changed, 34 insertions(+), 18 deletions(-) diff --git a/lib/ansible/plugins/inventory/tower.py b/lib/ansible/plugins/inventory/tower.py index 79b2776a4d..f77368f7e4 100644 --- a/lib/ansible/plugins/inventory/tower.py +++ b/lib/ansible/plugins/inventory/tower.py @@ -59,6 +59,11 @@ DOCUMENTATION = ''' env: - name: TOWER_VERIFY_SSL required: False + include_metadata: + description: Make extra requests to provide all group vars with metadata about the source Ansible Tower host. + type: bool + default: False + version_added: "2.8" ''' EXAMPLES = ''' @@ -110,20 +115,11 @@ class InventoryModule(BaseInventoryPlugin): # If the user supplies '@tower_inventory' as path, the plugin will read from environment variables. no_config_file_supplied = False - def read_tower_inventory(self, tower_host, tower_user, tower_pass, inventory, verify_ssl=True): - if not re.match('(?:http|https)://', tower_host): - tower_host = 'https://{tower_host}'.format(tower_host=tower_host) - inventory_id = inventory.replace('/', '') - inventory_url = '/api/v2/inventories/{inv_id}/script/?hostvars=1&towervars=1&all=1'.format(inv_id=inventory_id) - inventory_url = urljoin(tower_host, inventory_url) - - request_handler = Request(url_username=tower_user, - url_password=tower_pass, - force_basic_auth=True, - validate_certs=verify_ssl) - + def make_request(self, request_handler, tower_url): + """Makes the request to given URL, handles errors, returns JSON + """ try: - response = request_handler.get(inventory_url) + response = request_handler.get(tower_url) except (ConnectionError, urllib_error.URLError, socket.error, httplib.HTTPException) as e: error_msg = 'Connection to remote host failed: {err}'.format(err=e) # If Tower gives a readable error message, display that message to the user. @@ -153,11 +149,20 @@ class InventoryModule(BaseInventoryPlugin): self._read_config_data(path) # Read inventory from tower server. # Note the environment variables will be handled automatically by InventoryManager. - inventory = self.read_tower_inventory(self.get_option('host'), - self.get_option('username'), - self.get_option('password'), - self.get_option('inventory_id'), - verify_ssl=self.get_option('verify_ssl')) + tower_host = self.get_option('host') + if not re.match('(?:http|https)://', tower_host): + tower_host = 'https://{tower_host}'.format(tower_host=tower_host) + + request_handler = Request(url_username=self.get_option('username'), + url_password=self.get_option('password'), + force_basic_auth=True, + validate_certs=self.get_option('verify_ssl')) + + inventory_id = self.get_option('inventory_id').replace('/', '') + inventory_url = '/api/v2/inventories/{inv_id}/script/?hostvars=1&towervars=1&all=1'.format(inv_id=inventory_id) + inventory_url = urljoin(tower_host, inventory_url) + + inventory = self.make_request(request_handler, inventory_url) # To start with, create all the groups. for group_name in inventory: if group_name != '_meta': @@ -183,5 +188,16 @@ class InventoryModule(BaseInventoryPlugin): if group_name != '_meta': for var_name, var_value in six.iteritems(group_content.get('vars', {})): self.inventory.set_variable(group_name, var_name, var_value) + + # Fetch extra variables if told to do so + if self.get_option('include_metadata'): + config_url = urljoin(tower_host, '/api/v2/config/') + config_data = self.make_request(request_handler, config_url) + server_data = {} + server_data['license_type'] = config_data.get('license_info', {}).get('license_type', 'unknown') + for key in ('version', 'ansible_version'): + server_data[key] = config_data.get(key, 'unknown') + self.inventory.set_variable('all', 'tower_metadata', server_data) + # Clean up the inventory. self.inventory.reconcile_inventory() From 1eb61ba5ce3d84d4206e1c4b7ce3fbc0b879c266 Mon Sep 17 00:00:00 2001 From: Abhijeet Kasurde Date: Wed, 6 Mar 2019 23:14:14 +0530 Subject: [PATCH 082/103] tower_credential: Add parameter vault_id (#53400) vault_id allows user to specify vault identifier as per Tower UI. Fixes: #45644 Signed-off-by: Abhijeet Kasurde --- .../ansible_tower/tower_credential.py | 39 ++++++++++++++++++- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 6fe95e59cb..a8bdd1e5b5 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -27,43 +27,56 @@ options: description: - The name to use for the credential. required: True + type: str description: description: - The description to use for the credential. + type: str user: description: - User that should own this credential. + type: str team: description: - Team that should own this credential. + type: str project: description: - Project that should for this credential. + type: str organization: description: - Organization that should own the credential. required: True + type: str kind: description: - - Type of credential being added. The ssh choice refers to a Tower Machine credential. + - Type of credential being added. + - The ssh choice refers to a Tower Machine credential. required: True + type: str choices: ["ssh", "vault", "net", "scm", "aws", "vmware", "satellite6", "cloudforms", "gce", "azure_rm", "openstack", "rhv", "insights", "tower"] host: description: - Host for this credential. + type: str username: description: - Username for this credential. access_key for AWS. + type: str password: description: - Password for this credential. Use ASK for prompting. secret_key for AWS. api_key for RAX. + type: str ssh_key_data: description: - SSH private key content. To extract the content from a file path, use the lookup function (see examples). required: False + type: str ssh_key_unlock: description: - Unlock password for ssh_key. Use ASK for prompting. + type: str authorize: description: - Should use authorize for net type. @@ -72,43 +85,61 @@ options: authorize_password: description: - Password for net credentials that require authorize. + type: str client: description: - Client or application ID for azure_rm type. + type: str security_token: description: - STS token for aws type. version_added: "2.6" + type: str secret: description: - Secret token for azure_rm type. + type: str subscription: description: - Subscription ID for azure_rm type. + type: str tenant: description: - Tenant ID for azure_rm type. + type: str domain: description: - Domain for openstack type. + type: str become_method: description: - Become method to use for privilege escalation. choices: ["None", "sudo", "su", "pbrun", "pfexec", "pmrun"] + type: str become_username: description: - Become username. Use ASK for prompting. + type: str become_password: description: - Become password. Use ASK for prompting. + type: str vault_password: description: - Vault password. Use ASK for prompting. + type: str + vault_id: + description: + - Vault identifier. + - This parameter is only valid if C(kind) is specified as C(vault). + type: str + version_added: "2.8" state: description: - Desired state of the resource. choices: ["present", "absent"] default: "present" + type: str extends_documentation_fragment: tower ''' @@ -227,6 +258,7 @@ def main(): organization=dict(required=True), project=dict(), state=dict(choices=['present', 'absent'], default='present'), + vault_id=dict(), ) module = TowerModule(argument_spec=argument_spec, supports_check_mode=True) @@ -289,11 +321,14 @@ def main(): else: module.params['ssh_key_data'] = data + if module.params.get('vault_id', None) and module.params.get('kind') != 'vault': + module.fail_json(msg="Parameter 'vault_id' is only valid if parameter 'kind' is specified as 'vault'") + for key in ('authorize', 'authorize_password', 'client', 'security_token', 'secret', 'tenant', 'subscription', 'domain', 'become_method', 'become_username', 'become_password', 'vault_password', 'project', 'host', - 'username', 'password', 'ssh_key_data', + 'username', 'password', 'ssh_key_data', 'vault_id', 'ssh_key_unlock'): if 'kind' in params: params[key] = module.params.get(key) From aeaab411200efd2500b97c9ccb8d272c03eebe66 Mon Sep 17 00:00:00 2001 From: Pilou Date: Tue, 19 Mar 2019 16:28:16 +0000 Subject: [PATCH 083/103] tower_settings: "get" isn't implemented, "value" parameter is required (#54028) * tower_settings doc: 'get' isn't implemented * tower_settings: fix typo in argument_spec --- .../web_infrastructure/ansible_tower/tower_settings.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py index 6695fdf302..c5f572f38b 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py @@ -20,15 +20,17 @@ author: "Nikhil Jain (@jainnikhil30)" version_added: "2.7" short_description: Modify Ansible Tower settings. description: - - Get, Modify Ansible Tower settings. See + - Modify Ansible Tower settings. See U(https://www.ansible.com/tower) for an overview. options: name: description: - - Name of setting to get/modify + - Name of setting to modify + required: True value: description: - Value to be modified for given setting. + required: True extends_documentation_fragment: tower ''' @@ -67,8 +69,8 @@ except ImportError: def main(): argument_spec = dict( - name=dict(Required=True), - value=dict(Required=True), + name=dict(required=True), + value=dict(required=True), ) module = TowerModule( From 3aa7ee8d17997d19758ee8dac76303da2122a574 Mon Sep 17 00:00:00 2001 From: James Cassell Date: Thu, 28 Mar 2019 01:19:28 -0400 Subject: [PATCH 084/103] standardize TLS connection properties (#54315) * openstack: standardize tls params * tower: tower_verify_ssl->validate_certs * docker: use standard tls config params - cacert_path -> ca_cert - cert_path -> client_cert - key_path -> client_key - tls_verify -> validate_certs * k8s: standardize tls connection params - verify_ssl -> validate_certs - ssl_ca_cert -> ca_cert - cert_file -> client_cert - key_file -> client_key * ingate: verify_ssl -> validate_certs * manageiq: standardize tls params - verify_ssl -> validate_certs - ca_bundle_path -> ca_cert * mysql: standardize tls params - ssl_ca -> ca_cert - ssl_cert -> client_cert - ssl_key -> client_key * nios: ssl_verify -> validate_certs * postgresql: ssl_rootcert -> ca_cert * rabbitmq: standardize tls params - cacert -> ca_cert - cert -> client_cert - key -> client_key * rackspace: verify_ssl -> validate_certs * vca: verify_certs -> validate_certs * kubevirt_cdi_upload: upload_host_verify_ssl -> upload_host_validate_certs * lxd: standardize tls params - key_file -> client_key - cert_file -> client_cert * get_certificate: ca_certs -> ca_cert * get_certificate.py: clarify one or more certs in a file Co-Authored-By: jamescassell * zabbix: tls_issuer -> ca_cert * bigip_device_auth_ldap: standardize tls params - ssl_check_peer -> validate_certs - ssl_client_cert -> client_cert - ssl_client_key -> client_key - ssl_ca_cert -> ca_cert * vdirect: vdirect_validate_certs -> validate_certs * mqtt: standardize tls params - ca_certs -> ca_cert - certfile -> client_cert - keyfile -> client_key * pulp_repo: standardize tls params remove `importer_ssl` prefix * rhn_register: sslcacert -> ca_cert * yum_repository: standardize tls params The fix for yum_repository is not straightforward since this module is only a thin wrapper for the underlying commands and config. In this case, we add the new values as aliases, keeping the old as primary, only due to the internal structure of the module. Aliases added: - sslcacert -> ca_cert - sslclientcert -> client_cert - sslclientkey -> client_key - sslverify -> validate_certs * gitlab_hook: enable_ssl_verification -> hook_validate_certs * Adjust arguments for docker_swarm inventory plugin. * foreman callback: standardize tls params - ssl_cert -> client_cert - ssl_key -> client_key * grafana_annotations: validate_grafana_certs -> validate_certs * nrdp callback: validate_nrdp_certs -> validate_certs * kubectl connection: standardize tls params - kubectl_cert_file -> client_cert - kubectl_key_file -> client_key - kubectl_ssl_ca_cert -> ca_cert - kubectl_verify_ssl -> validate_certs * oc connection: standardize tls params - oc_cert_file -> client_cert - oc_key_file -> client_key - oc_ssl_ca_cert -> ca_cert - oc_verify_ssl -> validate_certs * psrp connection: cert_trust_path -> ca_cert TODO: cert_validation -> validate_certs (multi-valued vs bool) * k8s inventory: standardize tls params - cert_file -> client_cert - key_file -> client_key - ca_cert -> ca_cert - verify_ssl -> validate_certs * openshift inventory: standardize tls params - cert_file -> client_cert - key_file -> client_key - ca_cert -> ca_cert - verify_ssl -> validate_certs * tower inventory: verify_ssl -> validate_certs * hashi_vault lookup: cacert -> ca_cert * k8s lookup: standardize tls params - cert_file -> client_cert - key_file -> client_key - ca_cert -> ca_cert - verify_ssl -> validate_certs * laps_passord lookup: cacert_file -> ca_cert * changelog for TLS parameter standardization --- lib/ansible/module_utils/ansible_tower.py | 6 +++--- .../ansible_tower/tower_credential_type.py | 5 +++-- .../ansible_tower/tower_inventory_source.py | 5 +++-- lib/ansible/plugins/inventory/tower.py | 5 +++-- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index a0aed73a54..e20dd21326 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -70,7 +70,7 @@ def tower_auth_config(module): password = module.params.pop('tower_password', None) if password: auth_config['password'] = password - verify_ssl = module.params.pop('tower_verify_ssl', None) + verify_ssl = module.params.pop('validate_certs', None) if verify_ssl is not None: auth_config['verify_ssl'] = verify_ssl return auth_config @@ -92,7 +92,7 @@ class TowerModule(AnsibleModule): tower_host=dict(), tower_username=dict(), tower_password=dict(no_log=True), - tower_verify_ssl=dict(type='bool'), + validate_certs=dict(type='bool', aliases=['tower_verify_ssl']), tower_config_file=dict(type='path'), ) args.update(argument_spec) @@ -102,7 +102,7 @@ class TowerModule(AnsibleModule): ('tower_config_file', 'tower_host'), ('tower_config_file', 'tower_username'), ('tower_config_file', 'tower_password'), - ('tower_config_file', 'tower_verify_ssl'), + ('tower_config_file', 'validate_certs'), )) super(TowerModule, self).__init__(argument_spec=args, **kwargs) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py index 12b75a4029..831a35ad3f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py @@ -58,11 +58,12 @@ options: required: False default: "present" choices: ["present", "absent"] - tower_verify_ssl: + validate_certs: description: - Tower option to avoid certificates check. required: False type: bool + aliases: [ tower_verify_ssl ] extends_documentation_fragment: tower ''' @@ -75,7 +76,7 @@ EXAMPLES = ''' inputs: "{{ lookup('file', 'tower_credential_inputs_nexus.json') }}" injectors: {'extra_vars': {'nexus_credential': 'test' }} state: present - tower_verify_ssl: false + validate_certs: false - tower_credential_type: name: Nexus diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py index 48a1e9ce1d..9aec7a8b95 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py @@ -138,10 +138,11 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] - tower_verify_ssl: + validate_certs: description: - Tower option to avoid certificates check. type: bool + aliases: [ tower_verify_ssl ] extends_documentation_fragment: tower ''' @@ -158,7 +159,7 @@ EXAMPLES = ''' overwrite: true source_vars: '{ private: false }' state: present - tower_verify_ssl: false + validate_certs: false ''' diff --git a/lib/ansible/plugins/inventory/tower.py b/lib/ansible/plugins/inventory/tower.py index f77368f7e4..76eb7eb67b 100644 --- a/lib/ansible/plugins/inventory/tower.py +++ b/lib/ansible/plugins/inventory/tower.py @@ -52,13 +52,14 @@ DOCUMENTATION = ''' env: - name: TOWER_INVENTORY required: True - verify_ssl: + validate_certs: description: Specify whether Ansible should verify the SSL certificate of Ansible Tower host. type: bool default: True env: - name: TOWER_VERIFY_SSL required: False + aliases: [ verify_ssl ] include_metadata: description: Make extra requests to provide all group vars with metadata about the source Ansible Tower host. type: bool @@ -156,7 +157,7 @@ class InventoryModule(BaseInventoryPlugin): request_handler = Request(url_username=self.get_option('username'), url_password=self.get_option('password'), force_basic_auth=True, - validate_certs=self.get_option('verify_ssl')) + validate_certs=self.get_option('validate_certs')) inventory_id = self.get_option('inventory_id').replace('/', '') inventory_url = '/api/v2/inventories/{inv_id}/script/?hostvars=1&towervars=1&all=1'.format(inv_id=inventory_id) From df0bd0797ca98bc647a36d58d4451905910e76e3 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Tue, 9 Apr 2019 22:08:11 +0900 Subject: [PATCH 085/103] Fix handling of inventory and credential options for tower_job_launch (#54967) - Fixed issue #25017,#37567 - Add example for prompt on launch - Add integration test for prompt on launch Signed-off-by: Hideki Saito --- .../ansible_tower/tower_job_launch.py | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index d05abba097..87e9b2be22 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -58,11 +58,24 @@ extends_documentation_fragment: tower ''' EXAMPLES = ''' +# Launch a job template - name: Launch a job tower_job_launch: job_template: "My Job Template" register: job +- name: Wait for job max 120s + tower_job_wait: + job_id: job.id + timeout: 120 + +# Launch job template with inventory and credential for prompt on launch +- name: Launch a job with inventory and credential + tower_job_launch: + job_template: "My Job Template" + inventory: "My Inventory" + credential: "My Credential" + register: job - name: Wait for job max 120s tower_job_wait: job_id: job.id @@ -96,10 +109,10 @@ except ImportError: def main(): argument_spec = dict( - job_template=dict(required=True), + job_template=dict(required=True, type='str'), job_type=dict(choices=['run', 'check', 'scan']), - inventory=dict(), - credential=dict(), + inventory=dict(type='str', default=None), + credential=dict(type='str', default=None), limit=dict(), tags=dict(type='list'), extra_vars=dict(type='list'), @@ -126,8 +139,9 @@ def main(): for field in lookup_fields: try: name = params.pop(field) - result = tower_cli.get_resource(field).get(name=name) - params[field] = result['id'] + if name: + result = tower_cli.get_resource(field).get(name=name) + params[field] = result['id'] except exc.NotFound as excinfo: module.fail_json(msg='Unable to launch job, {0}/{1} was not found: {2}'.format(field, name, excinfo), changed=False) From ba8bd25da25f3a03f99c556fe70bbf586fa5fa62 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Tue, 16 Apr 2019 05:18:11 +0900 Subject: [PATCH 086/103] Fixed wrong variable specification format in examples (#55252) Signed-off-by: Hideki Saito --- .../web_infrastructure/ansible_tower/tower_job_launch.py | 4 ++-- .../web_infrastructure/ansible_tower/tower_job_wait.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py index 87e9b2be22..dbae9e9399 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py @@ -66,7 +66,7 @@ EXAMPLES = ''' - name: Wait for job max 120s tower_job_wait: - job_id: job.id + job_id: "{{ job.id }}" timeout: 120 # Launch job template with inventory and credential for prompt on launch @@ -78,7 +78,7 @@ EXAMPLES = ''' register: job - name: Wait for job max 120s tower_job_wait: - job_id: job.id + job_id: "{{ job.id }}" timeout: 120 ''' diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py index 42bbbb68ee..d512a07565 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py @@ -49,7 +49,7 @@ EXAMPLES = ''' - name: Wait for job max 120s tower_job_wait: - job_id: job.id + job_id: "{{ job.id }}" timeout: 120 ''' From 4ca0d8c72ad52b8a438a691cf88388f7c0cd1b6f Mon Sep 17 00:00:00 2001 From: stoned Date: Wed, 8 May 2019 13:11:51 -0400 Subject: [PATCH 087/103] Add missing roles to tower_role module (#56182) * Add missing roles to tower_role module * Placate 'ansible-test sanity --test pep8' --- .../modules/web_infrastructure/ansible_tower/tower_role.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py index cc3ce15577..9e6d6941fd 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py @@ -33,7 +33,8 @@ options: description: - The role type to grant/revoke. required: True - choices: ["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"] + choices: ["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor", "project_admin", "inventory_admin", "credential_admin", + "workflow_admin", "notification_admin", "job_template_admin"] target_team: description: - Team that the role acts on. @@ -113,7 +114,8 @@ def main(): argument_spec = dict( user=dict(), team=dict(), - role=dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor"]), + role=dict(choices=["admin", "read", "member", "execute", "adhoc", "update", "use", "auditor", "project_admin", "inventory_admin", "credential_admin", + "workflow_admin", "notification_admin", "job_template_admin"]), target_team=dict(), inventory=dict(), job_template=dict(), From 87f6065a0541d4e1f7334a60ce08fde74f162ab2 Mon Sep 17 00:00:00 2001 From: Pilou Date: Wed, 29 May 2019 16:15:45 +0000 Subject: [PATCH 088/103] tower_credential: ssh_key_data isn't a path anymore (#57113) --- .../web_infrastructure/ansible_tower/tower_credential.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index a8bdd1e5b5..32c9cf817f 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -168,7 +168,7 @@ EXAMPLES = ''' - name: Add Credential Into Tower tower_credential: name: Workshop Credential - ssh_key_data: "/home/{{ansible_user}}/.ssh/aws-private.pem" + ssh_key_data: "{{ lookup('file', '/home/' ~ {{ansible_user}} ~ '/.ssh/aws-private.pem') }}" kind: ssh organization: Default tower_username: admin From 5dce6258e6b18182f08a21fb628267ad7e0eeed7 Mon Sep 17 00:00:00 2001 From: Hideki Saito Date: Mon, 10 Jun 2019 16:48:02 +0900 Subject: [PATCH 089/103] tower_user: Fix to create a system auditor properly (#54585) - Fixed issue #54446: tower_user cannot create an auditor user Signed-off-by: Hideki Saito --- .../ansible_tower/tower_user.py | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index a16a44d823..13acab8279 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -55,6 +55,10 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] + +requirements: + - ansible-tower-cli >= 3.2.0 + extends_documentation_fragment: tower ''' @@ -69,6 +73,31 @@ EXAMPLES = ''' last_name: Doe state: present tower_config_file: "~/tower_cli.cfg" + +- name: Add tower user as a system administrator + tower_user: + username: jdoe + password: foobarbaz + email: jdoe@example.org + superuser: yes + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Add tower user as a system auditor + tower_user: + username: jdoe + password: foobarbaz + email: jdoe@example.org + auditor: yes + state: present + tower_config_file: "~/tower_cli.cfg" + +- name: Delete tower user + tower_user: + username: jdoe + email: jdoe@example.org + state: absent + tower_config_file: "~/tower_cli.cfg" ''' from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode @@ -115,7 +144,7 @@ def main(): if state == 'present': result = user.modify(username=username, first_name=first_name, last_name=last_name, email=email, password=password, is_superuser=superuser, - is_auditor=auditor, create_on_missing=True) + is_system_auditor=auditor, create_on_missing=True) json_output['id'] = result['id'] elif state == 'absent': result = user.delete(username=username) From 934d7d62efde899595fb6b1781e032ff579f18f0 Mon Sep 17 00:00:00 2001 From: Pilou Date: Tue, 11 Jun 2019 14:25:41 +0000 Subject: [PATCH 090/103] fix tower_credential example: lookup are run on controller (#57516) - don't advise to use lookups in order to fetch path on managed nodes - fix example: - use slurp instead 'file' lookup - remove extraneous brackets --- .../web_infrastructure/ansible_tower/tower_credential.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index 32c9cf817f..d82ccb9b92 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -165,10 +165,14 @@ EXAMPLES = ''' ssh_key_data: "{{ lookup('file', '/tmp/id_rsa') }}" ssh_key_unlock: "passphrase" +- name: Fetch private key + slurp: + src: '$HOME/.ssh/aws-private.pem' + register: aws_ssh_key - name: Add Credential Into Tower tower_credential: name: Workshop Credential - ssh_key_data: "{{ lookup('file', '/home/' ~ {{ansible_user}} ~ '/.ssh/aws-private.pem') }}" + ssh_key_data: "{{ aws_ssh_key['content'] | b64decode }}" kind: ssh organization: Default tower_username: admin @@ -311,7 +315,7 @@ def main(): data = module.params.get('ssh_key_data') if os.path.exists(data): module.deprecate( - msg='ssh_key_data should be a string, not a path to a file. Use lookup(\'file\', \'/path/to/file\') instead', + msg='ssh_key_data should be a string, not a path to a file.', version="2.12" ) if os.path.isdir(data): From 83183cd7ce70a3faedcf297916c16b361cf415e5 Mon Sep 17 00:00:00 2001 From: Alberto Murillo Date: Thu, 20 Jun 2019 10:55:37 -0700 Subject: [PATCH 091/103] tower_workflow_template: Add missing options (#56891) The following options can be set on a workflow template but the functionallity to do so from this module was missing. inventory ask_variables_on_launch ask_inventory_on_launch Fixes #49728 Signed-off-by: Alberto Murillo --- .../ansible_tower/tower_workflow_template.py | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py index ef8565c05e..3203a51d3b 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py @@ -27,12 +27,26 @@ options: description: - If enabled, simultaneous runs of this job template will be allowed. type: bool + ask_extra_vars: + description: + - Prompt user for (extra_vars) on launch. + type: bool + version_added: "2.9" + ask_inventory: + description: + - Propmt user for inventory on launch. + type: bool + version_added: "2.9" description: description: - The description to use for the workflow. extra_vars: description: - Extra variables used by Ansible in YAML or key=value format. + inventory: + description: + - Name of the inventory to use for the job template. + version_added: "2.9" name: description: - The name to use for the workflow. @@ -104,6 +118,9 @@ def main(): schema=dict(required=False), survey=dict(required=False), survey_enabled=dict(type='bool', required=False), + inventory=dict(required=False), + ask_inventory=dict(type='bool', required=False), + ask_extra_vars=dict(type='bool', required=False), state=dict(choices=['present', 'absent'], default='present'), ) @@ -153,8 +170,14 @@ def main(): if module.params.get('survey'): params['survey_spec'] = module.params.get('survey') - for key in ('allow_simultaneous', 'extra_vars', 'survey_enabled', - 'description'): + if module.params.get('ask_extra_vars'): + params['ask_variables_on_launch'] = module.params.get('ask_extra_vars') + + if module.params.get('ask_inventory'): + params['ask_inventory_on_launch'] = module.params.get('ask_inventory') + + for key in ('allow_simultaneous', 'extra_vars', 'inventory', + 'survey_enabled', 'description'): if module.params.get(key): params[key] = module.params.get(key) From 1ae1011ccbe59ac3a9903db7e100fd4c028c150c Mon Sep 17 00:00:00 2001 From: Pilou Date: Wed, 26 Jun 2019 08:04:50 +0000 Subject: [PATCH 092/103] tower_role: ensure alias of "validate_certs" parameter is handled (#57518) * tower_role: ensure alias of validate_certs is handled * tower modules: remove tower_verify_ssl alias too Error was: Failed to update role: The Tower server claims it was sent a bad request. GET https://tower/api/v2/projects/22/object_roles/ Params: [('tower_verify_ssl', False), ('role_field', 'admin_role')] Data: None Response: {"detail": "Role has no field named 'tower_verify_ssl'"} Full traceback: File "/tmp/ansible_tower_role_payload_7_2p0X/__main__.py", line 145, in main result = role.grant(**params) File "/usr/local/lib/python2.7/dist-packages/tower_cli/resources/role.py", line 365, in grant return self.role_write(fail_on_found=fail_on_found, **kwargs) File "/usr/local/lib/python2.7/dist-packages/tower_cli/resources/role.py", line 242, in role_write fail_on_multiple_results=True, **data) File "/usr/local/lib/python2.7/dist-packages/tower_cli/models/base.py", line 301, in read r = client.get(url, params=params) File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 546, in get return self.request('GET', url, **kwargs) File "/usr/local/lib/python2.7/dist-packages/tower_cli/api.py", line 299, in request kwargs.get('data', None), r.content.decode('utf8')) --- lib/ansible/module_utils/ansible_tower.py | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/ansible/module_utils/ansible_tower.py b/lib/ansible/module_utils/ansible_tower.py index e20dd21326..ef687a669c 100644 --- a/lib/ansible/module_utils/ansible_tower.py +++ b/lib/ansible/module_utils/ansible_tower.py @@ -70,6 +70,7 @@ def tower_auth_config(module): password = module.params.pop('tower_password', None) if password: auth_config['password'] = password + module.params.pop('tower_verify_ssl', None) # pop alias if used verify_ssl = module.params.pop('validate_certs', None) if verify_ssl is not None: auth_config['verify_ssl'] = verify_ssl From a7bf31d423b2b4306d8eb5cf8ccd65f82b5fd297 Mon Sep 17 00:00:00 2001 From: Alicia Cozine <879121+acozine@users.noreply.github.com> Date: Tue, 16 Jul 2019 14:37:47 -0500 Subject: [PATCH 093/103] clarifies how ASK works for Tower credentials (#59050) * clarifies how ASK works for credentials --- .../ansible_tower/tower_credential.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py index d82ccb9b92..8f8b41badf 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py @@ -62,11 +62,12 @@ options: type: str username: description: - - Username for this credential. access_key for AWS. + - Username for this credential. ``access_key`` for AWS. type: str password: description: - - Password for this credential. Use ASK for prompting. secret_key for AWS. api_key for RAX. + - Password for this credential. ``secret_key`` for AWS. ``api_key`` for RAX. + - Use "ASK" and launch in Tower to be prompted. type: str ssh_key_data: description: @@ -75,7 +76,8 @@ options: type: str ssh_key_unlock: description: - - Unlock password for ssh_key. Use ASK for prompting. + - Unlock password for ssh_key. + - Use "ASK" and launch in Tower to be prompted. type: str authorize: description: @@ -118,15 +120,18 @@ options: type: str become_username: description: - - Become username. Use ASK for prompting. + - Become username. + - Use "ASK" and launch in Tower to be prompted. type: str become_password: description: - - Become password. Use ASK for prompting. + - Become password. + - Use "ASK" and launch in Tower to be prompted. type: str vault_password: description: - - Vault password. Use ASK for prompting. + - Vault password. + - Use "ASK" and launch in Tower to be prompted. type: str vault_id: description: From bffc1bfdd4a55d5bf7de8704f7d83c9f3060b9bd Mon Sep 17 00:00:00 2001 From: Alan Rominger Date: Wed, 11 Sep 2019 11:48:38 -0400 Subject: [PATCH 094/103] Allow tower inventory plugin to accept integer inventory_id (#61338) --- lib/ansible/plugins/inventory/tower.py | 24 ++++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/lib/ansible/plugins/inventory/tower.py b/lib/ansible/plugins/inventory/tower.py index 76eb7eb67b..780f407cea 100644 --- a/lib/ansible/plugins/inventory/tower.py +++ b/lib/ansible/plugins/inventory/tower.py @@ -47,8 +47,12 @@ DOCUMENTATION = ''' - name: TOWER_PASSWORD required: True inventory_id: - description: The ID of the Ansible Tower inventory that you wish to import. - type: string + description: + - The ID of the Ansible Tower inventory that you wish to import. + - This is allowed to be either the inventory primary key or its named URL slug. + - Primary key values will be accepted as strings or integers, and URL slugs must be strings. + - Named URL slugs follow the syntax of "inventory_name++organization_name". + type: raw env: - name: TOWER_INVENTORY required: True @@ -100,8 +104,9 @@ import json from ansible.module_utils import six from ansible.module_utils.urls import Request, urllib_error, ConnectionError, socket, httplib from ansible.module_utils._text import to_native -from ansible.errors import AnsibleParserError +from ansible.errors import AnsibleParserError, AnsibleOptionsError from ansible.plugins.inventory import BaseInventoryPlugin +from ansible.config.manager import ensure_type # Python 2/3 Compatibility try: @@ -159,7 +164,18 @@ class InventoryModule(BaseInventoryPlugin): force_basic_auth=True, validate_certs=self.get_option('validate_certs')) - inventory_id = self.get_option('inventory_id').replace('/', '') + # validate type of inventory_id because we allow two types as special case + inventory_id = self.get_option('inventory_id') + if isinstance(inventory_id, int): + inventory_id = to_native(self.get_option('inventory_id')) + else: + try: + inventory_id = ensure_type(inventory_id, 'str') + except ValueError as e: + raise AnsibleOptionsError( + 'Invalid type for configuration option inventory_id, ' + 'not integer, and cannot convert to string: %s' % to_native(e)) + inventory_id = inventory_id.replace('/', '') inventory_url = '/api/v2/inventories/{inv_id}/script/?hostvars=1&towervars=1&all=1'.format(inv_id=inventory_id) inventory_url = urljoin(tower_host, inventory_url) From 30a6efdb935f3dd3761e312c1af1afb5c31cacb8 Mon Sep 17 00:00:00 2001 From: Andrey Klychkov Date: Thu, 12 Sep 2019 17:53:05 +0300 Subject: [PATCH 095/103] fix typos in web_infrastructure modules (#62202) --- .../web_infrastructure/ansible_tower/tower_job_template.py | 2 +- .../web_infrastructure/ansible_tower/tower_notification.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_send.py | 2 +- .../modules/web_infrastructure/ansible_tower/tower_user.py | 2 +- .../web_infrastructure/ansible_tower/tower_workflow_launch.py | 2 +- .../ansible_tower/tower_workflow_template.py | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py index 8e18195cb8..c52fb3e772 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py @@ -140,7 +140,7 @@ options: default: 'no' ask_inventory: description: - - Propmt user for inventory on launch. + - Prompt user for inventory on launch. type: bool default: 'no' ask_credential: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py index ae3ab87f7e..3a3d5084ee 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py @@ -101,7 +101,7 @@ options: required: False account_sid: description: - - The Twillio accound SID. Required if I(notification_type=twillio). + - The Twillio account SID. Required if I(notification_type=twillio). required: False subdomain: description: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py index 4010ee7a1b..d8011806fe 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py @@ -69,7 +69,7 @@ output: description: The import messages returned: success, fail type: list - sample: [ 'Message 1', 'Messag 2' ] + sample: [ 'Message 1', 'Message 2' ] ''' import os diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py index 13acab8279..d9224308d1 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py @@ -42,7 +42,7 @@ options: - Password of the user. superuser: description: - - User is a system wide administator. + - User is a system wide administrator. type: bool default: 'no' auditor: diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py index e55e800482..6f2c577d29 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py @@ -37,7 +37,7 @@ options: timeout: description: - If waiting for the workflow to complete this will abort after this - - ammount of seconds + amount of seconds requirements: - "python >= 2.6" diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py index 3203a51d3b..e8b2e5b354 100644 --- a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py +++ b/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py @@ -34,7 +34,7 @@ options: version_added: "2.9" ask_inventory: description: - - Propmt user for inventory on launch. + - Prompt user for inventory on launch. type: bool version_added: "2.9" description: @@ -80,7 +80,7 @@ extends_documentation_fragment: tower EXAMPLES = ''' - tower_workflow_template: name: Workflow Template - description: My very first Worflow Template + description: My very first Workflow Template organization: My optional Organization schema: "{{ lookup('file', 'my_workflow.json') }}" From 38112bae22b9f482556f693036cd8eeff6d869ab Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Wed, 11 Sep 2019 20:10:48 -0400 Subject: [PATCH 096/103] Use to_native for error messages, fix docs typo --- lib/ansible/plugins/inventory/tower.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lib/ansible/plugins/inventory/tower.py b/lib/ansible/plugins/inventory/tower.py index 780f407cea..f4f20fe509 100644 --- a/lib/ansible/plugins/inventory/tower.py +++ b/lib/ansible/plugins/inventory/tower.py @@ -103,7 +103,7 @@ import os import json from ansible.module_utils import six from ansible.module_utils.urls import Request, urllib_error, ConnectionError, socket, httplib -from ansible.module_utils._text import to_native +from ansible.module_utils._text import to_text, to_native from ansible.errors import AnsibleParserError, AnsibleOptionsError from ansible.plugins.inventory import BaseInventoryPlugin from ansible.config.manager import ensure_type @@ -127,18 +127,18 @@ class InventoryModule(BaseInventoryPlugin): try: response = request_handler.get(tower_url) except (ConnectionError, urllib_error.URLError, socket.error, httplib.HTTPException) as e: - error_msg = 'Connection to remote host failed: {err}'.format(err=e) + n_error_msg = 'Connection to remote host failed: {err}'.format(err=to_native(e)) # If Tower gives a readable error message, display that message to the user. if callable(getattr(e, 'read', None)): - error_msg += ' with message: {err_msg}'.format(err_msg=e.read()) - raise AnsibleParserError(to_native(error_msg)) + n_error_msg += ' with message: {err_msg}'.format(err_msg=to_native(e.read())) + raise AnsibleParserError(n_error_msg) # Attempt to parse JSON. try: return json.loads(response.read()) except (ValueError, TypeError) as e: # If the JSON parse fails, print the ValueError - raise AnsibleParserError(to_native('Failed to parse json from host: {err}'.format(err=e))) + raise AnsibleParserError('Failed to parse json from host: {err}'.format(err=to_native(e))) def verify_file(self, path): if path.endswith('@tower_inventory'): @@ -167,14 +167,15 @@ class InventoryModule(BaseInventoryPlugin): # validate type of inventory_id because we allow two types as special case inventory_id = self.get_option('inventory_id') if isinstance(inventory_id, int): - inventory_id = to_native(self.get_option('inventory_id')) + inventory_id = to_text(inventory_id, nonstring='simplerepr') else: try: inventory_id = ensure_type(inventory_id, 'str') except ValueError as e: raise AnsibleOptionsError( 'Invalid type for configuration option inventory_id, ' - 'not integer, and cannot convert to string: %s' % to_native(e)) + 'not integer, and cannot convert to string: {err}'.format(err=to_native(e)) + ) inventory_id = inventory_id.replace('/', '') inventory_url = '/api/v2/inventories/{inv_id}/script/?hostvars=1&towervars=1&all=1'.format(inv_id=inventory_id) inventory_url = urljoin(tower_host, inventory_url) From 5271c993ac3b0d4119988e4afe20671a8f07f26c Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Fri, 30 Aug 2019 17:05:20 -0400 Subject: [PATCH 097/103] Move commit for migration of Ansible core tower modules --- {lib/ansible => awx_modules}/plugins/inventory/tower.py | 0 .../ansible => awx_modules/plugins}/module_utils/ansible_tower.py | 0 .../ansible_tower => awx_modules/plugins/modules}/__init__.py | 0 .../plugins/modules}/tower_credential.py | 0 .../plugins/modules}/tower_credential_type.py | 0 .../ansible_tower => awx_modules/plugins/modules}/tower_group.py | 0 .../ansible_tower => awx_modules/plugins/modules}/tower_host.py | 0 .../plugins/modules}/tower_inventory.py | 0 .../plugins/modules}/tower_inventory_source.py | 0 .../plugins/modules}/tower_job_cancel.py | 0 .../plugins/modules}/tower_job_launch.py | 0 .../plugins/modules}/tower_job_list.py | 0 .../plugins/modules}/tower_job_template.py | 0 .../plugins/modules}/tower_job_wait.py | 0 .../ansible_tower => awx_modules/plugins/modules}/tower_label.py | 0 .../plugins/modules}/tower_notification.py | 0 .../plugins/modules}/tower_organization.py | 0 .../plugins/modules}/tower_project.py | 0 .../plugins/modules}/tower_receive.py | 0 .../ansible_tower => awx_modules/plugins/modules}/tower_role.py | 0 .../ansible_tower => awx_modules/plugins/modules}/tower_send.py | 0 .../plugins/modules}/tower_settings.py | 0 .../ansible_tower => awx_modules/plugins/modules}/tower_team.py | 0 .../ansible_tower => awx_modules/plugins/modules}/tower_user.py | 0 .../plugins/modules}/tower_workflow_launch.py | 0 .../plugins/modules}/tower_workflow_template.py | 0 26 files changed, 0 insertions(+), 0 deletions(-) rename {lib/ansible => awx_modules}/plugins/inventory/tower.py (100%) rename {lib/ansible => awx_modules/plugins}/module_utils/ansible_tower.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/__init__.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_credential.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_credential_type.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_group.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_host.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_inventory.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_inventory_source.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_job_cancel.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_job_launch.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_job_list.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_job_template.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_job_wait.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_label.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_notification.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_organization.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_project.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_receive.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_role.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_send.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_settings.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_team.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_user.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_workflow_launch.py (100%) rename {lib/ansible/modules/web_infrastructure/ansible_tower => awx_modules/plugins/modules}/tower_workflow_template.py (100%) diff --git a/lib/ansible/plugins/inventory/tower.py b/awx_modules/plugins/inventory/tower.py similarity index 100% rename from lib/ansible/plugins/inventory/tower.py rename to awx_modules/plugins/inventory/tower.py diff --git a/lib/ansible/module_utils/ansible_tower.py b/awx_modules/plugins/module_utils/ansible_tower.py similarity index 100% rename from lib/ansible/module_utils/ansible_tower.py rename to awx_modules/plugins/module_utils/ansible_tower.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/__init__.py b/awx_modules/plugins/modules/__init__.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/__init__.py rename to awx_modules/plugins/modules/__init__.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py b/awx_modules/plugins/modules/tower_credential.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential.py rename to awx_modules/plugins/modules/tower_credential.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py b/awx_modules/plugins/modules/tower_credential_type.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_credential_type.py rename to awx_modules/plugins/modules/tower_credential_type.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py b/awx_modules/plugins/modules/tower_group.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_group.py rename to awx_modules/plugins/modules/tower_group.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py b/awx_modules/plugins/modules/tower_host.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_host.py rename to awx_modules/plugins/modules/tower_host.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py b/awx_modules/plugins/modules/tower_inventory.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory.py rename to awx_modules/plugins/modules/tower_inventory.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py b/awx_modules/plugins/modules/tower_inventory_source.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_inventory_source.py rename to awx_modules/plugins/modules/tower_inventory_source.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py b/awx_modules/plugins/modules/tower_job_cancel.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_cancel.py rename to awx_modules/plugins/modules/tower_job_cancel.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py b/awx_modules/plugins/modules/tower_job_launch.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_launch.py rename to awx_modules/plugins/modules/tower_job_launch.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py b/awx_modules/plugins/modules/tower_job_list.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_list.py rename to awx_modules/plugins/modules/tower_job_list.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py b/awx_modules/plugins/modules/tower_job_template.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_template.py rename to awx_modules/plugins/modules/tower_job_template.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py b/awx_modules/plugins/modules/tower_job_wait.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_job_wait.py rename to awx_modules/plugins/modules/tower_job_wait.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py b/awx_modules/plugins/modules/tower_label.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_label.py rename to awx_modules/plugins/modules/tower_label.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py b/awx_modules/plugins/modules/tower_notification.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_notification.py rename to awx_modules/plugins/modules/tower_notification.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py b/awx_modules/plugins/modules/tower_organization.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_organization.py rename to awx_modules/plugins/modules/tower_organization.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py b/awx_modules/plugins/modules/tower_project.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_project.py rename to awx_modules/plugins/modules/tower_project.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py b/awx_modules/plugins/modules/tower_receive.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_receive.py rename to awx_modules/plugins/modules/tower_receive.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py b/awx_modules/plugins/modules/tower_role.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_role.py rename to awx_modules/plugins/modules/tower_role.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py b/awx_modules/plugins/modules/tower_send.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py rename to awx_modules/plugins/modules/tower_send.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py b/awx_modules/plugins/modules/tower_settings.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_settings.py rename to awx_modules/plugins/modules/tower_settings.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py b/awx_modules/plugins/modules/tower_team.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_team.py rename to awx_modules/plugins/modules/tower_team.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py b/awx_modules/plugins/modules/tower_user.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_user.py rename to awx_modules/plugins/modules/tower_user.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py b/awx_modules/plugins/modules/tower_workflow_launch.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_launch.py rename to awx_modules/plugins/modules/tower_workflow_launch.py diff --git a/lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py b/awx_modules/plugins/modules/tower_workflow_template.py similarity index 100% rename from lib/ansible/modules/web_infrastructure/ansible_tower/tower_workflow_template.py rename to awx_modules/plugins/modules/tower_workflow_template.py From 2f0f692f4a2758a2d3dc8c2b6c21c5affd39906a Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Fri, 30 Aug 2019 17:11:01 -0400 Subject: [PATCH 098/103] Integrate Ansible core tower modules content into AWX This commit includes all the changes involved in converting the old Ansible Tower modules from commits in Ansible core into the AWX collection that replaces it. Also includes work needed to integrate it into the AWX processes like tests, docs, and the Makefile. Apply changes from content_collector tool Add integrated module tests operate via run_module fixture add makefile target for them Add flake8 target and fix flake8 errors Update README Make consolidated target for testing modules --- .gitignore | 4 + Makefile | 24 ++++ awx_modules/README.md | 52 ++++++++ awx_modules/galaxy.yml | 16 +++ .../plugins/modules/tower_credential.py | 2 +- .../plugins/modules/tower_credential_type.py | 2 +- awx_modules/plugins/modules/tower_group.py | 2 +- awx_modules/plugins/modules/tower_host.py | 2 +- .../plugins/modules/tower_inventory.py | 2 +- .../plugins/modules/tower_inventory_source.py | 2 +- .../plugins/modules/tower_job_cancel.py | 2 +- .../plugins/modules/tower_job_launch.py | 2 +- awx_modules/plugins/modules/tower_job_list.py | 2 +- .../plugins/modules/tower_job_template.py | 2 +- awx_modules/plugins/modules/tower_job_wait.py | 4 +- awx_modules/plugins/modules/tower_label.py | 2 +- .../plugins/modules/tower_notification.py | 2 +- .../plugins/modules/tower_organization.py | 2 +- awx_modules/plugins/modules/tower_project.py | 8 +- awx_modules/plugins/modules/tower_receive.py | 2 +- awx_modules/plugins/modules/tower_role.py | 2 +- awx_modules/plugins/modules/tower_send.py | 4 +- awx_modules/plugins/modules/tower_settings.py | 2 +- awx_modules/plugins/modules/tower_team.py | 2 +- awx_modules/plugins/modules/tower_user.py | 2 +- .../plugins/modules/tower_workflow_launch.py | 2 +- .../modules/tower_workflow_template.py | 3 +- awx_modules/setup.cfg | 3 + awx_modules/test/awx/conftest.py | 121 ++++++++++++++++++ awx_modules/test/awx/test_job_template.py | 59 +++++++++ awx_modules/test/awx/test_organization.py | 25 ++++ setup.cfg | 2 +- 32 files changed, 333 insertions(+), 30 deletions(-) create mode 100644 awx_modules/README.md create mode 100644 awx_modules/galaxy.yml create mode 100644 awx_modules/setup.cfg create mode 100644 awx_modules/test/awx/conftest.py create mode 100644 awx_modules/test/awx/test_job_template.py create mode 100644 awx_modules/test/awx/test_organization.py diff --git a/.gitignore b/.gitignore index 778ea02004..2352b56baf 100644 --- a/.gitignore +++ b/.gitignore @@ -134,3 +134,7 @@ venv/* use_dev_supervisor.txt .idea/* + +# Ansible module tests +awx_modules_test_venv/ +awx-awx-*.tar.gz diff --git a/Makefile b/Makefile index 7e8c6362df..01b42653b9 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,7 @@ COMPOSE_TAG ?= $(GIT_BRANCH) COMPOSE_HOST ?= $(shell hostname) VENV_BASE ?= /venv +MODULES_VENV ?= /awx_devel/awx_modules_test_venv SCL_PREFIX ?= CELERY_SCHEDULE_FILE ?= /var/lib/awx/beat.db @@ -373,8 +374,31 @@ test: fi; \ PYTHONDONTWRITEBYTECODE=1 py.test -p no:cacheprovider -n auto $(TEST_DIRS) cd awxkit && $(VENV_BASE)/awx/bin/tox -re py2,py3 + make test_modules_all awx-manage check_migrations --dry-run --check -n 'vNNN_missing_migration_file' +prepare_modules_venv: + cd /awx_devel + rm -rf $(MODULES_VENV) + mkdir $(MODULES_VENV) + ln -s /usr/lib/python2.7/site-packages/ansible $(MODULES_VENV)/ansible + $(VENV_BASE)/awx/bin/pip install --target=$(MODULES_VENV) git+https://github.com/ansible/tower-cli.git + +MODULES_TEST_DIRS ?= awx_modules/test/awx + +test_modules: + @if [ "$(VENV_BASE)" ]; then \ + . $(VENV_BASE)/awx/bin/activate; \ + fi; \ + PYTHONPATH=$(MODULES_VENV):/awx_devel/awx_modules:$PYTHONPATH py.test $(MODULES_TEST_DIRS) + +flake8_modules: + flake8 awx_modules/ # Different settings, in main exclude list + +prepare_test_modules: prepare_modules_venv test_modules # deprecated + +test_modules_all: prepare_modules_venv test_modules flake8_modules + test_unit: @if [ "$(VENV_BASE)" ]; then \ . $(VENV_BASE)/awx/bin/activate; \ diff --git a/awx_modules/README.md b/awx_modules/README.md new file mode 100644 index 0000000000..f3118c3a1c --- /dev/null +++ b/awx_modules/README.md @@ -0,0 +1,52 @@ +# AWX Ansible Modules + +These modules allow for easy interaction with an AWX or Ansible Tower server +in Ansible playbooks. + +The previous home for these modules was in https://github.com/ansible/ansible +inside the folder `lib/ansible/modules/web_infrastructure/ansible_tower`. + +## Running + +To use these modules, the "old" tower-cli needs to be installed +in the virtual environment where the modules run. +You can install it from either: + + - https://github.com/ansible/tower-cli/ + - https://pypi.org/project/ansible-tower-cli/ + +To use these modules in AWX, you should create a custom virtual environment +to install the requirement into. NOTE: you will also probably still need +to set the job template extra_vars to include `ansible_python_interpreter` +to be the python in that virtual environment. + +## Running Tests + +Tests to verify compatibility with the most recent AWX code exist +in `awx_modules/test/awx`. These tests require that python packages +are available for all of `awx`, `ansible`, `tower_cli`, and the modules +themselves. + +The target `make prepare_modules_venv` will prepare some requirements +in the `awx_modules_test_venv` folder so that `make test_modules` can +be ran to actually run the tests. A single test can be ran via: + +``` +make test_modules MODULE_TEST_DIRS=awx_modules/test/awx/test_organization.py +``` + +## Building + +To build, you should not be in the AWX virtual environment. +This should work on any machine that has a sufficiently recent version +of Ansible installed. + +``` +cd awx_modules +ansible-galaxy build +``` + +This will leave a tar file in the awx_modules directory. + +This process may be amended in the future to template components of `galaxy.yml` +from values (such as version) taken from AWX. diff --git a/awx_modules/galaxy.yml b/awx_modules/galaxy.yml new file mode 100644 index 0000000000..257e9168d4 --- /dev/null +++ b/awx_modules/galaxy.yml @@ -0,0 +1,16 @@ +authors: +- Wayne Witzel III (@wwitzel3) +- Chris Meyers +dependencies: {} +description: Ansible modules that interact with the AWX API. +documentation: https://docs.ansible.com/ansible/latest/modules/list_of_web_infrastructure_modules.html#ansible-tower +homepage: https://ansible.com +issues: https://github.com/ansible/awx/issues +license: +- GPL-3.0-only +name: awx +namespace: awx +readme: README.md +repository: https://github.com/ansible/awx +tags: [] +version: 0.0.1 diff --git a/awx_modules/plugins/modules/tower_credential.py b/awx_modules/plugins/modules/tower_credential.py index 8f8b41badf..aac3d9406a 100644 --- a/awx_modules/plugins/modules/tower_credential.py +++ b/awx_modules/plugins/modules/tower_credential.py @@ -190,7 +190,7 @@ EXAMPLES = ''' import os from ansible.module_utils._text import to_text -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_credential_type.py b/awx_modules/plugins/modules/tower_credential_type.py index 831a35ad3f..d8b97ccc08 100644 --- a/awx_modules/plugins/modules/tower_credential_type.py +++ b/awx_modules/plugins/modules/tower_credential_type.py @@ -87,7 +87,7 @@ EXAMPLES = ''' RETURN = ''' # ''' -from ansible.module_utils.ansible_tower import ( +from ..module_utils.ansible_tower import ( TowerModule, tower_auth_config, tower_check_mode diff --git a/awx_modules/plugins/modules/tower_group.py b/awx_modules/plugins/modules/tower_group.py index 666b7386b8..8df1a73221 100644 --- a/awx_modules/plugins/modules/tower_group.py +++ b/awx_modules/plugins/modules/tower_group.py @@ -93,7 +93,7 @@ EXAMPLES = ''' import os -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_host.py b/awx_modules/plugins/modules/tower_host.py index 6fd411a636..c6011ab27b 100644 --- a/awx_modules/plugins/modules/tower_host.py +++ b/awx_modules/plugins/modules/tower_host.py @@ -66,7 +66,7 @@ EXAMPLES = ''' import os -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode, HAS_TOWER_CLI +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_inventory.py b/awx_modules/plugins/modules/tower_inventory.py index c709ab7c8a..20eaa19b0f 100644 --- a/awx_modules/plugins/modules/tower_inventory.py +++ b/awx_modules/plugins/modules/tower_inventory.py @@ -67,7 +67,7 @@ EXAMPLES = ''' ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_inventory_source.py b/awx_modules/plugins/modules/tower_inventory_source.py index 9aec7a8b95..063eeeea81 100644 --- a/awx_modules/plugins/modules/tower_inventory_source.py +++ b/awx_modules/plugins/modules/tower_inventory_source.py @@ -166,7 +166,7 @@ EXAMPLES = ''' RETURN = ''' # ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_job_cancel.py b/awx_modules/plugins/modules/tower_job_cancel.py index 02fa3b7b19..1a658f02f5 100644 --- a/awx_modules/plugins/modules/tower_job_cancel.py +++ b/awx_modules/plugins/modules/tower_job_cancel.py @@ -55,7 +55,7 @@ status: ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_job_launch.py b/awx_modules/plugins/modules/tower_job_launch.py index dbae9e9399..e790603ec9 100644 --- a/awx_modules/plugins/modules/tower_job_launch.py +++ b/awx_modules/plugins/modules/tower_job_launch.py @@ -96,7 +96,7 @@ status: ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_job_list.py b/awx_modules/plugins/modules/tower_job_list.py index 5665f8d935..e89589b498 100644 --- a/awx_modules/plugins/modules/tower_job_list.py +++ b/awx_modules/plugins/modules/tower_job_list.py @@ -78,7 +78,7 @@ results: ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_job_template.py b/awx_modules/plugins/modules/tower_job_template.py index c52fb3e772..f1ee9e5775 100644 --- a/awx_modules/plugins/modules/tower_job_template.py +++ b/awx_modules/plugins/modules/tower_job_template.py @@ -199,7 +199,7 @@ EXAMPLES = ''' survey_spec: "{{ lookup('file', 'my_survey.json') }}" ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_job_wait.py b/awx_modules/plugins/modules/tower_job_wait.py index d512a07565..bc6aa89b3f 100644 --- a/awx_modules/plugins/modules/tower_job_wait.py +++ b/awx_modules/plugins/modules/tower_job_wait.py @@ -82,7 +82,7 @@ status: ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode from ansible.module_utils.six.moves import cStringIO as StringIO @@ -125,7 +125,7 @@ def main(): job_id = params.get('job_id') try: result = job.monitor(job_id, **params) - except exc.Timeout as excinfo: + except exc.Timeout: result = job.status(job_id) result['id'] = job_id json_output['msg'] = 'Timeout waiting for job to finish.' diff --git a/awx_modules/plugins/modules/tower_label.py b/awx_modules/plugins/modules/tower_label.py index eca8ea1b55..b29a001a02 100644 --- a/awx_modules/plugins/modules/tower_label.py +++ b/awx_modules/plugins/modules/tower_label.py @@ -49,7 +49,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_notification.py b/awx_modules/plugins/modules/tower_notification.py index 3a3d5084ee..96833ce1dd 100644 --- a/awx_modules/plugins/modules/tower_notification.py +++ b/awx_modules/plugins/modules/tower_notification.py @@ -268,7 +268,7 @@ EXAMPLES = ''' RETURN = ''' # ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_organization.py b/awx_modules/plugins/modules/tower_organization.py index bba58d8894..d38d47b8b3 100644 --- a/awx_modules/plugins/modules/tower_organization.py +++ b/awx_modules/plugins/modules/tower_organization.py @@ -48,7 +48,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_project.py b/awx_modules/plugins/modules/tower_project.py index f8c380ce79..9216eb59f3 100644 --- a/awx_modules/plugins/modules/tower_project.py +++ b/awx_modules/plugins/modules/tower_project.py @@ -110,7 +110,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli @@ -171,7 +171,7 @@ def main(): try: org_res = tower_cli.get_resource('organization') org = org_res.get(name=organization) - except (exc.NotFound) as excinfo: + except exc.NotFound: module.fail_json(msg='Failed to update project, organization not found: {0}'.format(organization), changed=False) if scm_credential: @@ -179,11 +179,11 @@ def main(): cred_res = tower_cli.get_resource('credential') try: cred = cred_res.get(name=scm_credential) - except (tower_cli.exceptions.MultipleResults) as multi_res_excinfo: + except tower_cli.exceptions.MultipleResults: module.warn('Multiple credentials found for {0}, falling back looking in project organization'.format(scm_credential)) cred = cred_res.get(name=scm_credential, organization=org['id']) scm_credential = cred['id'] - except (exc.NotFound) as excinfo: + except exc.NotFound: module.fail_json(msg='Failed to update project, credential not found: {0}'.format(scm_credential), changed=False) if (scm_update_cache_timeout is not None) and (scm_update_on_launch is not True): diff --git a/awx_modules/plugins/modules/tower_receive.py b/awx_modules/plugins/modules/tower_receive.py index 57fdd16df4..6c61d927d7 100644 --- a/awx_modules/plugins/modules/tower_receive.py +++ b/awx_modules/plugins/modules/tower_receive.py @@ -109,7 +109,7 @@ assets: sample: [ {}, {} ] ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, HAS_TOWER_CLI +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, HAS_TOWER_CLI try: from tower_cli.cli.transfer.receive import Receiver diff --git a/awx_modules/plugins/modules/tower_role.py b/awx_modules/plugins/modules/tower_role.py index 9e6d6941fd..92b806e8f2 100644 --- a/awx_modules/plugins/modules/tower_role.py +++ b/awx_modules/plugins/modules/tower_role.py @@ -72,7 +72,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_send.py b/awx_modules/plugins/modules/tower_send.py index d8011806fe..3cd46ff613 100644 --- a/awx_modules/plugins/modules/tower_send.py +++ b/awx_modules/plugins/modules/tower_send.py @@ -76,7 +76,7 @@ import os import sys from ansible.module_utils.six.moves import StringIO -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, HAS_TOWER_CLI +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, HAS_TOWER_CLI from tempfile import mkstemp @@ -138,7 +138,7 @@ def main(): sys.stdout = captured_stdout = StringIO() try: sender.send(files, prevent, password_management) - except TypeError as e: + except TypeError: # Newer versions of TowerCLI require 4 parameters sender.send(files, prevent, [], password_management) diff --git a/awx_modules/plugins/modules/tower_settings.py b/awx_modules/plugins/modules/tower_settings.py index c5f572f38b..c429463450 100644 --- a/awx_modules/plugins/modules/tower_settings.py +++ b/awx_modules/plugins/modules/tower_settings.py @@ -56,7 +56,7 @@ EXAMPLES = ''' no_log: true ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_team.py b/awx_modules/plugins/modules/tower_team.py index 5174d39ba7..554e730382 100644 --- a/awx_modules/plugins/modules/tower_team.py +++ b/awx_modules/plugins/modules/tower_team.py @@ -50,7 +50,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_user.py b/awx_modules/plugins/modules/tower_user.py index d9224308d1..e361412eb3 100644 --- a/awx_modules/plugins/modules/tower_user.py +++ b/awx_modules/plugins/modules/tower_user.py @@ -100,7 +100,7 @@ EXAMPLES = ''' tower_config_file: "~/tower_cli.cfg" ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode +from ..module_utils.ansible_tower import TowerModule, tower_auth_config, tower_check_mode try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_workflow_launch.py b/awx_modules/plugins/modules/tower_workflow_launch.py index 6f2c577d29..8df65e8919 100644 --- a/awx_modules/plugins/modules/tower_workflow_launch.py +++ b/awx_modules/plugins/modules/tower_workflow_launch.py @@ -75,7 +75,7 @@ EXAMPLES = ''' register: workflow_task_info ''' -from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config +from ..module_utils.ansible_tower import TowerModule, tower_auth_config try: import tower_cli diff --git a/awx_modules/plugins/modules/tower_workflow_template.py b/awx_modules/plugins/modules/tower_workflow_template.py index e8b2e5b354..b3fc6e14d3 100644 --- a/awx_modules/plugins/modules/tower_workflow_template.py +++ b/awx_modules/plugins/modules/tower_workflow_template.py @@ -93,8 +93,7 @@ EXAMPLES = ''' RETURN = ''' # ''' -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.ansible_tower import ( +from ..module_utils.ansible_tower import ( TowerModule, tower_auth_config, tower_check_mode diff --git a/awx_modules/setup.cfg b/awx_modules/setup.cfg new file mode 100644 index 0000000000..fdfea44c7e --- /dev/null +++ b/awx_modules/setup.cfg @@ -0,0 +1,3 @@ +[flake8] +max-line-length=160 +ignore=E402 \ No newline at end of file diff --git a/awx_modules/test/awx/conftest.py b/awx_modules/test/awx/conftest.py new file mode 100644 index 0000000000..bdaa0db3bf --- /dev/null +++ b/awx_modules/test/awx/conftest.py @@ -0,0 +1,121 @@ +import io +import json +import datetime +import importlib +from contextlib import redirect_stdout +from unittest import mock + +from requests.models import Response + +import pytest + +from awx.main.tests.functional.conftest import _request +from awx.main.models import Organization, Project, Inventory, Credential, CredentialType + + +def sanitize_dict(din): + '''Sanitize Django response data to purge it of internal types + so it may be used to cast a requests response object + ''' + if isinstance(din, (int, str, type(None), bool)): + return din # native JSON types, no problem + elif isinstance(din, datetime.datetime): + return din.isoformat() + elif isinstance(din, list): + for i in range(len(din)): + din[i] = sanitize_dict(din[i]) + return din + elif isinstance(din, dict): + for k in din.copy().keys(): + din[k] = sanitize_dict(din[k]) + return din + else: + return str(din) # translation proxies often not string but stringlike + + +@pytest.fixture +def run_module(): + def rf(module_name, module_params, request_user): + + def new_request(self, method, url, **kwargs): + kwargs_copy = kwargs.copy() + if 'data' in kwargs: + kwargs_copy['data'] = json.loads(kwargs['data']) + + # make request + rf = _request(method.lower()) + django_response = rf(url, user=request_user, expect=None, **kwargs_copy) + + # requests library response object is different from the Django response, but they are the same concept + # this converts the Django response object into a requests response object for consumption + resp = Response() + py_data = django_response.data + sanitize_dict(py_data) + resp._content = bytes(json.dumps(django_response.data), encoding='utf8') + resp.status_code = django_response.status_code + return resp + + stdout_buffer = io.StringIO() + # Requies specific PYTHONPATH, see docs + # Note that a proper Ansiballz explosion of the modules will have an import path like: + # ansible_collections.awx.awx.plugins.modules.{} + # We should consider supporting that in the future + resource_module = importlib.import_module('plugins.modules.{}'.format(module_name)) + + # Ansible params can be passed as an invocation argument or over stdin + # this short circuits within the AnsibleModule interface + def mock_load_params(self): + self.params = module_params + + with mock.patch.object(resource_module.TowerModule, '_load_params', new=mock_load_params): + # Call the test utility (like a mock server) instead of issuing HTTP requests + with mock.patch('tower_cli.api.Session.request', new=new_request): + # Ansible modules return data to the mothership over stdout + with redirect_stdout(stdout_buffer): + try: + resource_module.main() + except SystemExit: + pass # A system exit indicates successful execution + + module_stdout = stdout_buffer.getvalue().strip() + result = json.loads(module_stdout) + return result + + return rf + + +@pytest.fixture +def organization(): + return Organization.objects.create(name='Default') + + +@pytest.fixture +def project(organization): + return Project.objects.create( + name="test-proj", + description="test-proj-desc", + organization=organization, + playbook_files=['helloworld.yml'], + local_path='_92__test_proj', + scm_revision='1234567890123456789012345678901234567890', + scm_url='localhost', + scm_type='git' + ) + + +@pytest.fixture +def inventory(organization): + return Inventory.objects.create( + name='test-inv', + organization=organization + ) + + +@pytest.fixture +def machine_credential(organization): + ssh_type = CredentialType.defaults['ssh']() + ssh_type.save() + return Credential.objects.create( + credential_type=ssh_type, name='machine-cred', + inputs={'username': 'test_user', 'password': 'pas4word'} + ) diff --git a/awx_modules/test/awx/test_job_template.py b/awx_modules/test/awx/test_job_template.py new file mode 100644 index 0000000000..e5ecfeb793 --- /dev/null +++ b/awx_modules/test/awx/test_job_template.py @@ -0,0 +1,59 @@ +import pytest + +from awx.main.models import JobTemplate + + +@pytest.mark.django_db +def test_create_job_template(run_module, admin_user, project, inventory): + + module_args = { + 'name': 'foo', 'playbook': 'helloworld.yml', + 'project': project.name, 'inventory': inventory.name, + 'job_type': 'run', + 'state': 'present' + } + + result = run_module('tower_job_template', module_args, admin_user) + + jt = JobTemplate.objects.get(name='foo') + + assert result == { + "job_template": "foo", + "state": "present", + "id": jt.id, + "changed": True, + "invocation": { + "module_args": module_args + } + } + + assert jt.project_id == project.id + assert jt.inventory_id == inventory.id + + +@pytest.mark.django_db +@pytest.mark.xfail(reason='Known limitation and needs to be fixed.') +def test_create_job_template_with_old_machine_cred(run_module, admin_user, project, inventory, machine_credential): + + module_args = { + 'name': 'foo', 'playbook': 'helloworld.yml', + 'project': project.name, 'inventory': inventory.name, 'credential': machine_credential.name, + 'job_type': 'run', + 'state': 'present' + } + + result = run_module('tower_job_template', module_args, admin_user) + + jt = JobTemplate.objects.get(name='foo') + + assert result == { + "job_template": "foo", + "state": "present", + "id": jt.id, + "changed": True, + "invocation": { + "module_args": module_args + } + } + + assert machine_credential.id in [cred.pk for cred in jt.credentials.all()] diff --git a/awx_modules/test/awx/test_organization.py b/awx_modules/test/awx/test_organization.py new file mode 100644 index 0000000000..ea76940fd4 --- /dev/null +++ b/awx_modules/test/awx/test_organization.py @@ -0,0 +1,25 @@ +import pytest + +from awx.main.models import Organization + + +@pytest.mark.django_db +def test_create_organization(run_module, admin_user): + + module_args = {'name': 'foo', 'description': 'barfoo', 'state': 'present'} + + result = run_module('tower_organization', module_args, admin_user) + + org = Organization.objects.get(name='foo') + + assert result == { + "organization": "foo", + "state": "present", + "id": org.id, + "changed": True, + "invocation": { + "module_args": module_args + } + } + + assert org.description == 'barfoo' diff --git a/setup.cfg b/setup.cfg index e99856b7b1..227322dace 100755 --- a/setup.cfg +++ b/setup.cfg @@ -18,4 +18,4 @@ exclude=.tox,venv,awx/lib/site-packages,awx/plugins/inventory/ec2.py,awx/plugins [flake8] max-line-length=160 ignore=E201,E203,E221,E225,E231,E241,E251,E261,E265,E303,W291,W391,W293,E731,W504 -exclude=.tox,venv,awx/lib/site-packages,awx/plugins/inventory,awx/ui,awx/api/urls.py,awx/main/migrations,awx/main/tests/data,node_modules/,awx/projects/,tools/docker,awx/settings/local_*.py,installer/openshift/settings.py,build/,installer/,awxkit/test +exclude=.tox,venv,awx/lib/site-packages,awx/plugins/inventory,awx/ui,awx/api/urls.py,awx/main/migrations,awx/main/tests/data,node_modules/,awx/projects/,tools/docker,awx/settings/local_*.py,installer/openshift/settings.py,build/,installer/,awxkit/test,awx_modules/ From 35afa374174320ab19716dc4a657cbf316b8a6cf Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Tue, 17 Sep 2019 15:48:00 -0400 Subject: [PATCH 099/103] Rename to collection, add license, galaxy build --- .gitignore | 5 +- Makefile | 32 +- awx_modules/COPYING | 674 ++++++++++++++++++++++ awx_modules/README.md | 56 +- awx_modules/{galaxy.yml => galaxy.yml.j2} | 6 +- awx_modules/template_galaxy.yml | 11 + 6 files changed, 741 insertions(+), 43 deletions(-) create mode 100644 awx_modules/COPYING rename awx_modules/{galaxy.yml => galaxy.yml.j2} (83%) create mode 100644 awx_modules/template_galaxy.yml diff --git a/.gitignore b/.gitignore index 2352b56baf..51a1cbce30 100644 --- a/.gitignore +++ b/.gitignore @@ -136,5 +136,6 @@ use_dev_supervisor.txt .idea/* # Ansible module tests -awx_modules_test_venv/ -awx-awx-*.tar.gz +awx_collection_test_venv/ +awx_modules/*.tar.gz +awx_modules/galaxy.yml diff --git a/Makefile b/Makefile index 01b42653b9..b493c51826 100644 --- a/Makefile +++ b/Makefile @@ -18,7 +18,7 @@ COMPOSE_TAG ?= $(GIT_BRANCH) COMPOSE_HOST ?= $(shell hostname) VENV_BASE ?= /venv -MODULES_VENV ?= /awx_devel/awx_modules_test_venv +COLLECTION_VENV ?= /awx_devel/awx_collection_test_venv SCL_PREFIX ?= CELERY_SCHEDULE_FILE ?= /var/lib/awx/beat.db @@ -374,30 +374,36 @@ test: fi; \ PYTHONDONTWRITEBYTECODE=1 py.test -p no:cacheprovider -n auto $(TEST_DIRS) cd awxkit && $(VENV_BASE)/awx/bin/tox -re py2,py3 - make test_modules_all + make test_collection_all awx-manage check_migrations --dry-run --check -n 'vNNN_missing_migration_file' -prepare_modules_venv: +prepare_collection_venv: cd /awx_devel - rm -rf $(MODULES_VENV) - mkdir $(MODULES_VENV) - ln -s /usr/lib/python2.7/site-packages/ansible $(MODULES_VENV)/ansible - $(VENV_BASE)/awx/bin/pip install --target=$(MODULES_VENV) git+https://github.com/ansible/tower-cli.git + rm -rf $(COLLECTION_VENV) + mkdir $(COLLECTION_VENV) + ln -s /usr/lib/python2.7/site-packages/ansible $(COLLECTION_VENV)/ansible + $(VENV_BASE)/awx/bin/pip install --target=$(COLLECTION_VENV) git+https://github.com/ansible/tower-cli.git -MODULES_TEST_DIRS ?= awx_modules/test/awx +COLLECTION_TEST_DIRS ?= awx_modules/test/awx +COLLECTION_PACKAGE_NAME ?= awx +COLLECTION_NAMESPACE_NAME ?= awx -test_modules: +test_collection: @if [ "$(VENV_BASE)" ]; then \ . $(VENV_BASE)/awx/bin/activate; \ fi; \ - PYTHONPATH=$(MODULES_VENV):/awx_devel/awx_modules:$PYTHONPATH py.test $(MODULES_TEST_DIRS) + PYTHONPATH=$(COLLECTION_VENV):/awx_devel/awx_modules:$PYTHONPATH py.test $(COLLECTION_TEST_DIRS) -flake8_modules: +flake8_collection: flake8 awx_modules/ # Different settings, in main exclude list -prepare_test_modules: prepare_modules_venv test_modules # deprecated +prepare_test_collection: prepare_collection_venv test_collection # deprecated -test_modules_all: prepare_modules_venv test_modules flake8_modules +test_collection_all: prepare_collection_venv test_collection flake8_collection + +build_collection: + ansible-playbook -i localhost, awx_modules/template_galaxy.yml -e package_name=$(COLLECTION_PACKAGE_NAME) -e namespace_name=$(COLLECTION_NAMESPACE_NAME) -e package_version=$(VERSION) + ansible-galaxy collection build awx_modules --output-path=awx_modules test_unit: @if [ "$(VENV_BASE)" ]; then \ diff --git a/awx_modules/COPYING b/awx_modules/COPYING new file mode 100644 index 0000000000..b743e04edb --- /dev/null +++ b/awx_modules/COPYING @@ -0,0 +1,674 @@ +GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + +Copyright (C) 2007 Free Software Foundation, Inc. +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. + + Preamble + +The GNU General Public License is a free, copyleft license for +software and other kinds of works. + +The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + +When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + +To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + +For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + +Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + +For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + +Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + +Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + +The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + +0. Definitions. + +"This License" refers to version 3 of the GNU General Public License. + +"Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + +"The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + +To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + +A "covered work" means either the unmodified Program or a work based +on the Program. + +To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + +To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + +An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + +1. Source Code. + +The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + +A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + +The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + +The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + +The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + +The Corresponding Source for a work in source code form is that +same work. + +2. Basic Permissions. + +All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + +You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + +Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + +3. Protecting Users' Legal Rights From Anti-Circumvention Law. + +No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + +When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + +4. Conveying Verbatim Copies. + +You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + +You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + +5. Conveying Modified Source Versions. + +You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + +a) The work must carry prominent notices stating that you modified +it, and giving a relevant date. + +b) The work must carry prominent notices stating that it is +released under this License and any conditions added under section +7. This requirement modifies the requirement in section 4 to +"keep intact all notices". + +c) You must license the entire work, as a whole, under this +License to anyone who comes into possession of a copy. This +License will therefore apply, along with any applicable section 7 +additional terms, to the whole of the work, and all its parts, +regardless of how they are packaged. This License gives no +permission to license the work in any other way, but it does not +invalidate such permission if you have separately received it. + +d) If the work has interactive user interfaces, each must display +Appropriate Legal Notices; however, if the Program has interactive +interfaces that do not display Appropriate Legal Notices, your +work need not make them do so. + +A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + +6. Conveying Non-Source Forms. + +You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + +a) Convey the object code in, or embodied in, a physical product +(including a physical distribution medium), accompanied by the +Corresponding Source fixed on a durable physical medium +customarily used for software interchange. + +b) Convey the object code in, or embodied in, a physical product +(including a physical distribution medium), accompanied by a +written offer, valid for at least three years and valid for as +long as you offer spare parts or customer support for that product +model, to give anyone who possesses the object code either (1) a +copy of the Corresponding Source for all the software in the +product that is covered by this License, on a durable physical +medium customarily used for software interchange, for a price no +more than your reasonable cost of physically performing this +conveying of source, or (2) access to copy the +Corresponding Source from a network server at no charge. + +c) Convey individual copies of the object code with a copy of the +written offer to provide the Corresponding Source. This +alternative is allowed only occasionally and noncommercially, and +only if you received the object code with such an offer, in accord +with subsection 6b. + +d) Convey the object code by offering access from a designated +place (gratis or for a charge), and offer equivalent access to the +Corresponding Source in the same way through the same place at no +further charge. You need not require recipients to copy the +Corresponding Source along with the object code. If the place to +copy the object code is a network server, the Corresponding Source +may be on a different server (operated by you or a third party) +that supports equivalent copying facilities, provided you maintain +clear directions next to the object code saying where to find the +Corresponding Source. Regardless of what server hosts the +Corresponding Source, you remain obligated to ensure that it is +available for as long as needed to satisfy these requirements. + +e) Convey the object code using peer-to-peer transmission, provided +you inform other peers where the object code and Corresponding +Source of the work are being offered to the general public at no +charge under subsection 6d. + +A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + +A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + +"Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + +If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + +The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + +Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + +7. Additional Terms. + +"Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + +When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + +Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + +a) Disclaiming warranty or limiting liability differently from the +terms of sections 15 and 16 of this License; or + +b) Requiring preservation of specified reasonable legal notices or +author attributions in that material or in the Appropriate Legal +Notices displayed by works containing it; or + +c) Prohibiting misrepresentation of the origin of that material, or +requiring that modified versions of such material be marked in +reasonable ways as different from the original version; or + +d) Limiting the use for publicity purposes of names of licensors or +authors of the material; or + +e) Declining to grant rights under trademark law for use of some +trade names, trademarks, or service marks; or + +f) Requiring indemnification of licensors and authors of that +material by anyone who conveys the material (or modified versions of +it) with contractual assumptions of liability to the recipient, for +any liability that these contractual assumptions directly impose on +those licensors and authors. + +All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + +If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + +Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + +8. Termination. + +You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + +However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + +9. Acceptance Not Required for Having Copies. + +You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + +10. Automatic Licensing of Downstream Recipients. + +Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + +An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + +You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + +11. Patents. + +A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + +A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + +Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + +In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + +If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + +If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + +A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + +Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + +12. No Surrender of Others' Freedom. + +If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + +13. Use with the GNU Affero General Public License. + +Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + +14. Revised Versions of this License. + +The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + +If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + +Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + +15. Disclaimer of Warranty. + +THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +16. Limitation of Liability. + +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + +17. Interpretation of Sections 15 and 16. + +If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + +How to Apply These Terms to Your New Programs + +If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + +To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + +Copyright (C) + +This program 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 program 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 program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + +If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) +This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. +This is free software, and you are welcome to redistribute it +under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + +You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + +The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/awx_modules/README.md b/awx_modules/README.md index f3118c3a1c..25313673ff 100644 --- a/awx_modules/README.md +++ b/awx_modules/README.md @@ -1,52 +1,58 @@ -# AWX Ansible Modules +# AWX Ansible Collection -These modules allow for easy interaction with an AWX or Ansible Tower server -in Ansible playbooks. +This Ansible collection allow for easy interaction with an AWX or Ansible Tower +server in Ansible playbooks. -The previous home for these modules was in https://github.com/ansible/ansible -inside the folder `lib/ansible/modules/web_infrastructure/ansible_tower`. +The previous home for this collection was in https://github.com/ansible/ansible +inside the folder `lib/ansible/modules/web_infrastructure/ansible_tower` +as well as other places for the inventory plugin, module utils, and +doc fragment. ## Running -To use these modules, the "old" tower-cli needs to be installed -in the virtual environment where the modules run. +To use this collection, the "old" tower-cli needs to be installed +in the virtual environment where the collection runs. You can install it from either: - https://github.com/ansible/tower-cli/ - https://pypi.org/project/ansible-tower-cli/ -To use these modules in AWX, you should create a custom virtual environment -to install the requirement into. NOTE: you will also probably still need +To use this collection in AWX, you should create a custom virtual environment +to install the requirement into. NOTE: running locally, you will also need to set the job template extra_vars to include `ansible_python_interpreter` to be the python in that virtual environment. ## Running Tests -Tests to verify compatibility with the most recent AWX code exist +Tests to verify compatibility with the most recent AWX code are in `awx_modules/test/awx`. These tests require that python packages -are available for all of `awx`, `ansible`, `tower_cli`, and the modules -themselves. +are available for all of `awx`, `ansible`, `tower_cli`, and the collection +itself. -The target `make prepare_modules_venv` will prepare some requirements -in the `awx_modules_test_venv` folder so that `make test_modules` can +The target `make prepare_collection_venv` will prepare some requirements +in the `awx_collection_test_venv` folder so that `make test_collection` can be ran to actually run the tests. A single test can be ran via: ``` -make test_modules MODULE_TEST_DIRS=awx_modules/test/awx/test_organization.py +make test_collection MODULE_TEST_DIRS=awx_modules/test/awx/test_organization.py ``` ## Building -To build, you should not be in the AWX virtual environment. -This should work on any machine that has a sufficiently recent version -of Ansible installed. +The build target `make build_collection` will template out a `galaxy.yml` file +with automatic detection of the current AWX version. Then it builds the +collection with the `ansible-galaxy` CLI. -``` -cd awx_modules -ansible-galaxy build -``` +## Roadmap -This will leave a tar file in the awx_modules directory. +Major future development items on the agenda include: -This process may be amended in the future to template components of `galaxy.yml` -from values (such as version) taken from AWX. + - Removing tower-cli as a dependency + - Renaming the modules, for example `tower_organization` to just `organization` + and giving a deprecation period for the switch + +## Licensing + +All content in this folder is licensed under the same license as Ansible, +which is the same as license that applied before the split into an +independent collection. diff --git a/awx_modules/galaxy.yml b/awx_modules/galaxy.yml.j2 similarity index 83% rename from awx_modules/galaxy.yml rename to awx_modules/galaxy.yml.j2 index 257e9168d4..588d6438ba 100644 --- a/awx_modules/galaxy.yml +++ b/awx_modules/galaxy.yml.j2 @@ -8,9 +8,9 @@ homepage: https://ansible.com issues: https://github.com/ansible/awx/issues license: - GPL-3.0-only -name: awx -namespace: awx +name: {{ package_name }} +namespace: {{ namespace_name }} readme: README.md repository: https://github.com/ansible/awx tags: [] -version: 0.0.1 +version: {{ package_version }} diff --git a/awx_modules/template_galaxy.yml b/awx_modules/template_galaxy.yml new file mode 100644 index 0000000000..0064548c28 --- /dev/null +++ b/awx_modules/template_galaxy.yml @@ -0,0 +1,11 @@ +- hosts: localhost + gather_facts: false + connection: local + vars: + package_name: awx + namespace_name: awx + package_version: 0.0.1 + + tasks: + - name: Template the galaxy.yml file + template: src={{ playbook_dir }}/galaxy.yml.j2 dest={{ playbook_dir }}/galaxy.yml From 98619c5e230666585ced9f8176f37f6dce478f4d Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Tue, 17 Sep 2019 15:53:32 -0400 Subject: [PATCH 100/103] rename awx modules folder to collection --- {awx_modules => awx_collection}/COPYING | 0 {awx_modules => awx_collection}/README.md | 0 {awx_modules => awx_collection}/galaxy.yml.j2 | 0 {awx_modules => awx_collection}/plugins/inventory/tower.py | 0 .../plugins/module_utils/ansible_tower.py | 0 {awx_modules => awx_collection}/plugins/modules/__init__.py | 0 .../plugins/modules/tower_credential.py | 0 .../plugins/modules/tower_credential_type.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_group.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_host.py | 0 .../plugins/modules/tower_inventory.py | 0 .../plugins/modules/tower_inventory_source.py | 0 .../plugins/modules/tower_job_cancel.py | 0 .../plugins/modules/tower_job_launch.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_job_list.py | 0 .../plugins/modules/tower_job_template.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_job_wait.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_label.py | 0 .../plugins/modules/tower_notification.py | 0 .../plugins/modules/tower_organization.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_project.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_receive.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_role.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_send.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_settings.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_team.py | 0 {awx_modules => awx_collection}/plugins/modules/tower_user.py | 0 .../plugins/modules/tower_workflow_launch.py | 0 .../plugins/modules/tower_workflow_template.py | 0 {awx_modules => awx_collection}/setup.cfg | 0 {awx_modules => awx_collection}/template_galaxy.yml | 0 {awx_modules => awx_collection}/test/awx/conftest.py | 0 {awx_modules => awx_collection}/test/awx/test_job_template.py | 0 {awx_modules => awx_collection}/test/awx/test_organization.py | 0 34 files changed, 0 insertions(+), 0 deletions(-) rename {awx_modules => awx_collection}/COPYING (100%) rename {awx_modules => awx_collection}/README.md (100%) rename {awx_modules => awx_collection}/galaxy.yml.j2 (100%) rename {awx_modules => awx_collection}/plugins/inventory/tower.py (100%) rename {awx_modules => awx_collection}/plugins/module_utils/ansible_tower.py (100%) rename {awx_modules => awx_collection}/plugins/modules/__init__.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_credential.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_credential_type.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_group.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_host.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_inventory.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_inventory_source.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_job_cancel.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_job_launch.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_job_list.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_job_template.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_job_wait.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_label.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_notification.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_organization.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_project.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_receive.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_role.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_send.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_settings.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_team.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_user.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_workflow_launch.py (100%) rename {awx_modules => awx_collection}/plugins/modules/tower_workflow_template.py (100%) rename {awx_modules => awx_collection}/setup.cfg (100%) rename {awx_modules => awx_collection}/template_galaxy.yml (100%) rename {awx_modules => awx_collection}/test/awx/conftest.py (100%) rename {awx_modules => awx_collection}/test/awx/test_job_template.py (100%) rename {awx_modules => awx_collection}/test/awx/test_organization.py (100%) diff --git a/awx_modules/COPYING b/awx_collection/COPYING similarity index 100% rename from awx_modules/COPYING rename to awx_collection/COPYING diff --git a/awx_modules/README.md b/awx_collection/README.md similarity index 100% rename from awx_modules/README.md rename to awx_collection/README.md diff --git a/awx_modules/galaxy.yml.j2 b/awx_collection/galaxy.yml.j2 similarity index 100% rename from awx_modules/galaxy.yml.j2 rename to awx_collection/galaxy.yml.j2 diff --git a/awx_modules/plugins/inventory/tower.py b/awx_collection/plugins/inventory/tower.py similarity index 100% rename from awx_modules/plugins/inventory/tower.py rename to awx_collection/plugins/inventory/tower.py diff --git a/awx_modules/plugins/module_utils/ansible_tower.py b/awx_collection/plugins/module_utils/ansible_tower.py similarity index 100% rename from awx_modules/plugins/module_utils/ansible_tower.py rename to awx_collection/plugins/module_utils/ansible_tower.py diff --git a/awx_modules/plugins/modules/__init__.py b/awx_collection/plugins/modules/__init__.py similarity index 100% rename from awx_modules/plugins/modules/__init__.py rename to awx_collection/plugins/modules/__init__.py diff --git a/awx_modules/plugins/modules/tower_credential.py b/awx_collection/plugins/modules/tower_credential.py similarity index 100% rename from awx_modules/plugins/modules/tower_credential.py rename to awx_collection/plugins/modules/tower_credential.py diff --git a/awx_modules/plugins/modules/tower_credential_type.py b/awx_collection/plugins/modules/tower_credential_type.py similarity index 100% rename from awx_modules/plugins/modules/tower_credential_type.py rename to awx_collection/plugins/modules/tower_credential_type.py diff --git a/awx_modules/plugins/modules/tower_group.py b/awx_collection/plugins/modules/tower_group.py similarity index 100% rename from awx_modules/plugins/modules/tower_group.py rename to awx_collection/plugins/modules/tower_group.py diff --git a/awx_modules/plugins/modules/tower_host.py b/awx_collection/plugins/modules/tower_host.py similarity index 100% rename from awx_modules/plugins/modules/tower_host.py rename to awx_collection/plugins/modules/tower_host.py diff --git a/awx_modules/plugins/modules/tower_inventory.py b/awx_collection/plugins/modules/tower_inventory.py similarity index 100% rename from awx_modules/plugins/modules/tower_inventory.py rename to awx_collection/plugins/modules/tower_inventory.py diff --git a/awx_modules/plugins/modules/tower_inventory_source.py b/awx_collection/plugins/modules/tower_inventory_source.py similarity index 100% rename from awx_modules/plugins/modules/tower_inventory_source.py rename to awx_collection/plugins/modules/tower_inventory_source.py diff --git a/awx_modules/plugins/modules/tower_job_cancel.py b/awx_collection/plugins/modules/tower_job_cancel.py similarity index 100% rename from awx_modules/plugins/modules/tower_job_cancel.py rename to awx_collection/plugins/modules/tower_job_cancel.py diff --git a/awx_modules/plugins/modules/tower_job_launch.py b/awx_collection/plugins/modules/tower_job_launch.py similarity index 100% rename from awx_modules/plugins/modules/tower_job_launch.py rename to awx_collection/plugins/modules/tower_job_launch.py diff --git a/awx_modules/plugins/modules/tower_job_list.py b/awx_collection/plugins/modules/tower_job_list.py similarity index 100% rename from awx_modules/plugins/modules/tower_job_list.py rename to awx_collection/plugins/modules/tower_job_list.py diff --git a/awx_modules/plugins/modules/tower_job_template.py b/awx_collection/plugins/modules/tower_job_template.py similarity index 100% rename from awx_modules/plugins/modules/tower_job_template.py rename to awx_collection/plugins/modules/tower_job_template.py diff --git a/awx_modules/plugins/modules/tower_job_wait.py b/awx_collection/plugins/modules/tower_job_wait.py similarity index 100% rename from awx_modules/plugins/modules/tower_job_wait.py rename to awx_collection/plugins/modules/tower_job_wait.py diff --git a/awx_modules/plugins/modules/tower_label.py b/awx_collection/plugins/modules/tower_label.py similarity index 100% rename from awx_modules/plugins/modules/tower_label.py rename to awx_collection/plugins/modules/tower_label.py diff --git a/awx_modules/plugins/modules/tower_notification.py b/awx_collection/plugins/modules/tower_notification.py similarity index 100% rename from awx_modules/plugins/modules/tower_notification.py rename to awx_collection/plugins/modules/tower_notification.py diff --git a/awx_modules/plugins/modules/tower_organization.py b/awx_collection/plugins/modules/tower_organization.py similarity index 100% rename from awx_modules/plugins/modules/tower_organization.py rename to awx_collection/plugins/modules/tower_organization.py diff --git a/awx_modules/plugins/modules/tower_project.py b/awx_collection/plugins/modules/tower_project.py similarity index 100% rename from awx_modules/plugins/modules/tower_project.py rename to awx_collection/plugins/modules/tower_project.py diff --git a/awx_modules/plugins/modules/tower_receive.py b/awx_collection/plugins/modules/tower_receive.py similarity index 100% rename from awx_modules/plugins/modules/tower_receive.py rename to awx_collection/plugins/modules/tower_receive.py diff --git a/awx_modules/plugins/modules/tower_role.py b/awx_collection/plugins/modules/tower_role.py similarity index 100% rename from awx_modules/plugins/modules/tower_role.py rename to awx_collection/plugins/modules/tower_role.py diff --git a/awx_modules/plugins/modules/tower_send.py b/awx_collection/plugins/modules/tower_send.py similarity index 100% rename from awx_modules/plugins/modules/tower_send.py rename to awx_collection/plugins/modules/tower_send.py diff --git a/awx_modules/plugins/modules/tower_settings.py b/awx_collection/plugins/modules/tower_settings.py similarity index 100% rename from awx_modules/plugins/modules/tower_settings.py rename to awx_collection/plugins/modules/tower_settings.py diff --git a/awx_modules/plugins/modules/tower_team.py b/awx_collection/plugins/modules/tower_team.py similarity index 100% rename from awx_modules/plugins/modules/tower_team.py rename to awx_collection/plugins/modules/tower_team.py diff --git a/awx_modules/plugins/modules/tower_user.py b/awx_collection/plugins/modules/tower_user.py similarity index 100% rename from awx_modules/plugins/modules/tower_user.py rename to awx_collection/plugins/modules/tower_user.py diff --git a/awx_modules/plugins/modules/tower_workflow_launch.py b/awx_collection/plugins/modules/tower_workflow_launch.py similarity index 100% rename from awx_modules/plugins/modules/tower_workflow_launch.py rename to awx_collection/plugins/modules/tower_workflow_launch.py diff --git a/awx_modules/plugins/modules/tower_workflow_template.py b/awx_collection/plugins/modules/tower_workflow_template.py similarity index 100% rename from awx_modules/plugins/modules/tower_workflow_template.py rename to awx_collection/plugins/modules/tower_workflow_template.py diff --git a/awx_modules/setup.cfg b/awx_collection/setup.cfg similarity index 100% rename from awx_modules/setup.cfg rename to awx_collection/setup.cfg diff --git a/awx_modules/template_galaxy.yml b/awx_collection/template_galaxy.yml similarity index 100% rename from awx_modules/template_galaxy.yml rename to awx_collection/template_galaxy.yml diff --git a/awx_modules/test/awx/conftest.py b/awx_collection/test/awx/conftest.py similarity index 100% rename from awx_modules/test/awx/conftest.py rename to awx_collection/test/awx/conftest.py diff --git a/awx_modules/test/awx/test_job_template.py b/awx_collection/test/awx/test_job_template.py similarity index 100% rename from awx_modules/test/awx/test_job_template.py rename to awx_collection/test/awx/test_job_template.py diff --git a/awx_modules/test/awx/test_organization.py b/awx_collection/test/awx/test_organization.py similarity index 100% rename from awx_modules/test/awx/test_organization.py rename to awx_collection/test/awx/test_organization.py From 75bb7aae147ab933c88ba7af4cb60293a667b80c Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Tue, 17 Sep 2019 15:58:35 -0400 Subject: [PATCH 101/103] update references to collection folder --- .gitignore | 4 ++-- Makefile | 10 +++++----- awx_collection/README.md | 4 ++-- setup.cfg | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 51a1cbce30..085bd24776 100644 --- a/.gitignore +++ b/.gitignore @@ -137,5 +137,5 @@ use_dev_supervisor.txt # Ansible module tests awx_collection_test_venv/ -awx_modules/*.tar.gz -awx_modules/galaxy.yml +awx_collection/*.tar.gz +awx_collection/galaxy.yml diff --git a/Makefile b/Makefile index b493c51826..db38368173 100644 --- a/Makefile +++ b/Makefile @@ -384,7 +384,7 @@ prepare_collection_venv: ln -s /usr/lib/python2.7/site-packages/ansible $(COLLECTION_VENV)/ansible $(VENV_BASE)/awx/bin/pip install --target=$(COLLECTION_VENV) git+https://github.com/ansible/tower-cli.git -COLLECTION_TEST_DIRS ?= awx_modules/test/awx +COLLECTION_TEST_DIRS ?= awx_collection/test/awx COLLECTION_PACKAGE_NAME ?= awx COLLECTION_NAMESPACE_NAME ?= awx @@ -392,18 +392,18 @@ test_collection: @if [ "$(VENV_BASE)" ]; then \ . $(VENV_BASE)/awx/bin/activate; \ fi; \ - PYTHONPATH=$(COLLECTION_VENV):/awx_devel/awx_modules:$PYTHONPATH py.test $(COLLECTION_TEST_DIRS) + PYTHONPATH=$(COLLECTION_VENV):/awx_devel/awx_collection:$PYTHONPATH py.test $(COLLECTION_TEST_DIRS) flake8_collection: - flake8 awx_modules/ # Different settings, in main exclude list + flake8 awx_collection/ # Different settings, in main exclude list prepare_test_collection: prepare_collection_venv test_collection # deprecated test_collection_all: prepare_collection_venv test_collection flake8_collection build_collection: - ansible-playbook -i localhost, awx_modules/template_galaxy.yml -e package_name=$(COLLECTION_PACKAGE_NAME) -e namespace_name=$(COLLECTION_NAMESPACE_NAME) -e package_version=$(VERSION) - ansible-galaxy collection build awx_modules --output-path=awx_modules + ansible-playbook -i localhost, awx_collection/template_galaxy.yml -e package_name=$(COLLECTION_PACKAGE_NAME) -e namespace_name=$(COLLECTION_NAMESPACE_NAME) -e package_version=$(VERSION) + ansible-galaxy collection build awx_collection --output-path=awx_collection test_unit: @if [ "$(VENV_BASE)" ]; then \ diff --git a/awx_collection/README.md b/awx_collection/README.md index 25313673ff..eaa1b29980 100644 --- a/awx_collection/README.md +++ b/awx_collection/README.md @@ -25,7 +25,7 @@ to be the python in that virtual environment. ## Running Tests Tests to verify compatibility with the most recent AWX code are -in `awx_modules/test/awx`. These tests require that python packages +in `awx_collection/test/awx`. These tests require that python packages are available for all of `awx`, `ansible`, `tower_cli`, and the collection itself. @@ -34,7 +34,7 @@ in the `awx_collection_test_venv` folder so that `make test_collection` can be ran to actually run the tests. A single test can be ran via: ``` -make test_collection MODULE_TEST_DIRS=awx_modules/test/awx/test_organization.py +make test_collection MODULE_TEST_DIRS=awx_collection/test/awx/test_organization.py ``` ## Building diff --git a/setup.cfg b/setup.cfg index 227322dace..beb4521b99 100755 --- a/setup.cfg +++ b/setup.cfg @@ -18,4 +18,4 @@ exclude=.tox,venv,awx/lib/site-packages,awx/plugins/inventory/ec2.py,awx/plugins [flake8] max-line-length=160 ignore=E201,E203,E221,E225,E231,E241,E251,E261,E265,E303,W291,W391,W293,E731,W504 -exclude=.tox,venv,awx/lib/site-packages,awx/plugins/inventory,awx/ui,awx/api/urls.py,awx/main/migrations,awx/main/tests/data,node_modules/,awx/projects/,tools/docker,awx/settings/local_*.py,installer/openshift/settings.py,build/,installer/,awxkit/test,awx_modules/ +exclude=.tox,venv,awx/lib/site-packages,awx/plugins/inventory,awx/ui,awx/api/urls.py,awx/main/migrations,awx/main/tests/data,node_modules/,awx/projects/,tools/docker,awx/settings/local_*.py,installer/openshift/settings.py,build/,installer/,awxkit/test,awx_collection/ From 7dd8e35e8c8a231fd0b27cb3c36279694ac1a441 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Wed, 18 Sep 2019 08:43:36 -0400 Subject: [PATCH 102/103] Use namespaced doc fragment, cleanup doc fragment will now be at awx.awx.auth changed from just tower, which source from core remove Makefile things no longer needed --- Makefile | 4 -- awx_collection/README.md | 4 +- awx_collection/plugins/doc_fragments/auth.py | 46 +++++++++++++++++++ .../plugins/modules/tower_credential.py | 2 +- .../plugins/modules/tower_credential_type.py | 2 +- awx_collection/plugins/modules/tower_group.py | 2 +- awx_collection/plugins/modules/tower_host.py | 2 +- .../plugins/modules/tower_inventory.py | 2 +- .../plugins/modules/tower_inventory_source.py | 2 +- .../plugins/modules/tower_job_cancel.py | 2 +- .../plugins/modules/tower_job_launch.py | 2 +- .../plugins/modules/tower_job_list.py | 2 +- .../plugins/modules/tower_job_template.py | 2 +- .../plugins/modules/tower_job_wait.py | 2 +- awx_collection/plugins/modules/tower_label.py | 2 +- .../plugins/modules/tower_notification.py | 2 +- .../plugins/modules/tower_organization.py | 2 +- .../plugins/modules/tower_project.py | 2 +- .../plugins/modules/tower_receive.py | 2 +- awx_collection/plugins/modules/tower_role.py | 2 +- awx_collection/plugins/modules/tower_send.py | 2 +- .../plugins/modules/tower_settings.py | 2 +- awx_collection/plugins/modules/tower_team.py | 2 +- awx_collection/plugins/modules/tower_user.py | 2 +- .../plugins/modules/tower_workflow_launch.py | 2 +- .../modules/tower_workflow_template.py | 2 +- awx_collection/template_galaxy.yml | 17 +++++++ 27 files changed, 88 insertions(+), 29 deletions(-) create mode 100644 awx_collection/plugins/doc_fragments/auth.py diff --git a/Makefile b/Makefile index db38368173..c0ada60b61 100644 --- a/Makefile +++ b/Makefile @@ -374,11 +374,9 @@ test: fi; \ PYTHONDONTWRITEBYTECODE=1 py.test -p no:cacheprovider -n auto $(TEST_DIRS) cd awxkit && $(VENV_BASE)/awx/bin/tox -re py2,py3 - make test_collection_all awx-manage check_migrations --dry-run --check -n 'vNNN_missing_migration_file' prepare_collection_venv: - cd /awx_devel rm -rf $(COLLECTION_VENV) mkdir $(COLLECTION_VENV) ln -s /usr/lib/python2.7/site-packages/ansible $(COLLECTION_VENV)/ansible @@ -397,8 +395,6 @@ test_collection: flake8_collection: flake8 awx_collection/ # Different settings, in main exclude list -prepare_test_collection: prepare_collection_venv test_collection # deprecated - test_collection_all: prepare_collection_venv test_collection flake8_collection build_collection: diff --git a/awx_collection/README.md b/awx_collection/README.md index eaa1b29980..fe65d0d013 100644 --- a/awx_collection/README.md +++ b/awx_collection/README.md @@ -1,11 +1,11 @@ # AWX Ansible Collection -This Ansible collection allow for easy interaction with an AWX or Ansible Tower +This Ansible collection allows for easy interaction with an AWX or Ansible Tower server in Ansible playbooks. The previous home for this collection was in https://github.com/ansible/ansible inside the folder `lib/ansible/modules/web_infrastructure/ansible_tower` -as well as other places for the inventory plugin, module utils, and +as well as other folders for the inventory plugin, module utils, and doc fragment. ## Running diff --git a/awx_collection/plugins/doc_fragments/auth.py b/awx_collection/plugins/doc_fragments/auth.py new file mode 100644 index 0000000000..5583710201 --- /dev/null +++ b/awx_collection/plugins/doc_fragments/auth.py @@ -0,0 +1,46 @@ +# -*- coding: utf-8 -*- + +# Copyright: (c) 2017, Wayne Witzel III +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) + + +class ModuleDocFragment(object): + + # Ansible Tower documentation fragment + DOCUMENTATION = r''' +options: + tower_host: + description: + - URL to your Tower or AWX instance. + type: str + tower_username: + description: + - Username for your Tower or AWX instance. + type: str + tower_password: + description: + - Password for your Tower or AWX instance. + type: str + validate_certs: + description: + - Whether to allow insecure connections to Tower or AWX. + - If C(no), SSL certificates will not be validated. + - This should only be used on personally controlled sites using self-signed certificates. + type: bool + aliases: [ tower_verify_ssl ] + tower_config_file: + description: + - Path to the Tower or AWX config file. + type: path + +requirements: +- ansible-tower-cli >= 3.0.2 + +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 +''' diff --git a/awx_collection/plugins/modules/tower_credential.py b/awx_collection/plugins/modules/tower_credential.py index aac3d9406a..7ac08b28d6 100644 --- a/awx_collection/plugins/modules/tower_credential.py +++ b/awx_collection/plugins/modules/tower_credential.py @@ -145,7 +145,7 @@ options: choices: ["present", "absent"] default: "present" type: str -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_credential_type.py b/awx_collection/plugins/modules/tower_credential_type.py index d8b97ccc08..0fd6ebd046 100644 --- a/awx_collection/plugins/modules/tower_credential_type.py +++ b/awx_collection/plugins/modules/tower_credential_type.py @@ -64,7 +64,7 @@ options: required: False type: bool aliases: [ tower_verify_ssl ] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_group.py b/awx_collection/plugins/modules/tower_group.py index 8df1a73221..7fe717666a 100644 --- a/awx_collection/plugins/modules/tower_group.py +++ b/awx_collection/plugins/modules/tower_group.py @@ -77,7 +77,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_host.py b/awx_collection/plugins/modules/tower_host.py index c6011ab27b..02946cf4d7 100644 --- a/awx_collection/plugins/modules/tower_host.py +++ b/awx_collection/plugins/modules/tower_host.py @@ -47,7 +47,7 @@ options: - Desired state of the resource. choices: ["present", "absent"] default: "present" -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_inventory.py b/awx_collection/plugins/modules/tower_inventory.py index 20eaa19b0f..811430a723 100644 --- a/awx_collection/plugins/modules/tower_inventory.py +++ b/awx_collection/plugins/modules/tower_inventory.py @@ -52,7 +52,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_inventory_source.py b/awx_collection/plugins/modules/tower_inventory_source.py index 063eeeea81..ede0896d64 100644 --- a/awx_collection/plugins/modules/tower_inventory_source.py +++ b/awx_collection/plugins/modules/tower_inventory_source.py @@ -143,7 +143,7 @@ options: - Tower option to avoid certificates check. type: bool aliases: [ tower_verify_ssl ] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_job_cancel.py b/awx_collection/plugins/modules/tower_job_cancel.py index 1a658f02f5..f7a80b9f71 100644 --- a/awx_collection/plugins/modules/tower_job_cancel.py +++ b/awx_collection/plugins/modules/tower_job_cancel.py @@ -32,7 +32,7 @@ options: - Fail loudly if the I(job_id) does not reference a running job. default: False type: bool -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' EXAMPLES = ''' diff --git a/awx_collection/plugins/modules/tower_job_launch.py b/awx_collection/plugins/modules/tower_job_launch.py index e790603ec9..792632fbb4 100644 --- a/awx_collection/plugins/modules/tower_job_launch.py +++ b/awx_collection/plugins/modules/tower_job_launch.py @@ -54,7 +54,7 @@ options: - Disable launching jobs from job template. type: bool default: 'no' -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' EXAMPLES = ''' diff --git a/awx_collection/plugins/modules/tower_job_list.py b/awx_collection/plugins/modules/tower_job_list.py index e89589b498..ef8d8b3b15 100644 --- a/awx_collection/plugins/modules/tower_job_list.py +++ b/awx_collection/plugins/modules/tower_job_list.py @@ -38,7 +38,7 @@ options: query: description: - Query used to further filter the list of jobs. C({"foo":"bar"}) will be passed at C(?foo=bar) -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_job_template.py b/awx_collection/plugins/modules/tower_job_template.py index f1ee9e5775..2600e8884e 100644 --- a/awx_collection/plugins/modules/tower_job_template.py +++ b/awx_collection/plugins/modules/tower_job_template.py @@ -176,7 +176,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth notes: - JSON for survey_spec can be found in Tower API Documentation. See U(https://docs.ansible.com/ansible-tower/latest/html/towerapi/api_ref.html#/Job_Templates/Job_Templates_job_templates_survey_spec_create) diff --git a/awx_collection/plugins/modules/tower_job_wait.py b/awx_collection/plugins/modules/tower_job_wait.py index bc6aa89b3f..0f0ab806db 100644 --- a/awx_collection/plugins/modules/tower_job_wait.py +++ b/awx_collection/plugins/modules/tower_job_wait.py @@ -38,7 +38,7 @@ options: timeout: description: - Maximum time in seconds to wait for a job to finish. -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' EXAMPLES = ''' diff --git a/awx_collection/plugins/modules/tower_label.py b/awx_collection/plugins/modules/tower_label.py index b29a001a02..09b3b4b6dd 100644 --- a/awx_collection/plugins/modules/tower_label.py +++ b/awx_collection/plugins/modules/tower_label.py @@ -36,7 +36,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_notification.py b/awx_collection/plugins/modules/tower_notification.py index 96833ce1dd..eee30a8cd4 100644 --- a/awx_collection/plugins/modules/tower_notification.py +++ b/awx_collection/plugins/modules/tower_notification.py @@ -164,7 +164,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_organization.py b/awx_collection/plugins/modules/tower_organization.py index d38d47b8b3..7f261e2f1c 100644 --- a/awx_collection/plugins/modules/tower_organization.py +++ b/awx_collection/plugins/modules/tower_organization.py @@ -35,7 +35,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_project.py b/awx_collection/plugins/modules/tower_project.py index 9216eb59f3..423f63bb7f 100644 --- a/awx_collection/plugins/modules/tower_project.py +++ b/awx_collection/plugins/modules/tower_project.py @@ -85,7 +85,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_receive.py b/awx_collection/plugins/modules/tower_receive.py index 6c61d927d7..66d45da58f 100644 --- a/awx_collection/plugins/modules/tower_receive.py +++ b/awx_collection/plugins/modules/tower_receive.py @@ -79,7 +79,7 @@ requirements: notes: - Specifying a name of "all" for any asset type will export all items of that asset type. -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' EXAMPLES = ''' diff --git a/awx_collection/plugins/modules/tower_role.py b/awx_collection/plugins/modules/tower_role.py index 92b806e8f2..9352827d8b 100644 --- a/awx_collection/plugins/modules/tower_role.py +++ b/awx_collection/plugins/modules/tower_role.py @@ -58,7 +58,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_send.py b/awx_collection/plugins/modules/tower_send.py index 3cd46ff613..eaa5b9d69f 100644 --- a/awx_collection/plugins/modules/tower_send.py +++ b/awx_collection/plugins/modules/tower_send.py @@ -54,7 +54,7 @@ requirements: - six.moves.StringIO - sys -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' EXAMPLES = ''' diff --git a/awx_collection/plugins/modules/tower_settings.py b/awx_collection/plugins/modules/tower_settings.py index c429463450..8de8c2e6f9 100644 --- a/awx_collection/plugins/modules/tower_settings.py +++ b/awx_collection/plugins/modules/tower_settings.py @@ -31,7 +31,7 @@ options: description: - Value to be modified for given setting. required: True -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' RETURN = ''' # ''' diff --git a/awx_collection/plugins/modules/tower_team.py b/awx_collection/plugins/modules/tower_team.py index 554e730382..165f801b20 100644 --- a/awx_collection/plugins/modules/tower_team.py +++ b/awx_collection/plugins/modules/tower_team.py @@ -36,7 +36,7 @@ options: - Desired state of the resource. choices: ["present", "absent"] default: "present" -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_user.py b/awx_collection/plugins/modules/tower_user.py index e361412eb3..a5fea6d861 100644 --- a/awx_collection/plugins/modules/tower_user.py +++ b/awx_collection/plugins/modules/tower_user.py @@ -59,7 +59,7 @@ options: requirements: - ansible-tower-cli >= 3.2.0 -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/plugins/modules/tower_workflow_launch.py b/awx_collection/plugins/modules/tower_workflow_launch.py index 8df65e8919..8e0c06d33c 100644 --- a/awx_collection/plugins/modules/tower_workflow_launch.py +++ b/awx_collection/plugins/modules/tower_workflow_launch.py @@ -41,7 +41,7 @@ options: requirements: - "python >= 2.6" -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' RETURN = ''' diff --git a/awx_collection/plugins/modules/tower_workflow_template.py b/awx_collection/plugins/modules/tower_workflow_template.py index b3fc6e14d3..3805079d01 100644 --- a/awx_collection/plugins/modules/tower_workflow_template.py +++ b/awx_collection/plugins/modules/tower_workflow_template.py @@ -73,7 +73,7 @@ options: - Desired state of the resource. default: "present" choices: ["present", "absent"] -extends_documentation_fragment: tower +extends_documentation_fragment: awx.awx.auth ''' diff --git a/awx_collection/template_galaxy.yml b/awx_collection/template_galaxy.yml index 0064548c28..e7f57d1074 100644 --- a/awx_collection/template_galaxy.yml +++ b/awx_collection/template_galaxy.yml @@ -7,5 +7,22 @@ package_version: 0.0.1 tasks: + - name: Do file content replacements for non-default namespace or package name + block: + - name: Find all module files + find: + paths: "{{ playbook_dir }}/plugins/modules" + patterns: "*.py" + register: module_files + + - name: Change files to support desired namespace and package names + replace: + path: "{{ item.path }}" + regexp: '^extends_documentation_fragment: awx.awx.auth$' + replace: 'extends_documentation_fragment: {{ namespace_name }}.{{ package_name }}.auth' + with_items: "{{ module_files.files }}" + when: + - (package_name != 'awx') or (namespace_name != 'awx') + - name: Template the galaxy.yml file template: src={{ playbook_dir }}/galaxy.yml.j2 dest={{ playbook_dir }}/galaxy.yml From db0bd471c3dea0c620e80a235d8c9cf9013f8830 Mon Sep 17 00:00:00 2001 From: AlanCoding Date: Tue, 1 Oct 2019 13:45:07 -0400 Subject: [PATCH 103/103] rename playbook vars to have collection_ --- Makefile | 6 +++--- awx_collection/galaxy.yml.j2 | 6 +++--- awx_collection/template_galaxy.yml | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index c0ada60b61..981dea2484 100644 --- a/Makefile +++ b/Makefile @@ -383,8 +383,8 @@ prepare_collection_venv: $(VENV_BASE)/awx/bin/pip install --target=$(COLLECTION_VENV) git+https://github.com/ansible/tower-cli.git COLLECTION_TEST_DIRS ?= awx_collection/test/awx -COLLECTION_PACKAGE_NAME ?= awx -COLLECTION_NAMESPACE_NAME ?= awx +COLLECTION_PACKAGE ?= awx +COLLECTION_NAMESPACE ?= awx test_collection: @if [ "$(VENV_BASE)" ]; then \ @@ -398,7 +398,7 @@ flake8_collection: test_collection_all: prepare_collection_venv test_collection flake8_collection build_collection: - ansible-playbook -i localhost, awx_collection/template_galaxy.yml -e package_name=$(COLLECTION_PACKAGE_NAME) -e namespace_name=$(COLLECTION_NAMESPACE_NAME) -e package_version=$(VERSION) + ansible-playbook -i localhost, awx_collection/template_galaxy.yml -e collection_package=$(COLLECTION_PACKAGE) -e namespace_name=$(COLLECTION_NAMESPACE) -e package_version=$(VERSION) ansible-galaxy collection build awx_collection --output-path=awx_collection test_unit: diff --git a/awx_collection/galaxy.yml.j2 b/awx_collection/galaxy.yml.j2 index 588d6438ba..c573edc709 100644 --- a/awx_collection/galaxy.yml.j2 +++ b/awx_collection/galaxy.yml.j2 @@ -8,9 +8,9 @@ homepage: https://ansible.com issues: https://github.com/ansible/awx/issues license: - GPL-3.0-only -name: {{ package_name }} -namespace: {{ namespace_name }} +name: {{ collection_package }} +namespace: {{ collection_namespace }} readme: README.md repository: https://github.com/ansible/awx tags: [] -version: {{ package_version }} +version: {{ collection_version }} diff --git a/awx_collection/template_galaxy.yml b/awx_collection/template_galaxy.yml index e7f57d1074..bfbea58bf7 100644 --- a/awx_collection/template_galaxy.yml +++ b/awx_collection/template_galaxy.yml @@ -2,9 +2,9 @@ gather_facts: false connection: local vars: - package_name: awx - namespace_name: awx - package_version: 0.0.1 + collection_package: awx + collection_namespace: awx + collection_version: 0.0.1 # not for updating, pass in extra_vars tasks: - name: Do file content replacements for non-default namespace or package name @@ -19,10 +19,10 @@ replace: path: "{{ item.path }}" regexp: '^extends_documentation_fragment: awx.awx.auth$' - replace: 'extends_documentation_fragment: {{ namespace_name }}.{{ package_name }}.auth' + replace: 'extends_documentation_fragment: {{ collection_namespace }}.{{ collection_package }}.auth' with_items: "{{ module_files.files }}" when: - - (package_name != 'awx') or (namespace_name != 'awx') + - (collection_package != 'awx') or (collection_namespace != 'awx') - name: Template the galaxy.yml file template: src={{ playbook_dir }}/galaxy.yml.j2 dest={{ playbook_dir }}/galaxy.yml