mirror of
https://github.com/ansible/awx.git
synced 2026-01-23 15:38:06 -03:30
Merge pull request #9980 from fosterseth/fix_t4958_rename_collection
Rename awx_collection modules
This commit is contained in:
commit
3063073395
@ -8,7 +8,7 @@ short_description: gather all maintenance plan playbooks for an insights account
|
||||
description:
|
||||
- Supply insights Credentials to download all playbooks for all maintenance plans.
|
||||
The totality of the plans are versioned based on the http ETag response.
|
||||
version_added: "2.3"
|
||||
version_added: "2.3.0"
|
||||
options:
|
||||
insights_url:
|
||||
description:
|
||||
|
||||
@ -9,7 +9,7 @@ description:
|
||||
- Unpacks an archive that contains a project, in order to support handling versioned
|
||||
artifacts from (for example) GitHub Releases or Artifactory builds.
|
||||
- Handles projects in the archive root, or in a single base directory of the archive.
|
||||
version_added: "2.9"
|
||||
version_added: "2.9.0"
|
||||
options:
|
||||
src:
|
||||
description:
|
||||
|
||||
@ -71,9 +71,8 @@ Notable releases of the `awx.awx` collection:
|
||||
|
||||
The following notes are changes that may require changes to playbooks:
|
||||
|
||||
- The module tower_notification was renamed tower_notification_template. In ansible >= 2.10 there is a seemless redirect. Ansible 2.9 does not respect the redirect.
|
||||
- When a project is created, it will wait for the update/sync to finish by default; this can be turned off with the `wait` parameter, if desired.
|
||||
- When using the wait parameter with project update, if the project did not undergo a revision update, the result will be
|
||||
'not changed'
|
||||
- Creating a "scan" type job template is no longer supported.
|
||||
- Specifying a custom certificate via the `TOWER_CERTIFICATE` environment variable no longer works.
|
||||
- Type changes of variable fields:
|
||||
@ -118,7 +117,7 @@ py.test awx_collection/test/awx/
|
||||
|
||||
## Running Integration Tests
|
||||
|
||||
The integration tests require a virtualenv with `ansible` >= 2.9 and `tower_cli`.
|
||||
The integration tests require a virtualenv with `ansible` >= 2.9 and `awxkit`.
|
||||
The collection must first be installed, which can be done using `make install_collection`.
|
||||
You also need a configuration file, as described in the running section.
|
||||
|
||||
|
||||
@ -7,12 +7,13 @@ When trying to fix a bug, it is best to replicate its behavior within a test wit
|
||||
|
||||
## Unit Tests
|
||||
|
||||
The unit tests are stored in the `test/awx` directory and, where possible, test interactions between the collections modules and the AWX database. This is achieved by using a Python testing suite and having a mocked layer which emulates interactions with the Tower API. You do not need a server to run these unit tests. The depth of testing is not fixed and can change from module to module.
|
||||
The unit tests are stored in the `test/awx` directory and, where possible, test interactions between the collections modules and the AWX database. This is achieved by using a Python testing suite and having a mocked layer which emulates interactions with the API. You do not need a server to run these unit tests. The depth of testing is not fixed and can change from module to module.
|
||||
|
||||
Let's take a closer look at the `test_token.py` file (which tests the `tower_token` module):
|
||||
Let's take a closer look at the `test_token.py` file (which tests the `token` module):
|
||||
|
||||
```
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
import pytest
|
||||
@ -27,15 +28,15 @@ def test_create_token(run_module, admin_user):
|
||||
'description': 'barfoo',
|
||||
'state': 'present',
|
||||
'scope': 'read',
|
||||
'tower_host': None,
|
||||
'tower_username': None,
|
||||
'tower_password': None,
|
||||
'controller_host': None,
|
||||
'controller_username': None,
|
||||
'controller_password': None,
|
||||
'validate_certs': None,
|
||||
'tower_oauthtoken': None,
|
||||
'tower_config_file': None,
|
||||
'controller_oauthtoken': None,
|
||||
'controller_config_file': None,
|
||||
}
|
||||
|
||||
result = run_module('tower_token', module_args, admin_user)
|
||||
result = run_module('token', module_args, admin_user)
|
||||
assert result.get('changed'), result
|
||||
|
||||
tokens = OAuth2AccessToken.objects.filter(description='barfoo')
|
||||
@ -43,7 +44,7 @@ def test_create_token(run_module, admin_user):
|
||||
assert tokens[0].scope == 'read', 'Token was not given read access'
|
||||
```
|
||||
|
||||
This test has a single test called `test_create_token`. It creates a `module_args` section which is what will be passed into our module. We then call `run_module`, asking it to run the `tower_token` module with the `module_args` we created and give us back the results. After that, we run an assertion to validate that our module did in fact report a change to the system. We will then use Python objects to look up the token that has a description of `barfoo` (which was in our arguments to the module). We want to validate that we only got back one token (the one we created) and that the scope of the token we created was read.
|
||||
This test has a single test called `test_create_token`. It creates a `module_args` section which is what will be passed into our module. We then call `run_module`, asking it to run the `token` module with the `module_args` we created and give us back the results. After that, we run an assertion to validate that our module did in fact report a change to the system. We will then use Python objects to look up the token that has a description of `barfoo` (which was in our arguments to the module). We want to validate that we only got back one token (the one we created) and that the scope of the token we created was read.
|
||||
|
||||
|
||||
### Completion Test
|
||||
@ -70,7 +71,7 @@ Inside the `/tests` directory, there are two folders:
|
||||
|
||||
In the `/sanity` folder are file directives for specific Ansible versions which contain information about which tests to skip for specific files. There are a number of reasons you may need to skip a sanity test. See the [`ansible-test` documentation](https://docs.ansible.com/ansible/latest/dev_guide/testing_running_locally.html) for more details about how and why you might want to skip a test.
|
||||
|
||||
In the `integration/targets` folder you will see directories (which act as roles) for all of the different modules and plugins. When the collection is tested, an instance of Ansible Tower (or AWX) will be spun up and these roles will be applied to the target server to validate the functionality of the modules. Since these are really roles, each directory will contain a tasks folder under it with a `main.yml` file as an entry point.
|
||||
In the `integration/targets` folder you will see directories (which act as roles) for all of the different modules and plugins. When the collection is tested, an instance of Automation Platform Controller (or AWX) will be spun up and these roles will be applied to the target server to validate the functionality of the modules. Since these are really roles, each directory will contain a tasks folder under it with a `main.yml` file as an entry point.
|
||||
|
||||
While not strictly followed, the general flow of a test should be:
|
||||
|
||||
@ -87,17 +88,17 @@ While not strictly followed, the general flow of a test should be:
|
||||
```
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
group_name1: "AWX-Collection-tests-tower_instance_group-group1-{{ test_id }}"
|
||||
group_name2: "AWX-Collection-tests-tower_instance_group-group2-{{ test_id }}"
|
||||
cred_name1: "AWX-Collection-tests-tower_instance_group-cred1-{{ test_id }}"
|
||||
group_name1: "AWX-Collection-tests-instance_group-group1-{{ test_id }}"
|
||||
group_name2: "AWX-Collection-tests-instance_group-group2-{{ test_id }}"
|
||||
cred_name1: "AWX-Collection-tests-instance_group-cred1-{{ test_id }}"
|
||||
```
|
||||
|
||||
- **Non-creating tests (i.e. test for specific error conditions, etc), with assertion**
|
||||
|
||||
```
|
||||
- name: Try to use a token as a dict which is missing the token parameter
|
||||
tower_job_list:
|
||||
tower_oauthtoken:
|
||||
job_list:
|
||||
controller_oauthtoken:
|
||||
not_token: "This has no token entry"
|
||||
register: results
|
||||
ignore_errors: true
|
||||
@ -105,14 +106,14 @@ While not strictly followed, the general flow of a test should be:
|
||||
- assert:
|
||||
that:
|
||||
- results is failed
|
||||
- '"The provided dict in tower_oauthtoken did not properly contain the token entry" == results.msg'
|
||||
- '"The provided dict in controller_oauthtoken did not properly contain the token entry" == results.msg'
|
||||
```
|
||||
|
||||
- **`Block:`**
|
||||
- Run test which creates/modifies/deletes object(s)
|
||||
```
|
||||
- name: Create a container group
|
||||
tower_instance_group:
|
||||
instance_group:
|
||||
name: "{{ group_name2 }}"
|
||||
credential: "{{ cred_result.id }}"
|
||||
register: result
|
||||
@ -128,14 +129,14 @@ While not strictly followed, the general flow of a test should be:
|
||||
- Cleanup created objects
|
||||
```
|
||||
- name: Delete the credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ cred_name1 }}"
|
||||
organization: "Default"
|
||||
credential_type: "OpenShift or Kubernetes API Bearer Token"
|
||||
```
|
||||
- Assert cleanup worked properly (if needed)
|
||||
|
||||
When writing an integration test, a test of asset type A does not need to make assertions for asset type B. For example, if you are writing an integration test for a credential and you create a custom credential type, you do not need to assert that the `tower_credential_type` call properly worked, you can assume it will. In addition, when cleaning up and deleting the `tower_credential_type`, you do not need to assert that it properly deleted the credential type.
|
||||
When writing an integration test, a test of asset type A does not need to make assertions for asset type B. For example, if you are writing an integration test for a credential and you create a custom credential type, you do not need to assert that the `credential_type` call properly worked, you can assume it will. In addition, when cleaning up and deleting the `credential_type`, you do not need to assert that it properly deleted the credential type.
|
||||
|
||||
|
||||
## Running Unit Tests
|
||||
@ -176,7 +177,7 @@ FAILED awx_collection/test/awx/test_module_utils.py::test_type_warning - SystemE
|
||||
make: *** [Makefile:382: test_collection] Error 1
|
||||
```
|
||||
|
||||
In addition to running all of the tests, you can also specify specific tests to run. This is useful when developing a single module. In this example, we will run the tests for the `tower_token` module:
|
||||
In addition to running all of the tests, you can also specify specific tests to run. This is useful when developing a single module. In this example, we will run the tests for the `token` module:
|
||||
|
||||
```
|
||||
$ pytest awx_collection/test/awx/test_token.py
|
||||
@ -195,7 +196,7 @@ awx_collection/test/awx/test_token.py . [100%]
|
||||
|
||||
## Running Integration Tests
|
||||
|
||||
For integration tests, you will need an existing AWX or Ansible Tower instance to run the test playbooks against. You can write a simple `run_it.yml` playbook to invoke the main method:
|
||||
For integration tests, you will need an existing AWX or Automation Platform Controller instance to run the test playbooks against. You can write a simple `run_it.yml` playbook to invoke the main method:
|
||||
|
||||
```
|
||||
---
|
||||
@ -215,7 +216,7 @@ For integration tests, you will need an existing AWX or Ansible Tower instance t
|
||||
- include_tasks: main.yml
|
||||
```
|
||||
|
||||
Place this file in the `/tasks` directory of the test playbook you'd like to run (i.e., `awx/awx_collection/tests/integration/targets/tower_ad_hoc_command_cancel/tasks/`; a test playbook named `main.yml` must be in the same directory).
|
||||
Place this file in the `/tasks` directory of the test playbook you'd like to run (i.e., `awx/awx_collection/tests/integration/targets/ad_hoc_command_cancel/tasks/`; a test playbook named `main.yml` must be in the same directory).
|
||||
|
||||
The `run_it.yml` playbook will set up your connection parameters via environment variables and then invoke the `main.yml` play of the role.
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
authors:
|
||||
- AWX Project Contributors <awx-project@googlegroups.com>
|
||||
dependencies: {}
|
||||
description: Ansible content that interacts with the AWX or Ansible Tower API.
|
||||
description: Ansible content that interacts with the AWX or Automation Platform Controller API.
|
||||
documentation: https://github.com/ansible/awx/blob/devel/awx_collection/README.md
|
||||
homepage: https://www.ansible.com/
|
||||
issues: https://github.com/ansible/awx/issues?q=is%3Aissue+label%3Acomponent%3Aawx_collection
|
||||
|
||||
@ -1,46 +1,207 @@
|
||||
---
|
||||
action_groups:
|
||||
tower:
|
||||
- tower_credential_input_source
|
||||
- tower_credential
|
||||
- tower_credential_type
|
||||
- tower_group
|
||||
- tower_host
|
||||
- tower_inventory
|
||||
- tower_inventory_source
|
||||
- tower_job_cancel
|
||||
- tower_job_launch
|
||||
- tower_job_list
|
||||
- tower_job_template
|
||||
- tower_job_wait
|
||||
- tower_label
|
||||
- tower_license
|
||||
- tower_notification
|
||||
- tower_organization
|
||||
- tower_project
|
||||
- tower_role
|
||||
- tower_schedule
|
||||
- tower_settings
|
||||
- tower_team
|
||||
- tower_token
|
||||
- tower_user
|
||||
- tower_workflow_job_template_node
|
||||
- tower_workflow_job_template
|
||||
- tower_workflow_launch
|
||||
|
||||
controller:
|
||||
- credential_input_source
|
||||
- credential
|
||||
- credential_type
|
||||
- group
|
||||
- host
|
||||
- inventory
|
||||
- inventory_source
|
||||
- job_cancel
|
||||
- job_launch
|
||||
- job_list
|
||||
- job_template
|
||||
- job_wait
|
||||
- label
|
||||
- license
|
||||
- notification
|
||||
- organization
|
||||
- project
|
||||
- role
|
||||
- schedule
|
||||
- settings
|
||||
- team
|
||||
- token
|
||||
- user
|
||||
- workflow_job_template_node
|
||||
- workflow_job_template
|
||||
- workflow_launch
|
||||
plugin_routing:
|
||||
inventory:
|
||||
tower:
|
||||
redirect: awx.awx.controller
|
||||
awx.awx.tower:
|
||||
redirect: awx.awx.controller
|
||||
lookup:
|
||||
tower_api:
|
||||
redirect: awx.awx.controller_api
|
||||
tower_schedule_rrule:
|
||||
redirect: awx.awx.schedule_rrule
|
||||
awx.awx.tower_api:
|
||||
redirect: awx.awx.controller_api
|
||||
awx.awx.tower_schedule_rrule:
|
||||
redirect: awx.awx.tower_schedule_rrule
|
||||
modules:
|
||||
tower_receive:
|
||||
deprecation:
|
||||
removal_date: TBD
|
||||
warning_text: see plugin documentation for details
|
||||
tower_send:
|
||||
deprecation:
|
||||
removal_date: TBD
|
||||
warning_text: see plugin documentation for details
|
||||
tower_workflow_template:
|
||||
deprecation:
|
||||
removal_date: TBD
|
||||
warning_text: see plugin documentation for details
|
||||
# if playbook does not specify a FQCN
|
||||
tower_ad_hoc_command_cancel:
|
||||
redirect: awx.awx.ad_hoc_command_cancel
|
||||
tower_ad_hoc_command_wait:
|
||||
redirect: awx.awx.ad_hoc_command_wait
|
||||
tower_ad_hoc_command:
|
||||
redirect: awx.awx.ad_hoc_command
|
||||
tower_application:
|
||||
redirect: awx.awx.application
|
||||
tower_meta:
|
||||
redirect: awx.awx.controller_meta
|
||||
tower_credential_input_source:
|
||||
redirect: awx.awx.credential_input_source
|
||||
tower_credential_type:
|
||||
redirect: awx.awx.credential_type
|
||||
tower_credential:
|
||||
redirect: awx.awx.credential
|
||||
tower_execution_environment:
|
||||
redirect: awx.awx.execution_environment
|
||||
tower_export:
|
||||
redirect: awx.awx.export
|
||||
tower_group:
|
||||
redirect: awx.awx.group
|
||||
tower_host:
|
||||
redirect: awx.awx.host
|
||||
tower_import:
|
||||
redirect: awx.awx.import
|
||||
tower_instance_group:
|
||||
redirect: awx.awx.instance_group
|
||||
tower_inventory_source_update:
|
||||
redirect: awx.awx.inventory_source_update
|
||||
tower_inventory_source:
|
||||
redirect: awx.awx.inventory_source
|
||||
tower_inventory:
|
||||
redirect: awx.awx.inventory
|
||||
tower_job_cancel:
|
||||
redirect: awx.awx.job_cancel
|
||||
tower_job_launch:
|
||||
redirect: awx.awx.job_launch
|
||||
tower_job_list:
|
||||
redirect: awx.awx.job_list
|
||||
tower_job_template:
|
||||
redirect: awx.awx.job_template
|
||||
tower_job_wait:
|
||||
redirect: awx.awx.job_wait
|
||||
tower_label:
|
||||
redirect: awx.awx.label
|
||||
tower_license:
|
||||
redirect: awx.awx.license
|
||||
tower_notification_template:
|
||||
redirect: awx.awx.notification_template
|
||||
tower_notification:
|
||||
redirect: tower_notification_template
|
||||
redirect: awx.awx.notification_template
|
||||
tower_organization:
|
||||
redirect: awx.awx.organization
|
||||
tower_project_update:
|
||||
redirect: awx.awx.project_update
|
||||
tower_project:
|
||||
redirect: awx.awx.project
|
||||
tower_role:
|
||||
redirect: awx.awx.role
|
||||
tower_schedule:
|
||||
redirect: awx.awx.schedule
|
||||
tower_settings:
|
||||
redirect: awx.awx.settings
|
||||
tower_team:
|
||||
redirect: awx.awx.team
|
||||
tower_token:
|
||||
redirect: awx.awx.token
|
||||
tower_user:
|
||||
redirect: awx.awx.user
|
||||
tower_workflow_approval:
|
||||
redirect: awx.awx.workflow_approval
|
||||
tower_workflow_job_template_node:
|
||||
redirect: awx.awx.workflow_job_template_node
|
||||
tower_workflow_job_template:
|
||||
redirect: awx.awx.workflow_job_template
|
||||
tower_workflow_launch:
|
||||
redirect: awx.awx.workflow_launch
|
||||
tower_workflow_node_wait:
|
||||
redirect: awx.awx.workflow_node_wait
|
||||
# if playbook specifies a FQCN
|
||||
awx.awx.tower_ad_hoc_command_cancel:
|
||||
redirect: awx.awx.ad_hoc_command_cancel
|
||||
awx.awx.tower_ad_hoc_command_wait:
|
||||
redirect: awx.awx.ad_hoc_command_wait
|
||||
awx.awx.tower_ad_hoc_command:
|
||||
redirect: awx.awx.ad_hoc_command
|
||||
awx.awx.tower_application:
|
||||
redirect: awx.awx.application
|
||||
awx.awx.tower_meta:
|
||||
redirect: awx.awx.controller_meta
|
||||
awx.awx.tower_credential_input_source:
|
||||
redirect: awx.awx.credential_input_source
|
||||
awx.awx.tower_credential_type:
|
||||
redirect: awx.awx.credential_type
|
||||
awx.awx.tower_credential:
|
||||
redirect: awx.awx.credential
|
||||
awx.awx.tower_execution_environment:
|
||||
redirect: awx.awx.execution_environment
|
||||
awx.awx.tower_export:
|
||||
redirect: awx.awx.export
|
||||
awx.awx.tower_group:
|
||||
redirect: awx.awx.group
|
||||
awx.awx.tower_host:
|
||||
redirect: awx.awx.host
|
||||
awx.awx.tower_import:
|
||||
redirect: awx.awx.import
|
||||
awx.awx.tower_instance_group:
|
||||
redirect: awx.awx.instance_group
|
||||
awx.awx.tower_inventory_source_update:
|
||||
redirect: awx.awx.inventory_source_update
|
||||
awx.awx.tower_inventory_source:
|
||||
redirect: awx.awx.inventory_source
|
||||
awx.awx.tower_inventory:
|
||||
redirect: awx.awx.inventory
|
||||
awx.awx.tower_job_cancel:
|
||||
redirect: awx.awx.job_cancel
|
||||
awx.awx.tower_job_launch:
|
||||
redirect: awx.awx.job_launch
|
||||
awx.awx.tower_job_list:
|
||||
redirect: awx.awx.job_list
|
||||
awx.awx.tower_job_template:
|
||||
redirect: awx.awx.job_template
|
||||
awx.awx.tower_job_wait:
|
||||
redirect: awx.awx.job_wait
|
||||
awx.awx.tower_label:
|
||||
redirect: awx.awx.label
|
||||
awx.awx.tower_license:
|
||||
redirect: awx.awx.license
|
||||
awx.awx.tower_notification_template:
|
||||
redirect: awx.awx.notification_template
|
||||
awx.awx.tower_notification:
|
||||
redirect: awx.awx.notification_template
|
||||
awx.awx.tower_organization:
|
||||
redirect: awx.awx.organization
|
||||
awx.awx.tower_project_update:
|
||||
redirect: awx.awx.project_update
|
||||
awx.awx.tower_project:
|
||||
redirect: awx.awx.project
|
||||
awx.awx.tower_role:
|
||||
redirect: awx.awx.role
|
||||
awx.awx.tower_schedule:
|
||||
redirect: awx.awx.schedule
|
||||
awx.awx.tower_settings:
|
||||
redirect: awx.awx.settings
|
||||
awx.awx.tower_team:
|
||||
redirect: awx.awx.team
|
||||
awx.awx.tower_token:
|
||||
redirect: awx.awx.token
|
||||
awx.awx.tower_user:
|
||||
redirect: awx.awx.user
|
||||
awx.awx.tower_workflow_approval:
|
||||
redirect: awx.awx.workflow_approval
|
||||
awx.awx.tower_workflow_job_template_node:
|
||||
redirect: awx.awx.workflow_job_template_node
|
||||
awx.awx.tower_workflow_job_template:
|
||||
redirect: awx.awx.workflow_job_template
|
||||
awx.awx.tower_workflow_launch:
|
||||
redirect: awx.awx.workflow_launch
|
||||
awx.awx.tower_workflow_node_wait:
|
||||
redirect: awx.awx.workflow_node_wait
|
||||
|
||||
@ -10,52 +10,57 @@ __metaclass__ = type
|
||||
|
||||
class ModuleDocFragment(object):
|
||||
|
||||
# Ansible Tower documentation fragment
|
||||
# Automation Platform Controller documentation fragment
|
||||
DOCUMENTATION = r'''
|
||||
options:
|
||||
tower_host:
|
||||
controller_host:
|
||||
description:
|
||||
- URL to your Tower or AWX instance.
|
||||
- If value not set, will try environment variable C(TOWER_HOST) and then config files
|
||||
- URL to your Automation Platform Controller instance.
|
||||
- If value not set, will try environment variable C(CONTROLLER_HOST) and then config files
|
||||
- If value not specified by any means, the value of C(127.0.0.1) will be used
|
||||
type: str
|
||||
tower_username:
|
||||
aliases: [ tower_host ]
|
||||
controller_username:
|
||||
description:
|
||||
- Username for your Tower or AWX instance.
|
||||
- If value not set, will try environment variable C(TOWER_USERNAME) and then config files
|
||||
- Username for your controller instance.
|
||||
- If value not set, will try environment variable C(CONTROLLER_USERNAME) and then config files
|
||||
type: str
|
||||
tower_password:
|
||||
aliases: [ tower_username ]
|
||||
controller_password:
|
||||
description:
|
||||
- Password for your Tower or AWX instance.
|
||||
- If value not set, will try environment variable C(TOWER_PASSWORD) and then config files
|
||||
- Password for your controller instance.
|
||||
- If value not set, will try environment variable C(CONTROLLER_PASSWORD) and then config files
|
||||
type: str
|
||||
tower_oauthtoken:
|
||||
aliases: [ tower_password ]
|
||||
controller_oauthtoken:
|
||||
description:
|
||||
- The Tower OAuth token to use.
|
||||
- The OAuth token to use.
|
||||
- This value can be in one of two formats.
|
||||
- A string which is the token itself. (i.e. bqV5txm97wqJqtkxlMkhQz0pKhRMMX)
|
||||
- A dictionary structure as returned by the tower_token module.
|
||||
- If value not set, will try environment variable C(TOWER_OAUTH_TOKEN) and then config files
|
||||
- A dictionary structure as returned by the token module.
|
||||
- If value not set, will try environment variable C(CONTROLLER_OAUTH_TOKEN) and then config files
|
||||
type: raw
|
||||
version_added: "3.7"
|
||||
version_added: "3.7.0"
|
||||
aliases: [ tower_oauthtoken ]
|
||||
validate_certs:
|
||||
description:
|
||||
- Whether to allow insecure connections to Tower or AWX.
|
||||
- Whether to allow insecure connections to AWX.
|
||||
- If C(no), SSL certificates will not be validated.
|
||||
- This should only be used on personally controlled sites using self-signed certificates.
|
||||
- If value not set, will try environment variable C(TOWER_VERIFY_SSL) and then config files
|
||||
- If value not set, will try environment variable C(CONTROLLER_VERIFY_SSL) and then config files
|
||||
type: bool
|
||||
aliases: [ tower_verify_ssl ]
|
||||
tower_config_file:
|
||||
controller_config_file:
|
||||
description:
|
||||
- Path to the Tower or AWX config file.
|
||||
- Path to the controller config file.
|
||||
- If provided, the other locations for config files will not be considered.
|
||||
type: path
|
||||
aliases: [tower_config_file]
|
||||
|
||||
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
|
||||
defaults to find your host information.
|
||||
- I(config_file) should be in the following format
|
||||
host=hostname
|
||||
username=username
|
||||
password=password
|
||||
|
||||
@ -10,39 +10,54 @@ __metaclass__ = type
|
||||
|
||||
class ModuleDocFragment(object):
|
||||
|
||||
# Ansible Tower documentation fragment
|
||||
# Automation Platform Controller documentation fragment
|
||||
DOCUMENTATION = r'''
|
||||
options:
|
||||
host:
|
||||
description: The network address of your Ansible Tower host.
|
||||
description: The network address of your Automation Platform Controller host.
|
||||
env:
|
||||
- name: CONTROLLER_HOST
|
||||
- name: TOWER_HOST
|
||||
deprecated:
|
||||
alternatives: 'CONTROLLER_HOST'
|
||||
username:
|
||||
description: The user that you plan to use to access inventories on Ansible Tower.
|
||||
description: The user that you plan to use to access inventories on the controller.
|
||||
env:
|
||||
- name: CONTROLLER_USERNAME
|
||||
- name: TOWER_USERNAME
|
||||
deprecated:
|
||||
alternatives: 'CONTROLLER_USERNAME'
|
||||
password:
|
||||
description: The password for your Ansible Tower user.
|
||||
description: The password for your controller user.
|
||||
env:
|
||||
- name: CONTROLLER_PASSWORD
|
||||
- name: TOWER_PASSWORD
|
||||
deprecated:
|
||||
alternatives: 'CONTROLLER_PASSWORD'
|
||||
oauth_token:
|
||||
description:
|
||||
- The Tower OAuth token to use.
|
||||
- The OAuth token to use.
|
||||
env:
|
||||
- name: CONTROLLER_OAUTH_TOKEN
|
||||
- name: TOWER_OAUTH_TOKEN
|
||||
deprecated:
|
||||
alternatives: 'CONTROLLER_OAUTH_TOKEN'
|
||||
verify_ssl:
|
||||
description:
|
||||
- Specify whether Ansible should verify the SSL certificate of Ansible Tower host.
|
||||
- Specify whether Ansible should verify the SSL certificate of the controller host.
|
||||
- Defaults to True, but this is handled by the shared module_utils code
|
||||
type: bool
|
||||
env:
|
||||
- name: CONTROLLER_VERIFY_SSL
|
||||
- name: TOWER_VERIFY_SSL
|
||||
deprecated:
|
||||
alternatives: 'CONTROLLER_VERIFY_SSL'
|
||||
aliases: [ validate_certs ]
|
||||
|
||||
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
|
||||
defaults to find your host information.
|
||||
- I(config_file) should be in the following format
|
||||
host=hostname
|
||||
username=username
|
||||
password=password
|
||||
|
||||
@ -6,33 +6,33 @@ from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = '''
|
||||
name: tower
|
||||
name: controller
|
||||
plugin_type: inventory
|
||||
author:
|
||||
- Matthew Jones (@matburt)
|
||||
- Yunfan Zhang (@YunfanZhang42)
|
||||
short_description: Ansible dynamic inventory plugin for Ansible Tower.
|
||||
short_description: Ansible dynamic inventory plugin for the Automation Platform Controller.
|
||||
description:
|
||||
- Reads inventories from Ansible Tower.
|
||||
- Reads inventories from the Automation Platform Controller.
|
||||
- Supports reading configuration from both YAML config file and environment variables.
|
||||
- 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
|
||||
- If reading from the YAML file, the file name must end with controller.(yml|yaml) or controller_inventory.(yml|yaml),
|
||||
the path in the command would be /path/to/controller_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.
|
||||
- If reading configurations from environment variables, the path in the command must be @controller_inventory.
|
||||
extends_documentation_fragment: awx.awx.auth_plugin
|
||||
options:
|
||||
inventory_id:
|
||||
description:
|
||||
- The ID of the Ansible Tower inventory that you wish to import.
|
||||
- The ID of the 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
|
||||
- name: CONTROLLER_INVENTORY
|
||||
required: True
|
||||
include_metadata:
|
||||
description: Make extra requests to provide all group vars with metadata about the source Ansible Tower host.
|
||||
description: Make extra requests to provide all group vars with metadata about the source host.
|
||||
type: bool
|
||||
default: False
|
||||
'''
|
||||
@ -41,27 +41,27 @@ 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
|
||||
# Example for using controller_inventory.yml file
|
||||
|
||||
plugin: awx.awx.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
|
||||
plugin: awx.awx.controller
|
||||
host: your_automation_controller_server_network_address
|
||||
username: your_automation_controller_username
|
||||
password: your_automation_controller_password
|
||||
inventory_id: the_ID_of_targeted_automation_controller_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
|
||||
# ansible-inventory -i /path/to/controller_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
|
||||
# export CONTROLLER_HOST=YOUR_AUTOMATION_PLATFORM_CONTROLLER_HOST_ADDRESS
|
||||
# export CONTROLLER_USERNAME=YOUR_CONTROLLER_USERNAME
|
||||
# export CONTROLLER_PASSWORD=YOUR_CONTROLLER_PASSWORD
|
||||
# export CONTROLLER_INVENTORY=THE_ID_OF_TARGETED_INVENTORY
|
||||
# Read the inventory specified in CONTROLLER_INVENTORY from the controller, and list them.
|
||||
# The inventory path must always be @controller_inventory if you are reading all settings from environment variables.
|
||||
# ansible-inventory -i @controller_inventory --list
|
||||
'''
|
||||
|
||||
import os
|
||||
@ -72,7 +72,7 @@ from ansible.errors import AnsibleParserError, AnsibleOptionsError
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin
|
||||
from ansible.config.manager import ensure_type
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def handle_error(**kwargs):
|
||||
@ -80,17 +80,28 @@ def handle_error(**kwargs):
|
||||
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin):
|
||||
NAME = 'awx.awx.tower' # REPLACE
|
||||
# Stays backward compatible with tower inventory script.
|
||||
# If the user supplies '@tower_inventory' as path, the plugin will read from environment variables.
|
||||
NAME = 'awx.awx.controller' # REPLACE
|
||||
# Stays backward compatible with the inventory script.
|
||||
# If the user supplies '@controller_inventory' as path, the plugin will read from environment variables.
|
||||
no_config_file_supplied = False
|
||||
|
||||
def verify_file(self, path):
|
||||
if path.endswith('@tower_inventory'):
|
||||
if path.endswith('@controller_inventory') or 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', 'tower_inventory.yaml', 'tower.yml', 'tower.yaml'))
|
||||
elif super().verify_file(path):
|
||||
return path.endswith(
|
||||
(
|
||||
'controller_inventory.yml',
|
||||
'controller_inventory.yaml',
|
||||
'controller.yml',
|
||||
'controller.yaml',
|
||||
'tower_inventory.yml',
|
||||
'tower_inventory.yaml',
|
||||
'tower.yml',
|
||||
'tower.yaml',
|
||||
)
|
||||
)
|
||||
else:
|
||||
return False
|
||||
|
||||
@ -98,18 +109,18 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
self.display.warning(warning)
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
super(InventoryModule, self).parse(inventory, loader, path)
|
||||
super().parse(inventory, loader, path)
|
||||
if not self.no_config_file_supplied and os.path.isfile(path):
|
||||
self._read_config_data(path)
|
||||
|
||||
# Defer processing of params to logic shared with the modules
|
||||
module_params = {}
|
||||
for plugin_param, module_param in TowerAPIModule.short_params.items():
|
||||
for plugin_param, module_param in ControllerAPIModule.short_params.items():
|
||||
opt_val = self.get_option(plugin_param)
|
||||
if opt_val is not None:
|
||||
module_params[module_param] = opt_val
|
||||
|
||||
module = TowerAPIModule(argument_spec={}, direct_params=module_params, error_callback=handle_error, warn_callback=self.warn_callback)
|
||||
module = ControllerAPIModule(argument_spec={}, direct_params=module_params, error_callback=handle_error, warn_callback=self.warn_callback)
|
||||
|
||||
# validate type of inventory_id because we allow two types as special case
|
||||
inventory_id = self.get_option('inventory_id')
|
||||
@ -121,7 +132,7 @@ class InventoryModule(BaseInventoryPlugin):
|
||||
except ValueError as e:
|
||||
raise AnsibleOptionsError(
|
||||
'Invalid type for configuration option inventory_id, ' 'not integer, and cannot convert to string: {err}'.format(err=to_native(e))
|
||||
)
|
||||
) from e
|
||||
inventory_id = inventory_id.replace('/', '')
|
||||
inventory_url = '/api/v2/inventories/{inv_id}/script/'.format(inv_id=inventory_id)
|
||||
|
||||
@ -5,16 +5,16 @@ from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
lookup: tower_api
|
||||
lookup: controller_api
|
||||
author: John Westcott IV (@john-westcott-iv)
|
||||
short_description: Search the API for objects
|
||||
requirements:
|
||||
- None
|
||||
description:
|
||||
- Returns GET requests from the Ansible Tower API. See
|
||||
- Returns GET requests from the Automation Platform Controller API. See
|
||||
U(https://docs.ansible.com/ansible-tower/latest/html/towerapi/index.html) for API usage.
|
||||
- For use that is cross-compatible between the awx.awx and ansible.tower collection
|
||||
see the tower_meta module
|
||||
- For use that is cross-compatible between the awx.awx and ansible.controller collection
|
||||
see the controller_meta module
|
||||
extends_documentation_fragment: awx.awx.auth_plugin
|
||||
options:
|
||||
_terms:
|
||||
@ -71,37 +71,38 @@ notes:
|
||||
EXAMPLES = """
|
||||
- name: Load the UI settings
|
||||
set_fact:
|
||||
tower_settings: "{{ lookup('awx.awx.tower_api', 'settings/ui') }}"
|
||||
controller_settings: "{{ lookup('awx.awx.controller_api', 'settings/ui') }}"
|
||||
|
||||
- name: Load the UI settings specifying the connection info
|
||||
set_fact:
|
||||
tower_settings: "{{ lookup('awx.awx.tower_api', 'settings/ui' host='tower.example.com', username='admin', password=my_pass_var, verify_ssl=False) }}"
|
||||
controller_settings: "{{ lookup('awx.awx.controller_api', 'settings/ui' host='controller.example.com',
|
||||
username='admin', password=my_pass_var, verify_ssl=False) }}"
|
||||
|
||||
- name: Report the usernames of all users with admin privs
|
||||
debug:
|
||||
msg: "Admin users: {{ query('awx.awx.tower_api', 'users', query_params={ 'is_superuser': true }) | map(attribute='username') | join(', ') }}"
|
||||
msg: "Admin users: {{ query('awx.awx.controller_api', 'users', query_params={ 'is_superuser': true }) | map(attribute='username') | join(', ') }}"
|
||||
|
||||
- name: debug all organizations in a loop # use query to return a list
|
||||
debug:
|
||||
msg: "Organization description={{ item['description'] }} id={{ item['id'] }}"
|
||||
loop: "{{ query('awx.awx.tower_api', 'organizations') }}"
|
||||
loop: "{{ query('awx.awx.controller_api', 'organizations') }}"
|
||||
loop_control:
|
||||
label: "{{ item['name'] }}"
|
||||
|
||||
- name: Make sure user 'john' is an org admin of the default org if the user exists
|
||||
tower_role:
|
||||
role:
|
||||
organization: Default
|
||||
role: admin
|
||||
user: john
|
||||
when: "lookup('awx.awx.tower_api', 'users', query_params={ 'username': 'john' }) | length == 1"
|
||||
when: "lookup('awx.awx.controller_api', 'users', query_params={ 'username': 'john' }) | length == 1"
|
||||
|
||||
- name: Create an inventory group with all 'foo' hosts
|
||||
tower_group:
|
||||
group:
|
||||
name: "Foo Group"
|
||||
inventory: "Demo Inventory"
|
||||
hosts: >-
|
||||
{{ query(
|
||||
'awx.awx.tower_api',
|
||||
'awx.awx.controller_api',
|
||||
'hosts',
|
||||
query_params={ 'name__startswith' : 'foo', },
|
||||
) | map(attribute='name') | list }}
|
||||
@ -120,7 +121,7 @@ from ansible.plugins.lookup import LookupBase
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.utils.display import Display
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
@ -140,13 +141,13 @@ class LookupModule(LookupBase):
|
||||
|
||||
# Defer processing of params to logic shared with the modules
|
||||
module_params = {}
|
||||
for plugin_param, module_param in TowerAPIModule.short_params.items():
|
||||
for plugin_param, module_param in ControllerAPIModule.short_params.items():
|
||||
opt_val = self.get_option(plugin_param)
|
||||
if opt_val is not None:
|
||||
module_params[module_param] = opt_val
|
||||
|
||||
# Create our module
|
||||
module = TowerAPIModule(argument_spec={}, direct_params=module_params, error_callback=self.handle_error, warn_callback=self.warn_callback)
|
||||
module = ControllerAPIModule(argument_spec={}, direct_params=module_params, error_callback=self.handle_error, warn_callback=self.warn_callback)
|
||||
|
||||
response = module.get_endpoint(terms[0], data=self.get_option('query_params', {}))
|
||||
|
||||
@ -5,12 +5,12 @@ from __future__ import absolute_import, division, print_function
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = """
|
||||
lookup: tower_schedule_rrule
|
||||
lookup: schedule_rrule
|
||||
author: John Westcott IV (@john-westcott-iv)
|
||||
short_description: Generate an rrule string which can be used for Tower Schedules
|
||||
short_description: Generate an rrule string which can be used for Schedules
|
||||
requirements:
|
||||
- pytz
|
||||
- python.dateutil >= 2.7.0
|
||||
- python-dateutil >= 2.7.0
|
||||
description:
|
||||
- Returns a string based on criteria which represents an rrule
|
||||
options:
|
||||
@ -75,7 +75,7 @@ DOCUMENTATION = """
|
||||
EXAMPLES = """
|
||||
- name: Create a string for a schedule
|
||||
debug:
|
||||
msg: "{{ query('awx.awx.tower_schedule_rrule', 'none', start_date='1979-09-13 03:45:07') }}"
|
||||
msg: "{{ query('awx.awx.schedule_rrule', 'none', start_date='1979-09-13 03:45:07') }}"
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
@ -84,35 +84,22 @@ _raw:
|
||||
- String in the rrule format
|
||||
type: string
|
||||
"""
|
||||
import re
|
||||
|
||||
from ansible.module_utils.six import raise_from
|
||||
from ansible.plugins.lookup import LookupBase
|
||||
from ansible.errors import AnsibleError
|
||||
from datetime import datetime
|
||||
import re
|
||||
from dateutil import rrule
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
missing_modules = []
|
||||
try:
|
||||
import pytz
|
||||
except ImportError:
|
||||
missing_modules.append('pytz')
|
||||
|
||||
try:
|
||||
from dateutil import rrule
|
||||
except ImportError:
|
||||
missing_modules.append('python.dateutil')
|
||||
|
||||
# Validate the version of python.dateutil
|
||||
try:
|
||||
import dateutil
|
||||
|
||||
if LooseVersion(dateutil.__version__) < LooseVersion("2.7.0"):
|
||||
raise Exception
|
||||
except Exception:
|
||||
missing_modules.append('python.dateutil>=2.7.0')
|
||||
|
||||
if len(missing_modules) > 0:
|
||||
raise AnsibleError('You are missing the modules {0}'.format(', '.join(missing_modules)))
|
||||
except ImportError as imp_exc:
|
||||
LIBRARY_IMPORT_ERROR = imp_exc
|
||||
else:
|
||||
LIBRARY_IMPORT_ERROR = None
|
||||
|
||||
|
||||
class LookupModule(LookupBase):
|
||||
@ -143,6 +130,15 @@ class LookupModule(LookupBase):
|
||||
'last': -1,
|
||||
}
|
||||
|
||||
# plugin constructor
|
||||
def __init__(self, *args, **kwargs):
|
||||
if LIBRARY_IMPORT_ERROR:
|
||||
raise_from(
|
||||
AnsibleError('{0}'.format(LIBRARY_IMPORT_ERROR)),
|
||||
LIBRARY_IMPORT_ERROR
|
||||
)
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
@staticmethod
|
||||
def parse_date_time(date_string):
|
||||
try:
|
||||
@ -173,8 +169,8 @@ class LookupModule(LookupBase):
|
||||
if 'start_date' in kwargs:
|
||||
try:
|
||||
rrule_kwargs['dtstart'] = LookupModule.parse_date_time(kwargs['start_date'])
|
||||
except Exception:
|
||||
raise AnsibleError('Parameter start_date must be in the format YYYY-MM-DD [HH:MM:SS]')
|
||||
except Exception as e:
|
||||
raise AnsibleError('Parameter start_date must be in the format YYYY-MM-DD [HH:MM:SS]') from e
|
||||
|
||||
# If we are a none frequency we don't need anything else
|
||||
if frequency == 'none':
|
||||
@ -188,8 +184,8 @@ class LookupModule(LookupBase):
|
||||
else:
|
||||
try:
|
||||
rrule_kwargs['until'] = LookupModule.parse_date_time(end_on)
|
||||
except Exception:
|
||||
raise AnsibleError('Parameter end_on must either be an integer or in the format YYYY-MM-DD [HH:MM:SS]')
|
||||
except Exception as e:
|
||||
raise AnsibleError('Parameter end_on must either be an integer or in the format YYYY-MM-DD [HH:MM:SS]') from e
|
||||
|
||||
# A week-based frequency can also take the on_days parameter
|
||||
if frequency == 'week' and 'on_days' in kwargs:
|
||||
@ -212,16 +208,16 @@ class LookupModule(LookupBase):
|
||||
my_month_day = int(kwargs['month_day_number'])
|
||||
if my_month_day < 1 or my_month_day > 31:
|
||||
raise Exception()
|
||||
except Exception:
|
||||
raise AnsibleError('month_day_number must be between 1 and 31')
|
||||
except Exception as e:
|
||||
raise AnsibleError('month_day_number must be between 1 and 31') from e
|
||||
|
||||
rrule_kwargs['bymonthday'] = my_month_day
|
||||
|
||||
if 'on_the' in kwargs:
|
||||
try:
|
||||
(occurance, weekday) = kwargs['on_the'].split(' ')
|
||||
except Exception:
|
||||
raise AnsibleError('on_the parameter must be two words separated by a space')
|
||||
except Exception as e:
|
||||
raise AnsibleError('on_the parameter must be two words separated by a space') from e
|
||||
|
||||
if weekday not in LookupModule.weekdays:
|
||||
raise AnsibleError('Weekday portion of on_the parameter is not valid')
|
||||
@ -233,7 +229,7 @@ class LookupModule(LookupBase):
|
||||
|
||||
my_rule = rrule.rrule(**rrule_kwargs)
|
||||
|
||||
# All frequencies can use a timezone but rrule can't support the format that Tower uses.
|
||||
# All frequencies can use a timezone but rrule can't support the format that AWX uses.
|
||||
# So we will do a string manip here if we need to
|
||||
timezone = 'America/New_York'
|
||||
if 'timezone' in kwargs:
|
||||
@ -243,7 +239,7 @@ class LookupModule(LookupBase):
|
||||
|
||||
# rrule puts a \n in the rule instad of a space and can't handle timezones
|
||||
return_rrule = str(my_rule).replace('\n', ' ').replace('DTSTART:', 'DTSTART;TZID={0}:'.format(timezone))
|
||||
# Tower requires an interval. rrule will not add interval if it's set to 1
|
||||
# AWX requires an interval. rrule will not add interval if it's set to 1
|
||||
if kwargs.get('every', 1) == 1:
|
||||
return_rrule = "{0};INTERVAL=1".format(return_rrule)
|
||||
|
||||
@ -2,7 +2,7 @@ from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
from .tower_module import TowerModule
|
||||
from .controller_module import ControllerModule
|
||||
from ansible.module_utils.basic import missing_required_lib
|
||||
|
||||
try:
|
||||
@ -15,14 +15,14 @@ except ImportError:
|
||||
HAS_AWX_KIT = False
|
||||
|
||||
|
||||
class TowerAWXKitModule(TowerModule):
|
||||
class ControllerAWXKitModule(ControllerModule):
|
||||
connection = None
|
||||
apiV2Ref = None
|
||||
|
||||
def __init__(self, argument_spec, **kwargs):
|
||||
kwargs['supports_check_mode'] = False
|
||||
|
||||
super(TowerAWXKitModule, self).__init__(argument_spec=argument_spec, **kwargs)
|
||||
super().__init__(argument_spec=argument_spec, **kwargs)
|
||||
|
||||
# Die if we don't have AWX_KIT installed
|
||||
if not HAS_AWX_KIT:
|
||||
@ -2,7 +2,7 @@ from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
from .tower_module import TowerModule
|
||||
from .controller_module import ControllerModule
|
||||
from ansible.module_utils.urls import Request, SSLValidationError, ConnectionError
|
||||
from ansible.module_utils.six import PY2
|
||||
from ansible.module_utils.six.moves.urllib.error import HTTPError
|
||||
@ -12,8 +12,8 @@ import time
|
||||
from json import loads, dumps
|
||||
|
||||
|
||||
class TowerAPIModule(TowerModule):
|
||||
# TODO: Move the collection version check into tower_module.py
|
||||
class ControllerAPIModule(ControllerModule):
|
||||
# TODO: Move the collection version check into controller_module.py
|
||||
# This gets set by the make process so whatever is in here is irrelevant
|
||||
_COLLECTION_VERSION = "0.0.1-devel"
|
||||
_COLLECTION_TYPE = "awx"
|
||||
@ -21,7 +21,7 @@ class TowerAPIModule(TowerModule):
|
||||
# Those values can be found in awx/api/generics.py line 204
|
||||
collection_to_version = {
|
||||
'awx': 'AWX',
|
||||
'tower': 'Red Hat Ansible Tower',
|
||||
'controller': 'Red Hat Automation Platform Controller',
|
||||
}
|
||||
session = None
|
||||
IDENTITY_FIELDS = {'users': 'username', 'workflow_job_template_nodes': 'identifier', 'instances': 'hostname'}
|
||||
@ -30,7 +30,7 @@ class TowerAPIModule(TowerModule):
|
||||
def __init__(self, argument_spec, direct_params=None, error_callback=None, warn_callback=None, **kwargs):
|
||||
kwargs['supports_check_mode'] = True
|
||||
|
||||
super(TowerAPIModule, self).__init__(
|
||||
super().__init__(
|
||||
argument_spec=argument_spec, direct_params=direct_params, error_callback=error_callback, warn_callback=warn_callback, **kwargs
|
||||
)
|
||||
self.session = Request(cookies=CookieJar(), validate_certs=self.verify_ssl)
|
||||
@ -47,14 +47,14 @@ class TowerAPIModule(TowerModule):
|
||||
|
||||
@staticmethod
|
||||
def get_name_field_from_endpoint(endpoint):
|
||||
return TowerAPIModule.IDENTITY_FIELDS.get(endpoint, 'name')
|
||||
return ControllerAPIModule.IDENTITY_FIELDS.get(endpoint, 'name')
|
||||
|
||||
def get_item_name(self, item, allow_unknown=False):
|
||||
if item:
|
||||
if 'name' in item:
|
||||
return item['name']
|
||||
|
||||
for field_name in TowerAPIModule.IDENTITY_FIELDS.values():
|
||||
for field_name in ControllerAPIModule.IDENTITY_FIELDS.values():
|
||||
if field_name in item:
|
||||
return item[field_name]
|
||||
|
||||
@ -163,7 +163,7 @@ class TowerAPIModule(TowerModule):
|
||||
if len(sample['json']['results']) > 1:
|
||||
sample['json']['results'] = sample['json']['results'][:2] + ['...more results snipped...']
|
||||
url = self.build_url(endpoint, query_params)
|
||||
display_endpoint = url.geturl()[len(self.host) :] # truncate to not include the base URL
|
||||
display_endpoint = url.geturl()[len(self.host):] # truncate to not include the base URL
|
||||
self.fail_json(
|
||||
msg="Request to {0} returned {1} items, expected 1".format(display_endpoint, response['json']['count']),
|
||||
query=query_params,
|
||||
@ -190,7 +190,7 @@ class TowerAPIModule(TowerModule):
|
||||
# Extract the headers, this will be used in a couple of places
|
||||
headers = kwargs.get('headers', {})
|
||||
|
||||
# Authenticate to Tower (if we don't have a token and if not already done so)
|
||||
# Authenticate to AWX (if we don't have a token and if not already done so)
|
||||
if not self.oauth_token and not self.authenticated:
|
||||
# This method will set a cookie in the cookie jar for us and also an oauth_token
|
||||
self.authenticate(**kwargs)
|
||||
@ -218,7 +218,7 @@ class TowerAPIModule(TowerModule):
|
||||
self.fail_json(msg='The host sent back a server error ({1}): {0}. Please check the logs and try again later'.format(url.path, he))
|
||||
# Sanity check: Did we fail to authenticate properly? If so, fail out now; this is always a failure.
|
||||
elif he.code == 401:
|
||||
self.fail_json(msg='Invalid Tower authentication credentials for {0} (HTTP 401).'.format(url.path))
|
||||
self.fail_json(msg='Invalid authentication credentials for {0} (HTTP 401).'.format(url.path))
|
||||
# Sanity check: Did we get a forbidden response, which means that the user isn't allowed to do this? Report that.
|
||||
elif he.code == 403:
|
||||
self.fail_json(msg="You don't have permission to {1} to {0} (HTTP 403).".format(url.path, method))
|
||||
@ -232,7 +232,7 @@ class TowerAPIModule(TowerModule):
|
||||
# A 405 means we used a method that isn't allowed. Usually this is a bad request, but it requires special treatment because the
|
||||
# API sends it as a logic error in a few situations (e.g. trying to cancel a job that isn't running).
|
||||
elif he.code == 405:
|
||||
self.fail_json(msg="The Tower server says you can't make a request with the {0} method to this endpoint {1}".format(method, url.path))
|
||||
self.fail_json(msg="Cannot make a request with the {0} method to this endpoint {1}".format(method, url.path))
|
||||
# Sanity check: Did we get some other kind of error? If so, write an appropriate error message.
|
||||
elif he.code >= 400:
|
||||
# We are going to return a 400 so the module can decide what to do with it
|
||||
@ -254,26 +254,28 @@ class TowerAPIModule(TowerModule):
|
||||
# In PY2 we get back an HTTPResponse object but PY2 is returning an addinfourl
|
||||
# First try to get the headers in PY3 format and then drop down to PY2.
|
||||
try:
|
||||
tower_type = response.getheader('X-API-Product-Name', None)
|
||||
tower_version = response.getheader('X-API-Product-Version', None)
|
||||
controller_type = response.getheader('X-API-Product-Name', None)
|
||||
controller_version = response.getheader('X-API-Product-Version', None)
|
||||
except Exception:
|
||||
tower_type = response.info().getheader('X-API-Product-Name', None)
|
||||
tower_version = response.info().getheader('X-API-Product-Version', None)
|
||||
controller_type = response.info().getheader('X-API-Product-Name', None)
|
||||
controller_version = response.info().getheader('X-API-Product-Version', None)
|
||||
|
||||
parsed_collection_version = Version(self._COLLECTION_VERSION).version
|
||||
parsed_tower_version = Version(tower_version).version
|
||||
if tower_type == 'AWX':
|
||||
parsed_controller_version = Version(controller_version).version
|
||||
if controller_type == 'AWX':
|
||||
collection_compare_ver = parsed_collection_version[0]
|
||||
tower_compare_ver = parsed_tower_version[0]
|
||||
controller_compare_ver = parsed_controller_version[0]
|
||||
else:
|
||||
collection_compare_ver = "{0}.{1}".format(parsed_collection_version[0], parsed_collection_version[1])
|
||||
tower_compare_ver = '{0}.{1}'.format(parsed_tower_version[0], parsed_tower_version[1])
|
||||
controller_compare_ver = '{0}.{1}'.format(parsed_controller_version[0], parsed_controller_version[1])
|
||||
|
||||
if self._COLLECTION_TYPE not in self.collection_to_version or self.collection_to_version[self._COLLECTION_TYPE] != tower_type:
|
||||
self.warn("You are using the {0} version of this collection but connecting to {1}".format(self._COLLECTION_TYPE, tower_type))
|
||||
elif collection_compare_ver != tower_compare_ver:
|
||||
if self._COLLECTION_TYPE not in self.collection_to_version or self.collection_to_version[self._COLLECTION_TYPE] != controller_type:
|
||||
self.warn("You are using the {0} version of this collection but connecting to {1}".format(self._COLLECTION_TYPE, controller_type))
|
||||
elif collection_compare_ver != controller_compare_ver:
|
||||
self.warn(
|
||||
"You are running collection version {0} but connecting to {2} version {1}".format(self._COLLECTION_VERSION, tower_version, tower_type)
|
||||
"You are running collection version {0} but connecting to {2} version {1}".format(
|
||||
self._COLLECTION_VERSION, controller_version, controller_type
|
||||
)
|
||||
)
|
||||
|
||||
self.version_checked = True
|
||||
@ -302,7 +304,7 @@ class TowerAPIModule(TowerModule):
|
||||
# Attempt to get a token from /api/v2/tokens/ by giving it our username/password combo
|
||||
# If we have a username and password, we need to get a session cookie
|
||||
login_data = {
|
||||
"description": "Ansible Tower Module Token",
|
||||
"description": "Automation Platform Controller Module Token",
|
||||
"application": None,
|
||||
"scope": "write",
|
||||
}
|
||||
@ -349,8 +351,8 @@ class TowerAPIModule(TowerModule):
|
||||
# the on_delete parameter will be called as a method pasing in this object and the json from the response
|
||||
# This will return one of two things:
|
||||
# 1. None if the existing_item is not defined (so no delete needs to happen)
|
||||
# 2. The response from Tower from calling the delete on the endpont. It's up to you to process the response and exit from the module
|
||||
# Note: common error codes from the Tower API can cause the module to fail
|
||||
# 2. The response from AWX from calling the delete on the endpont. It's up to you to process the response and exit from the module
|
||||
# Note: common error codes from the AWX API can cause the module to fail
|
||||
if existing_item:
|
||||
# If we have an item, we can try to delete it
|
||||
try:
|
||||
@ -472,8 +474,8 @@ class TowerAPIModule(TowerModule):
|
||||
# the on_create parameter will be called as a method pasing in this object and the json from the response
|
||||
# This will return one of two things:
|
||||
# 1. None if the existing_item is already defined (so no create needs to happen)
|
||||
# 2. The response from Tower from calling the patch on the endpont. It's up to you to process the response and exit from the module
|
||||
# Note: common error codes from the Tower API can cause the module to fail
|
||||
# 2. The response from AWX from calling the patch on the endpont. It's up to you to process the response and exit from the module
|
||||
# Note: common error codes from the AWX API can cause the module to fail
|
||||
response = None
|
||||
if not endpoint:
|
||||
self.fail_json(msg="Unable to create new {0} due to missing endpoint".format(item_type))
|
||||
@ -544,13 +546,13 @@ class TowerAPIModule(TowerModule):
|
||||
"""
|
||||
if isinstance(obj, dict):
|
||||
for val in obj.values():
|
||||
if TowerAPIModule.has_encrypted_values(val):
|
||||
if ControllerAPIModule.has_encrypted_values(val):
|
||||
return True
|
||||
elif isinstance(obj, list):
|
||||
for val in obj:
|
||||
if TowerAPIModule.has_encrypted_values(val):
|
||||
if ControllerAPIModule.has_encrypted_values(val):
|
||||
return True
|
||||
elif obj == TowerAPIModule.ENCRYPTED_STRING:
|
||||
elif obj == ControllerAPIModule.ENCRYPTED_STRING:
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -565,11 +567,11 @@ class TowerAPIModule(TowerModule):
|
||||
if set(old_field.keys()) != set(new_field.keys()):
|
||||
return False
|
||||
for key in new_field.keys():
|
||||
if not TowerAPIModule.fields_could_be_same(old_field[key], new_field[key]):
|
||||
if not ControllerAPIModule.fields_could_be_same(old_field[key], new_field[key]):
|
||||
return False
|
||||
return True # all sub-fields are either equal or could be equal
|
||||
else:
|
||||
if old_field == TowerAPIModule.ENCRYPTED_STRING:
|
||||
if old_field == ControllerAPIModule.ENCRYPTED_STRING:
|
||||
return True
|
||||
return bool(new_field == old_field)
|
||||
|
||||
@ -595,8 +597,8 @@ class TowerAPIModule(TowerModule):
|
||||
# the on_update parameter will be called as a method pasing in this object and the json from the response
|
||||
# This will return one of two things:
|
||||
# 1. None if the existing_item does not need to be updated
|
||||
# 2. The response from Tower from patching to the endpoint. It's up to you to process the response and exit from the module.
|
||||
# Note: common error codes from the Tower API can cause the module to fail
|
||||
# 2. The response from AWX from patching to the endpoint. It's up to you to process the response and exit from the module.
|
||||
# Note: common error codes from the AWX API can cause the module to fail
|
||||
response = None
|
||||
if existing_item:
|
||||
|
||||
@ -694,10 +696,10 @@ class TowerAPIModule(TowerModule):
|
||||
resp = he.read()
|
||||
except Exception as e:
|
||||
resp = 'unknown {0}'.format(e)
|
||||
self.warn('Failed to release tower token: {0}, response: {1}'.format(he, resp))
|
||||
self.warn('Failed to release token: {0}, response: {1}'.format(he, resp))
|
||||
except (Exception) as e:
|
||||
# Sanity check: Did the server send back some kind of internal error?
|
||||
self.warn('Failed to release tower token {0}: {1}'.format(self.oauth_token_id, e))
|
||||
self.warn('Failed to release token {0}: {1}'.format(self.oauth_token_id, e))
|
||||
|
||||
def is_job_done(self, job_status):
|
||||
if job_status in ['new', 'pending', 'waiting', 'running']:
|
||||
@ -29,22 +29,45 @@ class ItemNotDefined(Exception):
|
||||
pass
|
||||
|
||||
|
||||
class TowerModule(AnsibleModule):
|
||||
class ControllerModule(AnsibleModule):
|
||||
url = None
|
||||
AUTH_ARGSPEC = dict(
|
||||
tower_host=dict(required=False, fallback=(env_fallback, ['TOWER_HOST'])),
|
||||
tower_username=dict(required=False, fallback=(env_fallback, ['TOWER_USERNAME'])),
|
||||
tower_password=dict(no_log=True, required=False, fallback=(env_fallback, ['TOWER_PASSWORD'])),
|
||||
validate_certs=dict(type='bool', aliases=['tower_verify_ssl'], required=False, fallback=(env_fallback, ['TOWER_VERIFY_SSL'])),
|
||||
tower_oauthtoken=dict(type='raw', no_log=True, required=False, fallback=(env_fallback, ['TOWER_OAUTH_TOKEN'])),
|
||||
tower_config_file=dict(type='path', required=False, default=None),
|
||||
controller_host=dict(
|
||||
required=False,
|
||||
aliases=['tower_host'],
|
||||
fallback=(env_fallback, ['CONTROLLER_HOST', 'TOWER_HOST'])),
|
||||
controller_username=dict(
|
||||
required=False,
|
||||
aliases=['tower_username'],
|
||||
fallback=(env_fallback, ['CONTROLLER_USERNAME', 'TOWER_USERNAME'])),
|
||||
controller_password=dict(
|
||||
no_log=True,
|
||||
aliases=['tower_password'],
|
||||
required=False,
|
||||
fallback=(env_fallback, ['CONTROLLER_PASSWORD', 'TOWER_PASSWORD'])),
|
||||
validate_certs=dict(
|
||||
type='bool',
|
||||
aliases=['tower_verify_ssl'],
|
||||
required=False,
|
||||
fallback=(env_fallback, ['CONTROLLER_VERIFY_SSL', 'TOWER_VERIFY_SSL'])),
|
||||
controller_oauthtoken=dict(
|
||||
type='raw',
|
||||
no_log=True,
|
||||
aliases=['tower_oauthtoken'],
|
||||
required=False,
|
||||
fallback=(env_fallback, ['CONTROLLER_OAUTH_TOKEN', 'TOWER_OAUTH_TOKEN'])),
|
||||
controller_config_file=dict(
|
||||
type='path',
|
||||
aliases=['tower_config_file'],
|
||||
required=False,
|
||||
default=None),
|
||||
)
|
||||
short_params = {
|
||||
'host': 'tower_host',
|
||||
'username': 'tower_username',
|
||||
'password': 'tower_password',
|
||||
'host': 'controller_host',
|
||||
'username': 'controller_username',
|
||||
'password': 'controller_password',
|
||||
'verify_ssl': 'validate_certs',
|
||||
'oauth_token': 'tower_oauthtoken',
|
||||
'oauth_token': 'controller_oauthtoken',
|
||||
}
|
||||
host = '127.0.0.1'
|
||||
username = None
|
||||
@ -60,7 +83,7 @@ class TowerModule(AnsibleModule):
|
||||
|
||||
def __init__(self, argument_spec=None, direct_params=None, error_callback=None, warn_callback=None, **kwargs):
|
||||
full_argspec = {}
|
||||
full_argspec.update(TowerModule.AUTH_ARGSPEC)
|
||||
full_argspec.update(ControllerModule.AUTH_ARGSPEC)
|
||||
full_argspec.update(argument_spec)
|
||||
kwargs['supports_check_mode'] = True
|
||||
|
||||
@ -72,7 +95,7 @@ class TowerModule(AnsibleModule):
|
||||
if direct_params is not None:
|
||||
self.params = direct_params
|
||||
else:
|
||||
super(TowerModule, self).__init__(argument_spec=full_argspec, **kwargs)
|
||||
super().__init__(argument_spec=full_argspec, **kwargs)
|
||||
|
||||
self.load_config_files()
|
||||
|
||||
@ -82,18 +105,18 @@ class TowerModule(AnsibleModule):
|
||||
if direct_value is not None:
|
||||
setattr(self, short_param, direct_value)
|
||||
|
||||
# Perform magic depending on whether tower_oauthtoken is a string or a dict
|
||||
if self.params.get('tower_oauthtoken'):
|
||||
token_param = self.params.get('tower_oauthtoken')
|
||||
# Perform magic depending on whether controller_oauthtoken is a string or a dict
|
||||
if self.params.get('controller_oauthtoken'):
|
||||
token_param = self.params.get('controller_oauthtoken')
|
||||
if type(token_param) is dict:
|
||||
if 'token' in token_param:
|
||||
self.oauth_token = self.params.get('tower_oauthtoken')['token']
|
||||
self.oauth_token = self.params.get('controller_oauthtoken')['token']
|
||||
else:
|
||||
self.fail_json(msg="The provided dict in tower_oauthtoken did not properly contain the token entry")
|
||||
self.fail_json(msg="The provided dict in controller_oauthtoken did not properly contain the token entry")
|
||||
elif isinstance(token_param, string_types):
|
||||
self.oauth_token = self.params.get('tower_oauthtoken')
|
||||
self.oauth_token = self.params.get('controller_oauthtoken')
|
||||
else:
|
||||
error_msg = "The provided tower_oauthtoken type was not valid ({0}). Valid options are str or dict.".format(type(token_param).__name__)
|
||||
error_msg = "The provided controller_oauthtoken type was not valid ({0}). Valid options are str or dict.".format(type(token_param).__name__)
|
||||
self.fail_json(msg=error_msg)
|
||||
|
||||
# Perform some basic validation
|
||||
@ -104,14 +127,14 @@ class TowerModule(AnsibleModule):
|
||||
try:
|
||||
self.url = urlparse(self.host)
|
||||
except Exception as e:
|
||||
self.fail_json(msg="Unable to parse tower_host as a URL ({1}): {0}".format(self.host, e))
|
||||
self.fail_json(msg="Unable to parse controller_host as a URL ({1}): {0}".format(self.host, e))
|
||||
|
||||
# Try to resolve the hostname
|
||||
hostname = self.url.netloc.split(':')[0]
|
||||
try:
|
||||
gethostbyname(hostname)
|
||||
except Exception as e:
|
||||
self.fail_json(msg="Unable to resolve tower_host ({1}): {0}".format(hostname, e))
|
||||
self.fail_json(msg="Unable to resolve controller_host ({1}): {0}".format(hostname, e))
|
||||
|
||||
def build_url(self, endpoint, query_params=None):
|
||||
# Make sure we start with /api/vX
|
||||
@ -140,18 +163,18 @@ class TowerModule(AnsibleModule):
|
||||
config_files.insert(2, join(local_dir, ".{0}".format(self.config_name)))
|
||||
|
||||
# If we have a specified tower config, load it
|
||||
if self.params.get('tower_config_file'):
|
||||
duplicated_params = [fn for fn in self.AUTH_ARGSPEC if fn != 'tower_config_file' and self.params.get(fn) is not None]
|
||||
if self.params.get('controller_config_file'):
|
||||
duplicated_params = [fn for fn in self.AUTH_ARGSPEC if fn != 'controller_config_file' and self.params.get(fn) is not None]
|
||||
if duplicated_params:
|
||||
self.warn(
|
||||
(
|
||||
'The parameter(s) {0} were provided at the same time as tower_config_file. '
|
||||
'The parameter(s) {0} were provided at the same time as controller_config_file. '
|
||||
'Precedence may be unstable, we suggest either using config file or params.'
|
||||
).format(', '.join(duplicated_params))
|
||||
)
|
||||
try:
|
||||
# TODO: warn if there are conflicts with other params
|
||||
self.load_config(self.params.get('tower_config_file'))
|
||||
self.load_config(self.params.get('controller_config_file'))
|
||||
except ConfigFileException as cfe:
|
||||
# Since we were told specifically to load this we want it to fail if we have an error
|
||||
self.fail_json(msg=cfe)
|
||||
@ -215,10 +238,10 @@ class TowerModule(AnsibleModule):
|
||||
pass
|
||||
|
||||
except Exception as e:
|
||||
raise ConfigFileException("An unknown exception occured trying to ini load config file: {0}".format(e))
|
||||
raise ConfigFileException("An unknown exception occured trying to ini load config file: {0}".format(e)) from e
|
||||
|
||||
except Exception as e:
|
||||
raise ConfigFileException("An unknown exception occured trying to load config file: {0}".format(e))
|
||||
raise ConfigFileException("An unknown exception occured trying to load config file: {0}".format(e)) from e
|
||||
|
||||
# If we made it here, we have a dict which has values in it from our config, any final settings logic can be performed here
|
||||
for honorred_setting in self.short_params:
|
||||
@ -242,15 +265,15 @@ class TowerModule(AnsibleModule):
|
||||
if self.error_callback:
|
||||
self.error_callback(**kwargs)
|
||||
else:
|
||||
super(TowerModule, self).fail_json(**kwargs)
|
||||
super().fail_json(**kwargs)
|
||||
|
||||
def exit_json(self, **kwargs):
|
||||
# Try to log out if we are authenticated
|
||||
self.logout()
|
||||
super(TowerModule, self).exit_json(**kwargs)
|
||||
super().exit_json(**kwargs)
|
||||
|
||||
def warn(self, warning):
|
||||
if self.warn_callback is not None:
|
||||
self.warn_callback(warning)
|
||||
else:
|
||||
super(TowerModule, self).warn(warning)
|
||||
super().warn(warning)
|
||||
@ -113,7 +113,7 @@ class TowerLegacyModule(AnsibleModule):
|
||||
)
|
||||
)
|
||||
|
||||
super(TowerLegacyModule, self).__init__(argument_spec=args, **kwargs)
|
||||
super().__init__(argument_spec=args, **kwargs)
|
||||
|
||||
if not HAS_TOWER_CLI:
|
||||
self.fail_json(msg=missing_required_lib('ansible-tower-cli'), exception=TOWER_CLI_IMP_ERR)
|
||||
|
||||
@ -14,12 +14,12 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_ad_hoc_command
|
||||
module: ad_hoc_command
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
version_added: "4.0"
|
||||
short_description: create, update, or destroy Ansible Tower ad hoc commands.
|
||||
version_added: "4.0.0"
|
||||
short_description: create, update, or destroy Automation Platform Controller ad hoc commands.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower ad hoc commands. See
|
||||
- Create, update, or destroy Automation Platform Controller ad hoc commands. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
job_type:
|
||||
@ -84,7 +84,7 @@ options:
|
||||
type: bool
|
||||
interval:
|
||||
description:
|
||||
- The interval to request an update from Tower.
|
||||
- The interval to request an update from the controller.
|
||||
default: 1
|
||||
type: float
|
||||
timeout:
|
||||
@ -111,7 +111,7 @@ status:
|
||||
sample: pending
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -135,7 +135,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
inventory = module.params.get('inventory')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_ad_hoc_command_cancel
|
||||
module: ad_hoc_command_cancel
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
short_description: Cancel an Ansible Tower Ad Hoc Command.
|
||||
short_description: Cancel an Ad Hoc Command.
|
||||
description:
|
||||
- Cancel Ansible Tower ad hoc command. See
|
||||
- Cancel ad hoc command. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
command_id:
|
||||
@ -33,21 +33,21 @@ options:
|
||||
type: bool
|
||||
interval:
|
||||
description:
|
||||
- The interval in seconds, to request an update from Tower.
|
||||
- The interval in seconds, to request an update from .
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
timeout:
|
||||
description:
|
||||
- Maximum time in seconds to wait for a job to finish.
|
||||
- Not specifying means the task will wait until Tower cancels the command.
|
||||
- Not specifying means the task will wait until the controller cancels the command.
|
||||
type: int
|
||||
extends_documentation_fragment: awx.awx.auth
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Cancel command
|
||||
tower_ad_hoc_command_cancel:
|
||||
ad_hoc_command_cancel:
|
||||
command_id: command.id
|
||||
'''
|
||||
|
||||
@ -62,7 +62,7 @@ id:
|
||||
|
||||
import time
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -75,7 +75,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
command_id = module.params.get('command_id')
|
||||
@ -98,7 +98,7 @@ def main():
|
||||
|
||||
cancel_page = module.get_endpoint(command['related']['cancel'])
|
||||
if 'json' not in cancel_page or 'can_cancel' not in cancel_page['json']:
|
||||
module.fail_json(msg="Failed to cancel command, got unexpected response from tower", **{'response': cancel_page})
|
||||
module.fail_json(msg="Failed to cancel command, got unexpected response", **{'response': cancel_page})
|
||||
|
||||
if not cancel_page['json']['can_cancel']:
|
||||
if fail_if_not_running:
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_ad_hoc_command_wait
|
||||
module: ad_hoc_command_wait
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
short_description: Wait for Ansible Tower Ad Hoc Command to finish.
|
||||
short_description: Wait for Automation Platform Controller Ad Hoc Command to finish.
|
||||
description:
|
||||
- Wait for Ansible Tower ad hoc command to finish and report success or failure. See
|
||||
- Wait for Automation Platform Controller ad hoc command to finish and report success or failure. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
command_id:
|
||||
@ -28,7 +28,7 @@ options:
|
||||
type: int
|
||||
interval:
|
||||
description:
|
||||
- The interval in sections, to request an update from Tower.
|
||||
- The interval in sections, to request an update from the controller.
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
@ -41,14 +41,14 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Launch an ad hoc command
|
||||
tower_ad_hoc_command:
|
||||
ad_hoc_command:
|
||||
inventory: "Demo Inventory"
|
||||
credential: "Demo Credential"
|
||||
wait: false
|
||||
register: command
|
||||
|
||||
- name: Wait for ad joc command max 120s
|
||||
tower_ad_hoc_command_wait:
|
||||
ad_hoc_command_wait:
|
||||
command_id: "{{ command.id }}"
|
||||
timeout: 120
|
||||
'''
|
||||
@ -82,7 +82,7 @@ status:
|
||||
'''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -94,7 +94,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
command_id = module.params.get('command_id')
|
||||
@ -112,7 +112,7 @@ def main():
|
||||
)
|
||||
|
||||
if command is None:
|
||||
module.fail_json(msg='Unable to wait on ad hoc command {0}; that ID does not exist in Tower.'.format(command_id))
|
||||
module.fail_json(msg='Unable to wait on ad hoc command {0}; that ID does not exist.'.format(command_id))
|
||||
|
||||
# Invoke wait function
|
||||
module.wait_on_url(url=command['url'], object_name=command_id, object_type='ad hoc command', timeout=timeout, interval=interval)
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_application
|
||||
module: application
|
||||
author: "Geoffrey Bacheot (@jffz)"
|
||||
short_description: create, update, or destroy Ansible Tower applications
|
||||
short_description: create, update, or destroy Automation Platform Controller applications
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower applications. See
|
||||
- Create, update, or destroy Automation Platform Controller applications. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -69,7 +69,7 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add Foo application
|
||||
tower_application:
|
||||
application:
|
||||
name: "Foo"
|
||||
description: "Foo bar application"
|
||||
organization: "test"
|
||||
@ -78,7 +78,7 @@ EXAMPLES = '''
|
||||
client-type: public
|
||||
|
||||
- name: Add Foo application
|
||||
tower_application:
|
||||
application:
|
||||
name: "Foo"
|
||||
description: "Foo bar application"
|
||||
organization: "test"
|
||||
@ -91,7 +91,7 @@ EXAMPLES = '''
|
||||
|
||||
import time
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -108,7 +108,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -13,7 +13,7 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_meta
|
||||
module: controller_meta
|
||||
author: "Alan Rominger (@alancoding)"
|
||||
short_description: Returns metadata about the collection this module lives in.
|
||||
description:
|
||||
@ -49,7 +49,7 @@ version:
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- tower_meta:
|
||||
- controller_meta:
|
||||
register: result
|
||||
|
||||
- name: Show details about the collection
|
||||
@ -57,16 +57,16 @@ EXAMPLES = '''
|
||||
|
||||
- name: Load the UI setting without hard-coding the collection name
|
||||
debug:
|
||||
msg: "{{ lookup(result.prefix + '.tower_api', 'settings/ui') }}"
|
||||
msg: "{{ lookup(result.prefix + '.controller_api', 'settings/ui') }}"
|
||||
'''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
module = TowerAPIModule(argument_spec={})
|
||||
namespace = {'awx': 'awx', 'tower': 'ansible'}.get(module._COLLECTION_TYPE, 'unknown')
|
||||
module = ControllerAPIModule(argument_spec={})
|
||||
namespace = {'awx': 'awx', 'controller': 'ansible'}.get(module._COLLECTION_TYPE, 'unknown')
|
||||
namespace_name = '{0}.{1}'.format(namespace, module._COLLECTION_TYPE)
|
||||
module.exit_json(prefix=namespace_name, name=module._COLLECTION_TYPE, namespace=namespace, version=module._COLLECTION_VERSION)
|
||||
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_credential
|
||||
module: credential
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower credential.
|
||||
short_description: create, update, or destroy Automation Platform Controller credential.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower credentials. See
|
||||
- Create, update, or destroy Automation Platform Controller credentials. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -56,7 +56,7 @@ options:
|
||||
description:
|
||||
- >-
|
||||
Credential inputs where the keys are var names used in templating.
|
||||
Refer to the Ansible Tower documentation for example syntax.
|
||||
Refer to the Automation Platform Controller documentation for example syntax.
|
||||
- Any fields in this dict will take prescedence over any fields mentioned below (i.e. host, username, etc)
|
||||
type: dict
|
||||
update_secrets:
|
||||
@ -96,7 +96,7 @@ options:
|
||||
password:
|
||||
description:
|
||||
- Password for this credential. ``secret_key`` for AWS. ``api_key`` for RAX.
|
||||
- Use "ASK" and launch in Tower to be prompted.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
project:
|
||||
@ -112,7 +112,7 @@ options:
|
||||
ssh_key_unlock:
|
||||
description:
|
||||
- Unlock password for ssh_key.
|
||||
- Use "ASK" and launch in Tower to be prompted.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
authorize:
|
||||
@ -120,7 +120,6 @@ options:
|
||||
- Should use authorize for net type.
|
||||
- Deprecated, please use inputs
|
||||
type: bool
|
||||
default: 'no'
|
||||
authorize_password:
|
||||
description:
|
||||
- Password for net credentials that require authorize.
|
||||
@ -166,19 +165,19 @@ options:
|
||||
become_username:
|
||||
description:
|
||||
- Become username.
|
||||
- Use "ASK" and launch in Tower to be prompted.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
become_password:
|
||||
description:
|
||||
- Become password.
|
||||
- Use "ASK" and launch in Tower to be prompted.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
vault_password:
|
||||
description:
|
||||
- Vault password.
|
||||
- Use "ASK" and launch in Tower to be prompted.
|
||||
- Use "ASK" and launch job to be prompted.
|
||||
- Deprecated, please use inputs
|
||||
type: str
|
||||
vault_id:
|
||||
@ -203,17 +202,17 @@ notes:
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add tower machine credential
|
||||
tower_credential:
|
||||
- name: Add machine credential
|
||||
credential:
|
||||
name: Team Name
|
||||
description: Team Description
|
||||
organization: test-org
|
||||
credential_type: Machine
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Create a valid SCM credential from a private_key file
|
||||
tower_credential:
|
||||
credential:
|
||||
name: SCM Credential
|
||||
organization: Default
|
||||
state: present
|
||||
@ -229,8 +228,8 @@ EXAMPLES = '''
|
||||
src: '$HOME/.ssh/aws-private.pem'
|
||||
register: aws_ssh_key
|
||||
|
||||
- name: Add Credential Into Tower
|
||||
tower_credential:
|
||||
- name: Add Credential
|
||||
credential:
|
||||
name: Workshop Credential
|
||||
credential_type: Machine
|
||||
organization: Default
|
||||
@ -240,16 +239,16 @@ EXAMPLES = '''
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Add Credential with Custom Credential Type
|
||||
tower_credential:
|
||||
credential:
|
||||
name: Workshop Credential
|
||||
credential_type: MyCloudCredential
|
||||
organization: Default
|
||||
tower_username: admin
|
||||
tower_password: ansible
|
||||
tower_host: https://localhost
|
||||
controller_username: admin
|
||||
controller_password: ansible
|
||||
controller_host: https://localhost
|
||||
|
||||
- name: Create a Vaiult credential (example for notes)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: Example password
|
||||
credential_type: Vault
|
||||
organization: Default
|
||||
@ -258,7 +257,7 @@ EXAMPLES = '''
|
||||
vault_id: 'My ID'
|
||||
|
||||
- name: Bad password update (will replace vault_id)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: Example password
|
||||
credential_type: Vault
|
||||
organization: Default
|
||||
@ -266,14 +265,14 @@ EXAMPLES = '''
|
||||
vault_password: 'new_password'
|
||||
|
||||
- name: Another bad password update (will replace vault_id)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: Example password
|
||||
credential_type: Vault
|
||||
organization: Default
|
||||
vault_password: 'new_password'
|
||||
|
||||
- name: A safe way to update a password and keep vault_id
|
||||
tower_credential:
|
||||
credential:
|
||||
name: Example password
|
||||
credential_type: Vault
|
||||
organization: Default
|
||||
@ -282,14 +281,14 @@ EXAMPLES = '''
|
||||
vault_id: 'My ID'
|
||||
|
||||
- name: Copy Credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: Copy password
|
||||
copy_from: Example password
|
||||
credential_type: Vault
|
||||
organization: Foo
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
KIND_CHOICES = {
|
||||
'aws': 'Amazon Web Services',
|
||||
@ -363,7 +362,7 @@ def main():
|
||||
authorize=dict(type='bool'),
|
||||
authorize_password=dict(no_log=True),
|
||||
client=dict(),
|
||||
security_token=dict(),
|
||||
security_token=dict(no_log=False),
|
||||
secret=dict(no_log=True),
|
||||
subscription=dict(),
|
||||
tenant=dict(),
|
||||
@ -378,7 +377,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec, required_one_of=[['kind', 'credential_type']])
|
||||
module = ControllerAPIModule(argument_spec=argument_spec, required_one_of=[['kind', 'credential_type']])
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -395,12 +394,18 @@ def main():
|
||||
# End backwards compatability
|
||||
state = module.params.get('state')
|
||||
|
||||
# Deprication warnings
|
||||
# Deprecation warnings
|
||||
for legacy_input in OLD_INPUT_NAMES:
|
||||
if module.params.get(legacy_input) is not None:
|
||||
module.deprecate(msg='{0} parameter has been deprecated, please use inputs instead'.format(legacy_input), version="ansible.tower:4.0.0")
|
||||
module.deprecate(
|
||||
collection_name="awx.awx",
|
||||
msg='{0} parameter has been deprecated, please use inputs instead'.format(legacy_input),
|
||||
version="4.0.0")
|
||||
if kind:
|
||||
module.deprecate(msg='The kind parameter has been deprecated, please use credential_type instead', version="ansible.tower:4.0.0")
|
||||
module.deprecate(
|
||||
collection_name="awx.awx",
|
||||
msg='The kind parameter has been deprecated, please use credential_type instead',
|
||||
version="4.0.0")
|
||||
|
||||
cred_type_id = module.resolve_name_to_id('credential_types', credential_type if credential_type else KIND_CHOICES[kind])
|
||||
if organization:
|
||||
@ -14,12 +14,12 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_credential_input_source
|
||||
module: credential_input_source
|
||||
author: "Tom Page (@Tompage1994)"
|
||||
version_added: "2.3"
|
||||
short_description: create, update, or destroy Ansible Tower credential input sources.
|
||||
version_added: "2.3.0"
|
||||
short_description: create, update, or destroy Automation Platform Controller credential input sources.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower credential input sources. See
|
||||
- Create, update, or destroy Automation Platform Controller credential input sources. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
description:
|
||||
@ -58,7 +58,7 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Use CyberArk Lookup credential as password source
|
||||
tower_credential_input_source:
|
||||
credential_input_source:
|
||||
input_field_name: password
|
||||
target_credential: new_cred
|
||||
source_credential: cyberark_lookup
|
||||
@ -69,7 +69,7 @@ EXAMPLES = '''
|
||||
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -84,7 +84,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
description = module.params.get('description')
|
||||
@ -15,11 +15,11 @@ ANSIBLE_METADATA = {'status': ['preview'], 'supported_by': 'community', 'metadat
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_credential_type
|
||||
module: credential_type
|
||||
author: "Adrien Fleury (@fleu42)"
|
||||
short_description: Create, update, or destroy custom Ansible Tower credential type.
|
||||
short_description: Create, update, or destroy custom Automation Platform Controller credential type.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower credential type. See
|
||||
- Create, update, or destroy Automation Platform Controller credential type. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -42,14 +42,14 @@ options:
|
||||
inputs:
|
||||
description:
|
||||
- >-
|
||||
Enter inputs using either JSON or YAML syntax. Refer to the Ansible
|
||||
Tower documentation for example syntax.
|
||||
Enter inputs using either JSON or YAML syntax. Refer to the
|
||||
Automation Platform Controler documentation for example syntax.
|
||||
type: dict
|
||||
injectors:
|
||||
description:
|
||||
- >-
|
||||
Enter injectors using either JSON or YAML syntax. Refer to the
|
||||
Ansible Tower documentation for example syntax.
|
||||
Automation Platform Controller documentation for example syntax.
|
||||
type: dict
|
||||
state:
|
||||
description:
|
||||
@ -62,16 +62,16 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- tower_credential_type:
|
||||
- credential_type:
|
||||
name: Nexus
|
||||
description: Credentials type for Nexus
|
||||
kind: cloud
|
||||
inputs: "{{ lookup('file', 'tower_credential_inputs_nexus.json') }}"
|
||||
inputs: "{{ lookup('file', 'credential_inputs_nexus.json') }}"
|
||||
injectors: {'extra_vars': {'nexus_credential': 'test' }}
|
||||
state: present
|
||||
validate_certs: false
|
||||
|
||||
- tower_credential_type:
|
||||
- credential_type:
|
||||
name: Nexus
|
||||
state: absent
|
||||
'''
|
||||
@ -80,7 +80,7 @@ EXAMPLES = '''
|
||||
RETURN = ''' # '''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
KIND_CHOICES = {'ssh': 'Machine', 'vault': 'Ansible Vault', 'net': 'Network', 'scm': 'Source Control', 'cloud': 'Lots of others', 'insights': 'Insights'}
|
||||
|
||||
@ -97,7 +97,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_execution_environment
|
||||
module: execution_environment
|
||||
author: "Shane McDonald (@shanemcd)"
|
||||
short_description: create, update, or destroy Execution Environments in Ansible Tower.
|
||||
short_description: create, update, or destroy Execution Environments in Automation Platform Controller.
|
||||
description:
|
||||
- Create, update, or destroy Execution Environments in Ansible Tower. See
|
||||
- Create, update, or destroy Execution Environments in Automation Platform Controller. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -60,14 +60,14 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add EE to Tower
|
||||
tower_execution_environment:
|
||||
- name: Add EE to the controller instance
|
||||
execution_environment:
|
||||
name: "My EE"
|
||||
image: quay.io/ansible/awx-ee
|
||||
'''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
import json
|
||||
|
||||
|
||||
@ -84,7 +84,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,12 +14,12 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_export
|
||||
module: export
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
version_added: "3.7"
|
||||
short_description: export resources from Ansible Tower.
|
||||
version_added: "3.7.0"
|
||||
short_description: export resources from Automation Platform Controller.
|
||||
description:
|
||||
- Export assets from Ansible Tower.
|
||||
- Export assets from Automation Platform Controller.
|
||||
options:
|
||||
all:
|
||||
description:
|
||||
@ -82,16 +82,16 @@ extends_documentation_fragment: awx.awx.auth
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Export all tower assets
|
||||
tower_export:
|
||||
- name: Export all assets
|
||||
export:
|
||||
all: True
|
||||
|
||||
- name: Export all inventories
|
||||
tower_export:
|
||||
export:
|
||||
inventory: 'all'
|
||||
|
||||
- name: Export a job template named "My Template" and all Credentials
|
||||
tower_export:
|
||||
export:
|
||||
job_template: "My Template"
|
||||
credential: 'all'
|
||||
'''
|
||||
@ -99,7 +99,7 @@ EXAMPLES = '''
|
||||
from os import environ
|
||||
import logging
|
||||
from ansible.module_utils.six.moves import StringIO
|
||||
from ..module_utils.tower_awxkit import TowerAWXKitModule
|
||||
from ..module_utils.awxkit import ControllerAWXKitModule
|
||||
|
||||
try:
|
||||
from awxkit.api.pages.api import EXPORTABLE_RESOURCES
|
||||
@ -112,19 +112,31 @@ except ImportError:
|
||||
def main():
|
||||
argument_spec = dict(
|
||||
all=dict(type='bool', default=False),
|
||||
credential_types=dict(type='str'),
|
||||
credentials=dict(type='str'),
|
||||
execution_environments=dict(type='str'),
|
||||
inventory=dict(type='str'),
|
||||
inventory_sources=dict(type='str'),
|
||||
job_templates=dict(type='str'),
|
||||
notification_templates=dict(type='str'),
|
||||
organizations=dict(type='str'),
|
||||
projects=dict(type='str'),
|
||||
teams=dict(type='str'),
|
||||
users=dict(type='str'),
|
||||
workflow_job_templates=dict(type='str'),
|
||||
)
|
||||
|
||||
# We are not going to raise an error here because the __init__ method of TowerAWXKitModule will do that for us
|
||||
# We are not going to raise an error here because the __init__ method of ControllerAWXKitModule will do that for us
|
||||
if HAS_EXPORTABLE_RESOURCES:
|
||||
for resource in EXPORTABLE_RESOURCES:
|
||||
argument_spec[resource] = dict(type='str')
|
||||
|
||||
module = TowerAWXKitModule(argument_spec=argument_spec)
|
||||
module = ControllerAWXKitModule(argument_spec=argument_spec)
|
||||
|
||||
if not HAS_EXPORTABLE_RESOURCES:
|
||||
module.fail_json(msg="Your version of awxkit does not have import/export")
|
||||
|
||||
# The export process will never change a Tower system
|
||||
# The export process will never change the AWX system
|
||||
module.json_output['changed'] = False
|
||||
|
||||
# The exporter code currently works like the following:
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_group
|
||||
module: group
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower group.
|
||||
short_description: create, update, or destroy Automation Platform Controller group.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower groups. See
|
||||
- Create, update, or destroy Automation Platform Controller groups. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -53,12 +53,12 @@ options:
|
||||
- groups
|
||||
preserve_existing_hosts:
|
||||
description:
|
||||
- Provide option (False by default) to preserves existing hosts in an existing group in tower.
|
||||
- Provide option (False by default) to preserves existing hosts in an existing group.
|
||||
default: False
|
||||
type: bool
|
||||
preserve_existing_children:
|
||||
description:
|
||||
- Provide option (False by default) to preserves existing children in an existing group in tower.
|
||||
- Provide option (False by default) to preserves existing children in an existing group.
|
||||
default: False
|
||||
type: bool
|
||||
aliases:
|
||||
@ -78,16 +78,16 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add tower group
|
||||
tower_group:
|
||||
- name: Add group
|
||||
group:
|
||||
name: localhost
|
||||
description: "Local Host Group"
|
||||
inventory: "Local Inventory"
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add tower group
|
||||
tower_group:
|
||||
- name: Add group
|
||||
group:
|
||||
name: Cities
|
||||
description: "Local Host Group"
|
||||
inventory: Default Inventory
|
||||
@ -99,7 +99,7 @@ EXAMPLES = '''
|
||||
preserve_existing_children: True
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
import json
|
||||
|
||||
|
||||
@ -119,7 +119,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_host
|
||||
module: host
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower host.
|
||||
short_description: create, update, or destroy Automation Platform Controller host.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower hosts. See
|
||||
- Create, update, or destroy Automation Platform Controller hosts. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -59,19 +59,19 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add tower host
|
||||
tower_host:
|
||||
- name: Add host
|
||||
host:
|
||||
name: localhost
|
||||
description: "Local Host Group"
|
||||
inventory: "Local Inventory"
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
variables:
|
||||
example_var: 123
|
||||
'''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
import json
|
||||
|
||||
|
||||
@ -88,7 +88,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,18 +14,18 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_import
|
||||
module: import
|
||||
author: "John Westcott (@john-westcott-iv)"
|
||||
version_added: "3.7"
|
||||
short_description: import resources into Ansible Tower.
|
||||
version_added: "3.7.0"
|
||||
short_description: import resources into Automation Platform Controller.
|
||||
description:
|
||||
- Import assets into Ansible Tower. See
|
||||
- Import assets into Automation Platform Controller. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
assets:
|
||||
description:
|
||||
- The assets to import.
|
||||
- This can be the output of tower_export or loaded from a file
|
||||
- This can be the output of the export module or loaded from a file
|
||||
required: True
|
||||
type: dict
|
||||
requirements:
|
||||
@ -35,20 +35,20 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Export all assets
|
||||
tower_export:
|
||||
export:
|
||||
all: True
|
||||
register: export_output
|
||||
|
||||
- name: Import all tower assets from our export
|
||||
tower_import:
|
||||
- name: Import all assets from our export
|
||||
import:
|
||||
assets: "{{ export_output.assets }}"
|
||||
|
||||
- name: Load data from a json file created by a command like awx export --organization Default
|
||||
tower_import:
|
||||
import:
|
||||
assets: "{{ lookup('file', 'org.json') | from_json() }}"
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_awxkit import TowerAWXKitModule
|
||||
from ..module_utils.awxkit import ControllerAWXKitModule
|
||||
|
||||
# These two lines are not needed if awxkit changes to do programatic notifications on issues
|
||||
from ansible.module_utils.six.moves import StringIO
|
||||
@ -66,7 +66,7 @@ except ImportError:
|
||||
def main():
|
||||
argument_spec = dict(assets=dict(type='dict', required=True))
|
||||
|
||||
module = TowerAWXKitModule(argument_spec=argument_spec, supports_check_mode=False)
|
||||
module = ControllerAWXKitModule(argument_spec=argument_spec, supports_check_mode=False)
|
||||
|
||||
assets = module.params.get('assets')
|
||||
|
||||
@ -14,12 +14,12 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_instance_group
|
||||
module: instance_group
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
version_added: "4.0"
|
||||
short_description: create, update, or destroy Ansible Tower instance groups.
|
||||
version_added: "4.0.0"
|
||||
short_description: create, update, or destroy Automation Platform Controller instance groups.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower instance groups. See
|
||||
- Create, update, or destroy Automation Platform Controller instance groups. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -41,6 +41,7 @@ options:
|
||||
- Signifies that this InstanceGroup should act as a ContainerGroup. If no credential is specified, the underlying Pod's ServiceAccount will be used.
|
||||
required: False
|
||||
type: bool
|
||||
default: False
|
||||
policy_instance_percentage:
|
||||
description:
|
||||
- Minimum percentage of all instances that will be automatically assigned to this group when new instances come online.
|
||||
@ -58,6 +59,7 @@ options:
|
||||
- List of exact-match Instances that will be assigned to this group
|
||||
required: False
|
||||
type: list
|
||||
elements: str
|
||||
pod_spec_override:
|
||||
description:
|
||||
- A custom Kubernetes or OpenShift Pod specification.
|
||||
@ -68,6 +70,7 @@ options:
|
||||
- The instances associated with this instance_group
|
||||
required: False
|
||||
type: list
|
||||
elements: str
|
||||
state:
|
||||
description:
|
||||
- Desired state of the resource.
|
||||
@ -80,7 +83,7 @@ extends_documentation_fragment: awx.awx.auth
|
||||
EXAMPLES = '''
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -92,14 +95,14 @@ def main():
|
||||
is_container_group=dict(type='bool', default=False),
|
||||
policy_instance_percentage=dict(type='int', default='0'),
|
||||
policy_instance_minimum=dict(type='int', default='0'),
|
||||
policy_instance_list=dict(type='list'),
|
||||
policy_instance_list=dict(type='list', elements='str'),
|
||||
pod_spec_override=dict(),
|
||||
instances=dict(required=False, type="list", default=None),
|
||||
instances=dict(required=False, type="list", elements='str', default=None),
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_inventory
|
||||
module: inventory
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower inventory.
|
||||
short_description: create, update, or destroy Automation Platform Controller inventory.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower inventories. See
|
||||
- Create, update, or destroy Automation Platform Controller inventories. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -77,16 +77,16 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add tower inventory
|
||||
tower_inventory:
|
||||
- name: Add inventory
|
||||
inventory:
|
||||
name: "Foo Inventory"
|
||||
description: "Our Foo Cloud Servers"
|
||||
organization: "Bar Org"
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Copy tower inventory
|
||||
tower_inventory:
|
||||
- name: Copy inventory
|
||||
inventory:
|
||||
name: Copy Foo Inventory
|
||||
copy_from: Default Inventory
|
||||
description: "Our Foo Cloud Servers"
|
||||
@ -95,7 +95,7 @@ EXAMPLES = '''
|
||||
'''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
import json
|
||||
|
||||
|
||||
@ -115,7 +115,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_inventory_source
|
||||
module: inventory_source
|
||||
author: "Adrien Fleury (@fleu42)"
|
||||
short_description: create, update, or destroy Ansible Tower inventory source.
|
||||
short_description: create, update, or destroy Automation Platform Controller inventory source.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower inventory source. See
|
||||
- Create, update, or destroy Automation Platform Controller inventory source. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -138,7 +138,7 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add an inventory source
|
||||
tower_inventory_source:
|
||||
inventory_source:
|
||||
name: "source-inventory"
|
||||
description: Source for inventory
|
||||
inventory: previously-created-inventory
|
||||
@ -150,7 +150,7 @@ EXAMPLES = '''
|
||||
private: false
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
from json import dumps
|
||||
|
||||
|
||||
@ -162,7 +162,7 @@ def main():
|
||||
description=dict(),
|
||||
inventory=dict(required=True),
|
||||
#
|
||||
# How do we handle manual and file? Tower does not seem to be able to activate them
|
||||
# How do we handle manual and file? The controller does not seem to be able to activate them
|
||||
#
|
||||
source=dict(choices=["scm", "ec2", "gce", "azure_rm", "vmware", "satellite6", "openstack", "rhv", "tower"]),
|
||||
source_path=dict(),
|
||||
@ -189,7 +189,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_inventory_source_update
|
||||
module: inventory_source_update
|
||||
author: "Bianca Henderson (@beeankha)"
|
||||
short_description: Update inventory source(s).
|
||||
description:
|
||||
- Update Ansible Tower inventory source(s). See
|
||||
- Update Automation Platform Controller inventory source(s). See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -44,7 +44,7 @@ options:
|
||||
type: bool
|
||||
interval:
|
||||
description:
|
||||
- The interval to request an update from Tower.
|
||||
- The interval to request an update from the controller.
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
@ -58,16 +58,16 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Update a single inventory source
|
||||
tower_inventory_source_update:
|
||||
inventory_source_update:
|
||||
name: "Example Inventory Source"
|
||||
inventory: "My Inventory"
|
||||
organization: Default
|
||||
|
||||
- name: Update all inventory sources
|
||||
tower_inventory_source_update:
|
||||
inventory_source_update:
|
||||
name: "{{ item }}"
|
||||
inventory: "My Other Inventory"
|
||||
loop: "{{ query('awx.awx.tower_api', 'inventory_sources', query_params={ 'inventory': 30 }, return_ids=True ) }}"
|
||||
loop: "{{ query('awx.awx.controller_api', 'inventory_sources', query_params={ 'inventory': 30 }, return_ids=True ) }}"
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
@ -83,7 +83,7 @@ status:
|
||||
sample: pending
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -98,7 +98,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_job_cancel
|
||||
module: job_cancel
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: Cancel an Ansible Tower Job.
|
||||
short_description: Cancel an Automation Platform Controller Job.
|
||||
description:
|
||||
- Cancel Ansible Tower jobs. See
|
||||
- Cancel Automation Platform Controller jobs. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
job_id:
|
||||
@ -36,7 +36,7 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Cancel job
|
||||
tower_job_cancel:
|
||||
job_cancel:
|
||||
job_id: job.id
|
||||
'''
|
||||
|
||||
@ -49,7 +49,7 @@ id:
|
||||
'''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -60,7 +60,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
job_id = module.params.get('job_id')
|
||||
@ -81,7 +81,7 @@ def main():
|
||||
|
||||
cancel_page = module.get_endpoint(job['related']['cancel'])
|
||||
if 'json' not in cancel_page or 'can_cancel' not in cancel_page['json']:
|
||||
module.fail_json(msg="Failed to cancel job, got unexpected response from tower", **{'response': cancel_page})
|
||||
module.fail_json(msg="Failed to cancel job, got unexpected response from the controller", **{'response': cancel_page})
|
||||
|
||||
if not cancel_page['json']['can_cancel']:
|
||||
if fail_if_not_running:
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_job_launch
|
||||
module: job_launch
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: Launch an Ansible Job.
|
||||
description:
|
||||
- Launch an Ansible Tower jobs. See
|
||||
- Launch an Automation Platform Controller jobs. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -51,7 +51,7 @@ options:
|
||||
extra_vars:
|
||||
description:
|
||||
- extra_vars to use for the Job Template.
|
||||
- ask_extra_vars needs to be set to True via tower_job_template module
|
||||
- ask_extra_vars needs to be set to True via job_template module
|
||||
when creating the Job Template.
|
||||
type: dict
|
||||
limit:
|
||||
@ -93,7 +93,7 @@ options:
|
||||
type: bool
|
||||
interval:
|
||||
description:
|
||||
- The interval to request an update from Tower.
|
||||
- The interval to request an update from the controller.
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
@ -107,12 +107,12 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Launch a job
|
||||
tower_job_launch:
|
||||
job_launch:
|
||||
job_template: "My Job Template"
|
||||
register: job
|
||||
|
||||
- name: Launch a job template with extra_vars on remote Tower instance
|
||||
tower_job_launch:
|
||||
- name: Launch a job template with extra_vars on remote controller instance
|
||||
job_launch:
|
||||
job_template: "My Job Template"
|
||||
extra_vars:
|
||||
var1: "My First Variable"
|
||||
@ -121,13 +121,13 @@ EXAMPLES = '''
|
||||
job_type: run
|
||||
|
||||
- name: Launch a job with inventory and credential
|
||||
tower_job_launch:
|
||||
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_wait:
|
||||
job_id: "{{ job.id }}"
|
||||
timeout: 120
|
||||
'''
|
||||
@ -145,7 +145,7 @@ status:
|
||||
sample: pending
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -164,14 +164,14 @@ def main():
|
||||
skip_tags=dict(type='list', elements='str'),
|
||||
verbosity=dict(type='int', choices=[0, 1, 2, 3, 4, 5]),
|
||||
diff_mode=dict(type='bool'),
|
||||
credential_passwords=dict(type='dict'),
|
||||
credential_passwords=dict(type='dict', no_log=False),
|
||||
wait=dict(default=False, type='bool'),
|
||||
interval=dict(default=1.0, type='float'),
|
||||
timeout=dict(default=None, type='int'),
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
optional_args = {}
|
||||
# Extract our parameters
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_job_list
|
||||
module: job_list
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: List Ansible Tower jobs.
|
||||
short_description: List Automation Platform Controller jobs.
|
||||
description:
|
||||
- List Ansible Tower jobs. See
|
||||
- List Automation Platform Controller jobs. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
status:
|
||||
@ -45,10 +45,10 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: List running jobs for the testing.yml playbook
|
||||
tower_job_list:
|
||||
job_list:
|
||||
status: running
|
||||
query: {"playbook": "testing.yml"}
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
register: testing_jobs
|
||||
'''
|
||||
|
||||
@ -79,7 +79,7 @@ results:
|
||||
'''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -92,7 +92,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(
|
||||
module = ControllerAPIModule(
|
||||
argument_spec=argument_spec,
|
||||
mutually_exclusive=[
|
||||
('page', 'all_pages'),
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_job_template
|
||||
module: job_template
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower job templates.
|
||||
short_description: create, update, or destroy Automation Platform Controller job templates.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower job templates. See
|
||||
- Create, update, or destroy Automation Platform Controller job templates. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -57,7 +57,7 @@ options:
|
||||
- Used to help lookup the object, cannot be modified using this module.
|
||||
- The Organization is inferred from the associated project
|
||||
- If not provided, will lookup by name only, which does not work with duplicates.
|
||||
- Requires Tower Version 3.7.0 or AWX 10.0.0 IS NOT backwards compatible with earlier versions.
|
||||
- Requires Automation Platform Version 3.7.0 or AWX 10.0.0 IS NOT backwards compatible with earlier versions.
|
||||
type: str
|
||||
project:
|
||||
description:
|
||||
@ -140,12 +140,10 @@ options:
|
||||
type: bool
|
||||
aliases:
|
||||
- diff_mode_enabled
|
||||
default: 'no'
|
||||
use_fact_cache:
|
||||
description:
|
||||
- Enable use of fact caching for the job template.
|
||||
type: bool
|
||||
default: 'no'
|
||||
aliases:
|
||||
- fact_caching_enabled
|
||||
host_config_key:
|
||||
@ -156,75 +154,64 @@ options:
|
||||
description:
|
||||
- Prompt user for (scm branch) on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
ask_diff_mode_on_launch:
|
||||
description:
|
||||
- Prompt user to enable diff mode (show changes) to files when supported by modules.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_diff_mode
|
||||
ask_variables_on_launch:
|
||||
description:
|
||||
- Prompt user for (extra_vars) on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_extra_vars
|
||||
ask_limit_on_launch:
|
||||
description:
|
||||
- Prompt user for a limit on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_limit
|
||||
ask_tags_on_launch:
|
||||
description:
|
||||
- Prompt user for job tags on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_tags
|
||||
ask_skip_tags_on_launch:
|
||||
description:
|
||||
- Prompt user for job tags to skip on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_skip_tags
|
||||
ask_job_type_on_launch:
|
||||
description:
|
||||
- Prompt user for job type on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_job_type
|
||||
ask_verbosity_on_launch:
|
||||
description:
|
||||
- Prompt user to choose a verbosity level on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_verbosity
|
||||
ask_inventory_on_launch:
|
||||
description:
|
||||
- Prompt user for inventory on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_inventory
|
||||
ask_credential_on_launch:
|
||||
description:
|
||||
- Prompt user for credential on launch.
|
||||
type: bool
|
||||
default: 'False'
|
||||
aliases:
|
||||
- ask_credential
|
||||
survey_enabled:
|
||||
description:
|
||||
- Enable a survey on the job template.
|
||||
type: bool
|
||||
default: 'no'
|
||||
survey_spec:
|
||||
description:
|
||||
- JSON/YAML dict formatted survey definition.
|
||||
@ -233,12 +220,10 @@ options:
|
||||
description:
|
||||
- Activate privilege escalation.
|
||||
type: bool
|
||||
default: 'no'
|
||||
allow_simultaneous:
|
||||
description:
|
||||
- Allow simultaneous runs of the job template.
|
||||
type: bool
|
||||
default: 'no'
|
||||
aliases:
|
||||
- concurrent_jobs_enabled
|
||||
timeout:
|
||||
@ -297,15 +282,15 @@ options:
|
||||
extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
notes:
|
||||
- JSON for survey_spec can be found in Tower API Documentation. See
|
||||
- JSON for survey_spec can be found in the 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.
|
||||
'''
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Create Tower Ping job template
|
||||
tower_job_template:
|
||||
- name: Create Ping job template
|
||||
job_template:
|
||||
name: "Ping"
|
||||
job_type: "run"
|
||||
organization: "Default"
|
||||
@ -315,25 +300,25 @@ EXAMPLES = '''
|
||||
credentials:
|
||||
- "Local"
|
||||
state: "present"
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
survey_enabled: yes
|
||||
survey_spec: "{{ lookup('file', 'my_survey.json') }}"
|
||||
|
||||
- name: Add start notification to Job Template
|
||||
tower_job_template:
|
||||
job_template:
|
||||
name: "Ping"
|
||||
notification_templates_started:
|
||||
- Notification1
|
||||
- Notification2
|
||||
|
||||
- name: Remove Notification1 start notification from Job Template
|
||||
tower_job_template:
|
||||
job_template:
|
||||
name: "Ping"
|
||||
notification_templates_started:
|
||||
- Notification2
|
||||
|
||||
- name: Copy Job Template
|
||||
tower_job_template:
|
||||
job_template:
|
||||
name: copy job template
|
||||
copy_from: test job template
|
||||
job_type: "run"
|
||||
@ -343,7 +328,7 @@ EXAMPLES = '''
|
||||
state: "present"
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
import json
|
||||
|
||||
|
||||
@ -389,7 +374,7 @@ def main():
|
||||
start_at_task=dict(),
|
||||
timeout=dict(type='int', default=0),
|
||||
use_fact_cache=dict(type='bool', aliases=['fact_caching_enabled']),
|
||||
host_config_key=dict(),
|
||||
host_config_key=dict(no_log=False),
|
||||
ask_diff_mode_on_launch=dict(type='bool', aliases=['ask_diff_mode']),
|
||||
ask_variables_on_launch=dict(type='bool', aliases=['ask_extra_vars']),
|
||||
ask_limit_on_launch=dict(type='bool', aliases=['ask_limit']),
|
||||
@ -417,7 +402,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -534,7 +519,7 @@ def main():
|
||||
}
|
||||
)
|
||||
if project_data is None:
|
||||
module.fail_json(msg="The project {0} in organization {1} was not found on the Tower server".format(project, organization))
|
||||
module.fail_json(msg="The project {0} in organization {1} was not found on the controller instance server".format(project, organization))
|
||||
new_fields['project'] = project_data['id']
|
||||
else:
|
||||
new_fields['project'] = module.resolve_name_to_id('projects', project)
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_job_wait
|
||||
module: job_wait
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: Wait for Ansible Tower job to finish.
|
||||
short_description: Wait for Automation Platform Controller job to finish.
|
||||
description:
|
||||
- Wait for Ansible Tower job to finish and report success or failure. See
|
||||
- Wait for Automation Platform Controller job to finish and report success or failure. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
job_id:
|
||||
@ -28,19 +28,19 @@ options:
|
||||
type: int
|
||||
interval:
|
||||
description:
|
||||
- The interval in sections, to request an update from Tower.
|
||||
- The interval in sections, to request an update from the controller.
|
||||
- For backwards compatibility if unset this will be set to the average of min and max intervals
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
min_interval:
|
||||
description:
|
||||
- Minimum interval in seconds, to request an update from Tower.
|
||||
- Minimum interval in seconds, to request an update from the controller.
|
||||
- deprecated, use interval instead
|
||||
type: float
|
||||
max_interval:
|
||||
description:
|
||||
- Maximum interval in seconds, to request an update from Tower.
|
||||
- Maximum interval in seconds, to request an update from the controller.
|
||||
- deprecated, use interval instead
|
||||
type: float
|
||||
timeout:
|
||||
@ -58,12 +58,12 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Launch a job
|
||||
tower_job_launch:
|
||||
job_launch:
|
||||
job_template: "My Job Template"
|
||||
register: job
|
||||
|
||||
- name: Wait for job max 120s
|
||||
tower_job_wait:
|
||||
job_wait:
|
||||
job_id: "{{ job.id }}"
|
||||
timeout: 120
|
||||
'''
|
||||
@ -97,7 +97,7 @@ status:
|
||||
'''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -112,7 +112,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
job_id = module.params.get('job_id')
|
||||
@ -132,8 +132,9 @@ def main():
|
||||
max_interval = 30
|
||||
interval = abs((min_interval + max_interval) / 2)
|
||||
module.deprecate(
|
||||
collection_name="awx.awx",
|
||||
msg="Min and max interval have been deprecated, please use interval instead; interval will be set to {0}".format(interval),
|
||||
version="ansible.tower:4.0.0",
|
||||
version="4.0.0",
|
||||
)
|
||||
|
||||
# Attempt to look up job based on the provided id
|
||||
@ -147,7 +148,7 @@ def main():
|
||||
)
|
||||
|
||||
if job is None:
|
||||
module.fail_json(msg='Unable to wait on ' + job_type.rstrip("s") + ' {0}; that ID does not exist in Tower.'.format(job_id))
|
||||
module.fail_json(msg='Unable to wait on ' + job_type.rstrip("s") + ' {0}; that ID does not exist.'.format(job_id))
|
||||
|
||||
# Invoke wait function
|
||||
result = module.wait_on_url(url=job['url'], object_name=job_id, object_type='legacy_job_wait', timeout=timeout, interval=interval)
|
||||
@ -14,13 +14,13 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_label
|
||||
module: label
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower labels.
|
||||
short_description: create, update, or destroy Automation Platform Controller labels.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower labels. See
|
||||
- Create, update, or destroy Automation Platform Controller labels. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
- Note, labels can only be created via the Tower API, they can not be deleted.
|
||||
- Note, labels can only be created via the API, they can not be deleted.
|
||||
Once they are fully disassociated the API will clean them up on its own.
|
||||
options:
|
||||
name:
|
||||
@ -47,13 +47,13 @@ extends_documentation_fragment: awx.awx.auth
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add label to tower organization
|
||||
tower_label:
|
||||
- name: Add label to organization
|
||||
label:
|
||||
name: Custom Label
|
||||
organization: My Organization
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -66,7 +66,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -13,11 +13,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_license
|
||||
module: license
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
short_description: Set the license for Ansible Tower
|
||||
short_description: Set the license for Automation Platform Controller
|
||||
description:
|
||||
- Get or Set Ansible Tower license. See
|
||||
- Get or Set Automation Platform Controller license. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
manifest:
|
||||
@ -29,7 +29,6 @@ options:
|
||||
description:
|
||||
- By default, the license manifest will only be applied if Tower is currently
|
||||
unlicensed or trial licensed. When force=true, the license is always applied.
|
||||
required: True
|
||||
type: bool
|
||||
default: 'False'
|
||||
extends_documentation_fragment: awx.awx.auth
|
||||
@ -39,20 +38,20 @@ RETURN = ''' # '''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Set the license using a file
|
||||
tower_license:
|
||||
license:
|
||||
manifest: "/tmp/my_manifest.zip"
|
||||
'''
|
||||
|
||||
import base64
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
module = TowerAPIModule(
|
||||
module = ControllerAPIModule(
|
||||
argument_spec=dict(
|
||||
manifest=dict(type='str', required=True),
|
||||
force=dict(type='bool', required=False),
|
||||
force=dict(type='bool', default=False),
|
||||
),
|
||||
)
|
||||
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_notification_template
|
||||
module: notification_template
|
||||
author: "Samuel Carpentier (@samcarpentier)"
|
||||
short_description: create, update, or destroy Ansible Tower notification.
|
||||
short_description: create, update, or destroy Automation Platform Controller notification.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower notifications. See
|
||||
- Create, update, or destroy Automation Platform Controller notifications. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -210,7 +210,7 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add Slack notification with custom messages
|
||||
tower_notification_template:
|
||||
notification_template:
|
||||
name: slack notification
|
||||
organization: Default
|
||||
notification_type: slack
|
||||
@ -226,10 +226,10 @@ EXAMPLES = '''
|
||||
error:
|
||||
message: "{{ '{{ job_friendly_name }} FAILED! Please look at {{ job.url }}' }}"
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add webhook notification
|
||||
tower_notification_template:
|
||||
notification_template:
|
||||
name: webhook notification
|
||||
notification_type: webhook
|
||||
notification_configuration:
|
||||
@ -237,16 +237,16 @@ EXAMPLES = '''
|
||||
headers:
|
||||
X-Custom-Header: value123
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add email notification
|
||||
tower_notification_template:
|
||||
notification_template:
|
||||
name: email notification
|
||||
notification_type: email
|
||||
notification_configuration:
|
||||
username: user
|
||||
password: s3cr3t
|
||||
sender: tower@example.com
|
||||
sender: controller@example.com
|
||||
recipients:
|
||||
- user1@example.com
|
||||
host: smtp.example.com
|
||||
@ -254,10 +254,10 @@ EXAMPLES = '''
|
||||
use_tls: no
|
||||
use_ssl: no
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add twilio notification
|
||||
tower_notification_template:
|
||||
notification_template:
|
||||
name: twilio notification
|
||||
notification_type: twilio
|
||||
notification_configuration:
|
||||
@ -267,10 +267,10 @@ EXAMPLES = '''
|
||||
to_numbers:
|
||||
- '+15553334444'
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add PagerDuty notification
|
||||
tower_notification_template:
|
||||
notification_template:
|
||||
name: pagerduty notification
|
||||
notification_type: pagerduty
|
||||
notification_configuration:
|
||||
@ -279,14 +279,14 @@ EXAMPLES = '''
|
||||
client_name: client
|
||||
service_key: a_key
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add IRC notification
|
||||
tower_notification_template:
|
||||
notification_template:
|
||||
name: irc notification
|
||||
notification_type: irc
|
||||
notification_configuration:
|
||||
nickname: tower
|
||||
nickname: controller
|
||||
password: s3cr3t
|
||||
targets:
|
||||
- user1
|
||||
@ -294,16 +294,16 @@ EXAMPLES = '''
|
||||
server: irc.example.com
|
||||
use_ssl: no
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Delete notification
|
||||
tower_notification_template:
|
||||
notification_template:
|
||||
name: old notification
|
||||
state: absent
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Copy webhook notification
|
||||
tower_notification_template:
|
||||
notification_template:
|
||||
name: foo notification
|
||||
copy_from: email notification
|
||||
organization: Foo
|
||||
@ -313,7 +313,7 @@ EXAMPLES = '''
|
||||
RETURN = ''' # '''
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
OLD_INPUT_NAMES = (
|
||||
'username',
|
||||
@ -384,7 +384,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -401,7 +401,9 @@ def main():
|
||||
for legacy_input in OLD_INPUT_NAMES:
|
||||
if module.params.get(legacy_input) is not None:
|
||||
module.deprecate(
|
||||
msg='{0} parameter has been deprecated, please use notification_configuration instead'.format(legacy_input), version="ansible.tower:4.0.0"
|
||||
collection_name="awx.awx",
|
||||
msg='{0} parameter has been deprecated, please use notification_configuration instead'.format(legacy_input),
|
||||
version="4.0.0"
|
||||
)
|
||||
|
||||
# Attempt to look up the related items the user specified (these will fail the module if not found)
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_organization
|
||||
module: organization
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower organizations
|
||||
short_description: create, update, or destroy Automation Platform Controller organizations
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower organizations. See
|
||||
- Create, update, or destroy Automation Platform Controller organizations. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -86,30 +86,30 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Create tower organization
|
||||
tower_organization:
|
||||
- name: Create organization
|
||||
organization:
|
||||
name: "Foo"
|
||||
description: "Foo bar organization"
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Create tower organization using 'foo-venv' as default Python virtualenv
|
||||
tower_organization:
|
||||
- name: Create organization using 'foo-venv' as default Python virtualenv
|
||||
organization:
|
||||
name: "Foo"
|
||||
description: "Foo bar organization using foo-venv"
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Create tower organization that pulls content from galaxy.ansible.com
|
||||
tower_organization:
|
||||
- name: Create organization that pulls content from galaxy.ansible.com
|
||||
organization:
|
||||
name: "Foo"
|
||||
state: present
|
||||
galaxy_credentials:
|
||||
- Ansible Galaxy
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -130,7 +130,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_project
|
||||
module: project
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower projects
|
||||
short_description: create, update, or destroy Automation Platform Controller projects
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower projects. See
|
||||
- Create, update, or destroy Automation Platform Controller projects. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -160,7 +160,7 @@ options:
|
||||
type: bool
|
||||
interval:
|
||||
description:
|
||||
- The interval to request an update from Tower.
|
||||
- The interval to request an update from the controller.
|
||||
- Requires wait.
|
||||
required: False
|
||||
default: 1
|
||||
@ -170,26 +170,26 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add tower project
|
||||
tower_project:
|
||||
- name: Add project
|
||||
project:
|
||||
name: "Foo"
|
||||
description: "Foo bar project"
|
||||
organization: "test"
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add Tower Project with cache timeout
|
||||
tower_project:
|
||||
- name: Add Project with cache timeout
|
||||
project:
|
||||
name: "Foo"
|
||||
description: "Foo bar project"
|
||||
organization: "test"
|
||||
scm_update_on_launch: True
|
||||
scm_update_cache_timeout: 60
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Copy tower project
|
||||
tower_project:
|
||||
- name: Copy project
|
||||
project:
|
||||
name: copy
|
||||
copy_from: test
|
||||
description: Foo copy project
|
||||
@ -199,7 +199,7 @@ EXAMPLES = '''
|
||||
|
||||
import time
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def wait_for_project_update(module, last_request):
|
||||
@ -280,7 +280,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -11,11 +11,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.0', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_project_update
|
||||
module: project_update
|
||||
author: "Sean Sullivan (@sean-m-sullivan)"
|
||||
short_description: Update a Project in Ansible Tower
|
||||
short_description: Update a Project in Automation Platform Controller
|
||||
description:
|
||||
- Update a Ansible Tower Project. See
|
||||
- Update a Automation Platform Controller Project. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -39,7 +39,7 @@ options:
|
||||
type: bool
|
||||
interval:
|
||||
description:
|
||||
- The interval to request an update from Tower.
|
||||
- The interval to request an update from the controller.
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
@ -67,17 +67,17 @@ status:
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Launch a project with a timeout of 10 seconds
|
||||
tower_project_update:
|
||||
project_update:
|
||||
project: "Networking Project"
|
||||
timeout: 10
|
||||
|
||||
- name: Launch a Project with extra_vars without waiting
|
||||
tower_project_update:
|
||||
project_update:
|
||||
project: "Networking Project"
|
||||
wait: False
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
import json
|
||||
import time
|
||||
|
||||
@ -93,7 +93,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,12 +14,12 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_role
|
||||
module: role
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: grant or revoke an Ansible Tower role.
|
||||
short_description: grant or revoke an Automation Platform Controller role.
|
||||
description:
|
||||
- Roles are used for access control, this module is for managing user access to server resources.
|
||||
- Grant or revoke Ansible Tower roles to users. See U(https://www.ansible.com/tower) for an overview.
|
||||
- Grant or revoke Automation Platform Controller roles to users. See U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
user:
|
||||
description:
|
||||
@ -131,14 +131,14 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add jdoe to the member role of My Team
|
||||
tower_role:
|
||||
role:
|
||||
user: jdoe
|
||||
target_team: "My Team"
|
||||
role: member
|
||||
state: present
|
||||
|
||||
- name: Add Joe to multiple job templates and a workflow
|
||||
tower_role:
|
||||
role:
|
||||
user: joe
|
||||
role: execute
|
||||
workflow: test-role-workflow
|
||||
@ -148,7 +148,7 @@ EXAMPLES = '''
|
||||
state: present
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -194,7 +194,7 @@ def main():
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
)
|
||||
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
role_type = module.params.pop('role')
|
||||
role_field = role_type + '_role'
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_schedule
|
||||
module: schedule
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
short_description: create, update, or destroy Ansible Tower schedules.
|
||||
short_description: create, update, or destroy Automation Platform Controller schedules.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower schedules. See
|
||||
- Create, update, or destroy Automation Platform Controller schedules. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
rrule:
|
||||
@ -119,7 +119,7 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Build a schedule for Demo Job Template
|
||||
tower_schedule:
|
||||
schedule:
|
||||
name: "{{ sched1 }}"
|
||||
state: present
|
||||
unified_job_template: "Demo Job Template"
|
||||
@ -127,15 +127,15 @@ EXAMPLES = '''
|
||||
register: result
|
||||
|
||||
- name: Build the same schedule using the rrule plugin
|
||||
tower_schedule:
|
||||
schedule:
|
||||
name: "{{ sched1 }}"
|
||||
state: present
|
||||
unified_job_template: "Demo Job Template"
|
||||
rrule: "{{ query('awx.awx.tower_schedule_rrule', 'week', start_date='2019-12-19 13:05:51') }}"
|
||||
rrule: "{{ query('awx.awx.schedule_rrule', 'week', start_date='2019-12-19 13:05:51') }}"
|
||||
register: result
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -160,7 +160,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
rrule = module.params.get('rrule')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_settings
|
||||
module: settings
|
||||
author: "Nikhil Jain (@jainnikhil30)"
|
||||
short_description: Modify Ansible Tower settings.
|
||||
short_description: Modify Automation Platform Controller settings.
|
||||
description:
|
||||
- Modify Ansible Tower settings. See
|
||||
- Modify Automation Platform Controller settings. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -42,25 +42,25 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Set the value of AWX_ISOLATION_BASE_PATH
|
||||
tower_settings:
|
||||
settings:
|
||||
name: AWX_ISOLATION_BASE_PATH
|
||||
value: "/tmp"
|
||||
register: testing_settings
|
||||
|
||||
- name: Set the value of AWX_ISOLATION_SHOW_PATHS
|
||||
tower_settings:
|
||||
settings:
|
||||
name: "AWX_ISOLATION_SHOW_PATHS"
|
||||
value: "'/var/lib/awx/projects/', '/tmp'"
|
||||
register: testing_settings
|
||||
|
||||
- name: Set the LDAP Auth Bind Password
|
||||
tower_settings:
|
||||
settings:
|
||||
name: "AUTH_LDAP_BIND_PASSWORD"
|
||||
value: "Password"
|
||||
no_log: true
|
||||
|
||||
- name: Set all the LDAP Auth Bind Params
|
||||
tower_settings:
|
||||
settings:
|
||||
settings:
|
||||
AUTH_LDAP_BIND_PASSWORD: "password"
|
||||
AUTH_LDAP_USER_ATTR_MAP:
|
||||
@ -69,7 +69,7 @@ EXAMPLES = '''
|
||||
last_name: "surname"
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
try:
|
||||
import yaml
|
||||
@ -107,7 +107,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(
|
||||
module = ControllerAPIModule(
|
||||
argument_spec=argument_spec,
|
||||
required_one_of=[['name', 'settings']],
|
||||
mutually_exclusive=[['name', 'settings']],
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_team
|
||||
module: team
|
||||
author: "Wayne Witzel III (@wwitzel3)"
|
||||
short_description: create, update, or destroy Ansible Tower team.
|
||||
short_description: create, update, or destroy Automation Platform Controller team.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower teams. See
|
||||
- Create, update, or destroy Automation Platform Controller teams. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -50,16 +50,16 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Create tower team
|
||||
tower_team:
|
||||
- name: Create team
|
||||
team:
|
||||
name: Team Name
|
||||
description: Team Description
|
||||
organization: test-org
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -73,7 +73,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,18 +14,18 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_token
|
||||
module: token
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
version_added: "2.3"
|
||||
short_description: create, update, or destroy Ansible Tower tokens.
|
||||
version_added: "2.3.0"
|
||||
short_description: create, update, or destroy Automation Platform Controller tokens.
|
||||
description:
|
||||
- Create or destroy Ansible Tower tokens. See
|
||||
- Create or destroy Automation Platform Controller tokens. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
- In addition, the module sets an Ansible fact which can be passed into other
|
||||
tower_* modules as the parameter tower_oauthtoken. See examples for usage.
|
||||
controller modules as the parameter controller_oauthtoken. See examples for usage.
|
||||
- Because of the sensitive nature of tokens, the created token value is only available once
|
||||
through the Ansible fact. (See RETURN for details)
|
||||
- Due to the nature of tokens in Tower this module is not idempotent. A second will
|
||||
- Due to the nature of tokens this module is not idempotent. A second will
|
||||
with the same parameters will create a new token.
|
||||
- If you are creating a temporary token for use with modules you should delete the token
|
||||
when you are done with it. See the example for how to do it.
|
||||
@ -49,7 +49,7 @@ options:
|
||||
default: 'write'
|
||||
choices: ["read", "write"]
|
||||
existing_token:
|
||||
description: The data structure produced from tower_token in create mode to be used with state absent.
|
||||
description: The data structure produced from token in create mode to be used with state absent.
|
||||
type: dict
|
||||
existing_token_id:
|
||||
description: A token ID (number) which can be used to delete an arbitrary token with state absent.
|
||||
@ -66,38 +66,38 @@ extends_documentation_fragment: awx.awx.auth
|
||||
EXAMPLES = '''
|
||||
- block:
|
||||
- name: Create a new token using an existing token
|
||||
tower_token:
|
||||
token:
|
||||
description: '{{ token_description }}'
|
||||
scope: "write"
|
||||
state: present
|
||||
tower_oauthtoken: "{{ my_existing_token }}"
|
||||
controller_oauthtoken: "{{ my_existing_token }}"
|
||||
|
||||
- name: Delete this token
|
||||
tower_token:
|
||||
existing_token: "{{ tower_token }}"
|
||||
token:
|
||||
existing_token: "{{ token }}"
|
||||
state: absent
|
||||
|
||||
- name: Create a new token using username/password
|
||||
tower_token:
|
||||
token:
|
||||
description: '{{ token_description }}'
|
||||
scope: "write"
|
||||
state: present
|
||||
tower_username: "{{ my_username }}"
|
||||
tower_password: "{{ my_password }}"
|
||||
controller_username: "{{ my_username }}"
|
||||
controller_password: "{{ my_password }}"
|
||||
|
||||
- name: Use our new token to make another call
|
||||
tower_job_list:
|
||||
tower_oauthtoken: "{{ tower_token }}"
|
||||
job_list:
|
||||
controller_oauthtoken: "{{ token }}"
|
||||
|
||||
always:
|
||||
- name: Delete our Token with the token we created
|
||||
tower_token:
|
||||
existing_token: "{{ tower_token }}"
|
||||
token:
|
||||
existing_token: "{{ token }}"
|
||||
state: absent
|
||||
when: tower_token is defined
|
||||
when: token is defined
|
||||
|
||||
- name: Delete a token by its id
|
||||
tower_token:
|
||||
token:
|
||||
existing_token_id: 4
|
||||
state: absent
|
||||
'''
|
||||
@ -105,7 +105,7 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
tower_token:
|
||||
type: dict
|
||||
description: An Ansible Fact variable representing a Tower token object which can be used for auth in subsequent modules. See examples for usage.
|
||||
description: An Ansible Fact variable representing a token object which can be used for auth in subsequent modules. See examples for usage.
|
||||
contains:
|
||||
token:
|
||||
description: The token that was generated. This token can never be accessed again, make sure this value is noted before it is lost.
|
||||
@ -116,7 +116,7 @@ tower_token:
|
||||
returned: on successful create
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def return_token(module, last_response):
|
||||
@ -136,13 +136,13 @@ def main():
|
||||
description=dict(),
|
||||
application=dict(),
|
||||
scope=dict(choices=['read', 'write'], default='write'),
|
||||
existing_token=dict(type='dict'),
|
||||
existing_token=dict(type='dict', no_log=False),
|
||||
existing_token_id=dict(),
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(
|
||||
module = ControllerAPIModule(
|
||||
argument_spec=argument_spec,
|
||||
mutually_exclusive=[
|
||||
('existing_token', 'existing_token_id'),
|
||||
@ -1,192 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8 -*-
|
||||
|
||||
# (c) 2017, John Westcott IV <john.westcott.iv@redhat.com>
|
||||
# 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': ['deprecated'], 'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_receive
|
||||
deprecated:
|
||||
removed_in: "14.0.0"
|
||||
why: Deprecated in favor of upcoming C(_export) module.
|
||||
alternative: Once published, use M(tower_export) instead.
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
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: []
|
||||
type: list
|
||||
elements: str
|
||||
user:
|
||||
description:
|
||||
- List of user names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
team:
|
||||
description:
|
||||
- List of team names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
credential_type:
|
||||
description:
|
||||
- List of credential type names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
credential:
|
||||
description:
|
||||
- List of credential names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
notification_template:
|
||||
description:
|
||||
- List of notification template names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
inventory:
|
||||
description:
|
||||
- List of inventory names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
project:
|
||||
description:
|
||||
- List of project names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
job_template:
|
||||
description:
|
||||
- List of job template names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
workflow:
|
||||
description:
|
||||
- List of workflow names to export
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
|
||||
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: awx.awx.auth_legacy
|
||||
'''
|
||||
|
||||
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 ..module_utils.tower_legacy import TowerLegacyModule, 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=[], elements='str'),
|
||||
credential_type=dict(type='list', default=[], elements='str'),
|
||||
inventory=dict(type='list', default=[], elements='str'),
|
||||
job_template=dict(type='list', default=[], elements='str'),
|
||||
notification_template=dict(type='list', default=[], elements='str'),
|
||||
organization=dict(type='list', default=[], elements='str'),
|
||||
project=dict(type='list', default=[], elements='str'),
|
||||
team=dict(type='list', default=[], elements='str'),
|
||||
user=dict(type='list', default=[], elements='str'),
|
||||
workflow=dict(type='list', default=[], elements='str'),
|
||||
)
|
||||
|
||||
module = TowerLegacyModule(argument_spec=argument_spec, supports_check_mode=False)
|
||||
|
||||
module.deprecate(msg="This module is deprecated and will be replaced by the AWX CLI export command.", version="awx.awx:14.0.0")
|
||||
|
||||
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.message
|
||||
module.fail_json(msg='Receive Failed', **result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@ -1,174 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8 -*-
|
||||
|
||||
# (c) 2017, John Westcott IV <john.westcott.iv@redhat.com>
|
||||
# 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': ['deprecated'], 'supported_by': 'community'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_send
|
||||
deprecated:
|
||||
removed_in: "14.0.0"
|
||||
why: Deprecated in favor of upcoming C(_import) module.
|
||||
alternative: Once published, use M(tower_import) instead.
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
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
|
||||
type: str
|
||||
files:
|
||||
description:
|
||||
- List of files to import.
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
prevent:
|
||||
description:
|
||||
- A list of asset types to prevent import for
|
||||
default: []
|
||||
type: list
|
||||
elements: str
|
||||
password_management:
|
||||
description:
|
||||
- The password management option to use.
|
||||
- The prompt option is not supported.
|
||||
default: 'default'
|
||||
choices: ["default", "random"]
|
||||
type: str
|
||||
|
||||
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: awx.awx.auth_legacy
|
||||
'''
|
||||
|
||||
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', 'Message 2' ]
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
from ansible.module_utils.six.moves import StringIO
|
||||
from ..module_utils.tower_legacy import TowerLegacyModule, 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(),
|
||||
files=dict(default=[], type='list', elements='str'),
|
||||
prevent=dict(default=[], type='list', elements='str'),
|
||||
password_management=dict(default='default', choices=['default', 'random']),
|
||||
)
|
||||
|
||||
module = TowerLegacyModule(argument_spec=argument_spec, supports_check_mode=False)
|
||||
|
||||
module.deprecate(msg="This module is deprecated and will be replaced by the AWX CLI import command", version="awx.awx:14.0.0")
|
||||
|
||||
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:
|
||||
# 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.message
|
||||
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()
|
||||
@ -1,221 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# coding: utf-8 -*-
|
||||
|
||||
# Copyright: (c) 2018, Adrien Fleury <fleu42@gmail.com>
|
||||
# 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': ['deprecated'], 'supported_by': 'community', 'metadata_version': '1.1'}
|
||||
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_workflow_template
|
||||
deprecated:
|
||||
removed_in: "14.0.0"
|
||||
why: Deprecated in favor of C(_workflow_job_template) and C(_workflow_job_template_node) modules.
|
||||
alternative: Use M(tower_workflow_job_template) and M(_workflow_job_template_node) instead.
|
||||
author: "Adrien Fleury (@fleu42)"
|
||||
short_description: create, update, or destroy Ansible Tower workflow template.
|
||||
description:
|
||||
- A tower-cli based module for CRUD actions on workflow job templates.
|
||||
- Enables use of the old schema functionality.
|
||||
- Not updated for new features, convert to the modules for
|
||||
workflow_job_template and workflow_job_template node instead.
|
||||
options:
|
||||
allow_simultaneous:
|
||||
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
|
||||
ask_inventory:
|
||||
description:
|
||||
- Prompt user for inventory on launch.
|
||||
type: bool
|
||||
description:
|
||||
description:
|
||||
- The description to use for the workflow.
|
||||
type: str
|
||||
extra_vars:
|
||||
description:
|
||||
- Extra variables used by Ansible in YAML or key=value format.
|
||||
type: dict
|
||||
inventory:
|
||||
description:
|
||||
- Name of the inventory to use for the job template.
|
||||
type: str
|
||||
name:
|
||||
description:
|
||||
- The name to use for the workflow.
|
||||
required: True
|
||||
type: str
|
||||
organization:
|
||||
description:
|
||||
- The organization the workflow is linked to.
|
||||
type: str
|
||||
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.
|
||||
type: list
|
||||
elements: dict
|
||||
survey_enabled:
|
||||
description:
|
||||
- Setting that variable will prompt the user for job type on the
|
||||
workflow launch.
|
||||
type: bool
|
||||
survey:
|
||||
description:
|
||||
- The definition of the survey associated to the workflow.
|
||||
type: dict
|
||||
state:
|
||||
description:
|
||||
- Desired state of the resource.
|
||||
default: "present"
|
||||
choices: ["present", "absent"]
|
||||
type: str
|
||||
|
||||
requirements:
|
||||
- ansible-tower-cli >= 3.0.2
|
||||
|
||||
extends_documentation_fragment: awx.awx.auth_legacy
|
||||
'''
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- tower_workflow_template:
|
||||
name: Workflow Template
|
||||
description: My very first Workflow Template
|
||||
organization: My optional Organization
|
||||
schema: "{{ lookup('file', 'my_workflow.json') }}"
|
||||
|
||||
- tower_workflow_template:
|
||||
name: Workflow Template
|
||||
state: absent
|
||||
'''
|
||||
|
||||
|
||||
RETURN = ''' # '''
|
||||
|
||||
|
||||
from ..module_utils.tower_legacy import TowerLegacyModule, tower_auth_config, tower_check_mode
|
||||
|
||||
import json
|
||||
|
||||
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(),
|
||||
extra_vars=dict(type='dict'),
|
||||
organization=dict(),
|
||||
allow_simultaneous=dict(type='bool'),
|
||||
schema=dict(type='list', elements='dict'),
|
||||
survey=dict(type='dict'),
|
||||
survey_enabled=dict(type='bool'),
|
||||
inventory=dict(),
|
||||
ask_inventory=dict(type='bool'),
|
||||
ask_extra_vars=dict(type='bool'),
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
)
|
||||
|
||||
module = TowerLegacyModule(argument_spec=argument_spec, supports_check_mode=False)
|
||||
|
||||
module.deprecate(
|
||||
msg=(
|
||||
"This module is replaced by the combination of tower_workflow_job_template and "
|
||||
"tower_workflow_job_template_node. This uses the old tower-cli and wll be "
|
||||
"removed in 2022."
|
||||
),
|
||||
version='awx.awx:14.0.0',
|
||||
)
|
||||
|
||||
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')
|
||||
|
||||
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', 'inventory', 'survey_enabled', 'description'):
|
||||
if module.params.get(key):
|
||||
params[key] = module.params.get(key)
|
||||
|
||||
# Special treatment for tower-cli extra_vars
|
||||
extra_vars = module.params.get('extra_vars')
|
||||
if extra_vars:
|
||||
params['extra_vars'] = [json.dumps(extra_vars)]
|
||||
|
||||
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'], json.dumps(schema))
|
||||
elif state == 'absent':
|
||||
params['fail_on_missing'] = False
|
||||
result = wfjt_res.delete(**params)
|
||||
except (exc.ConnectionError, exc.BadRequest, exc.AuthError) 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()
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_user
|
||||
module: user
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
short_description: create, update, or destroy Ansible Tower users.
|
||||
short_description: create, update, or destroy Automation Platform Controller users.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower users. See
|
||||
- Create, update, or destroy Automation Platform Controller users. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
username:
|
||||
@ -71,43 +71,43 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Add tower user
|
||||
tower_user:
|
||||
- name: Add user
|
||||
user:
|
||||
username: jdoe
|
||||
password: foobarbaz
|
||||
email: jdoe@example.org
|
||||
first_name: John
|
||||
last_name: Doe
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add tower user as a system administrator
|
||||
tower_user:
|
||||
- name: Add user as a system administrator
|
||||
user:
|
||||
username: jdoe
|
||||
password: foobarbaz
|
||||
email: jdoe@example.org
|
||||
superuser: yes
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Add tower user as a system auditor
|
||||
tower_user:
|
||||
- name: Add user as a system auditor
|
||||
user:
|
||||
username: jdoe
|
||||
password: foobarbaz
|
||||
email: jdoe@example.org
|
||||
auditor: yes
|
||||
state: present
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
|
||||
- name: Delete tower user
|
||||
tower_user:
|
||||
- name: Delete user
|
||||
user:
|
||||
username: jdoe
|
||||
email: jdoe@example.org
|
||||
state: absent
|
||||
tower_config_file: "~/tower_cli.cfg"
|
||||
controller_config_file: "~/tower_cli.cfg"
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -125,7 +125,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
username = module.params.get('username')
|
||||
@ -18,7 +18,7 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: tower_workflow_approval
|
||||
module: workflow_approval
|
||||
author: "Sean Sullivan (@sean-m-sullivan)"
|
||||
short_description: Approve an approval node in a workflow job.
|
||||
description:
|
||||
@ -43,7 +43,7 @@ options:
|
||||
type: str
|
||||
interval:
|
||||
description:
|
||||
- The interval in sections, to request an update from Tower.
|
||||
- The interval in sections, to request an update from the controller.
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
@ -58,13 +58,13 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Launch a workflow with a timeout of 10 seconds
|
||||
tower_workflow_launch:
|
||||
workflow_launch:
|
||||
workflow_template: "Test Workflow"
|
||||
wait: False
|
||||
register: workflow
|
||||
|
||||
- name: Wait for approval node to activate and approve
|
||||
tower_workflow_approval:
|
||||
workflow_approval:
|
||||
workflow_job_id: "{{ workflow.id }}"
|
||||
name: Approve Me
|
||||
interval: 10
|
||||
@ -77,7 +77,7 @@ RETURN = """
|
||||
"""
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -91,7 +91,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
workflow_job_id = module.params.get("workflow_job_id")
|
||||
@ -14,13 +14,13 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_workflow_job_template
|
||||
module: workflow_job_template
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
short_description: create, update, or destroy Ansible Tower workflow job templates.
|
||||
short_description: create, update, or destroy Automation Platform Controller workflow job templates.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower workflow job templates.
|
||||
- Create, update, or destroy Automation Platform Controller workflow job templates.
|
||||
- Replaces the deprecated tower_workflow_template module.
|
||||
- Use the tower_workflow_job_template_node after this, or use the schema paramater to build the workflow's graph
|
||||
- Use workflow_job_template_node after this, or use the schema parameter to build the workflow's graph
|
||||
options:
|
||||
name:
|
||||
description:
|
||||
@ -148,6 +148,7 @@ options:
|
||||
description:
|
||||
- A json list of nodes and their coresponding options. The following suboptions describe a single node.
|
||||
type: list
|
||||
elements: dict
|
||||
suboptions:
|
||||
extra_data:
|
||||
description:
|
||||
@ -328,13 +329,13 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Create a workflow job template
|
||||
tower_workflow_job_template:
|
||||
workflow_job_template:
|
||||
name: example-workflow
|
||||
description: created by Ansible Playbook
|
||||
organization: Default
|
||||
|
||||
- name: Create a workflow job template with schema in template
|
||||
awx.awx.tower_workflow_job_template:
|
||||
awx.awx.workflow_job_template:
|
||||
name: example-workflow
|
||||
inventory: Demo Inventory
|
||||
extra_vars: {'foo': 'bar', 'another-foo': {'barz': 'bar2'}}
|
||||
@ -391,13 +392,13 @@ EXAMPLES = '''
|
||||
register: result
|
||||
|
||||
- name: Copy a workflow job template
|
||||
tower_workflow_job_template:
|
||||
workflow_job_template:
|
||||
name: copy-workflow
|
||||
copy_from: example-workflow
|
||||
organization: Foo
|
||||
|
||||
- name: Create a workflow job template with schema in template
|
||||
awx.awx.tower_workflow_job_template:
|
||||
awx.awx.workflow_job_template:
|
||||
name: example-workflow
|
||||
inventory: Demo Inventory
|
||||
extra_vars: {'foo': 'bar', 'another-foo': {'barz': 'bar2'}}
|
||||
@ -455,7 +456,7 @@ EXAMPLES = '''
|
||||
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
import json
|
||||
|
||||
@ -689,7 +690,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
name = module.params.get('name')
|
||||
@ -14,11 +14,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_workflow_job_template_node
|
||||
module: workflow_job_template_node
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
short_description: create, update, or destroy Ansible Tower workflow job template nodes.
|
||||
short_description: create, update, or destroy Automation Platform Controller workflow job template nodes.
|
||||
description:
|
||||
- Create, update, or destroy Ansible Tower workflow job template nodes.
|
||||
- Create, update, or destroy Automation Platform Controller workflow job template nodes.
|
||||
- Use this to build a graph for a workflow, which dictates what the workflow runs.
|
||||
- Replaces the deprecated tower_workflow_template module schema command.
|
||||
- You can create nodes first, and link them afterwards, and not worry about ordering.
|
||||
@ -157,8 +157,8 @@ extends_documentation_fragment: awx.awx.auth
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Create a node, follows tower_workflow_job_template example
|
||||
tower_workflow_job_template_node:
|
||||
- name: Create a node, follows workflow_job_template example
|
||||
workflow_job_template_node:
|
||||
identifier: my-first-node
|
||||
workflow: example-workflow
|
||||
unified_job_template: jt-for-node-use
|
||||
@ -167,7 +167,7 @@ EXAMPLES = '''
|
||||
foo_key: bar_value
|
||||
|
||||
- name: Create parent node for prior node
|
||||
tower_workflow_job_template_node:
|
||||
workflow_job_template_node:
|
||||
identifier: my-root-node
|
||||
workflow: example-workflow
|
||||
unified_job_template: jt-for-node-use
|
||||
@ -224,7 +224,7 @@ EXAMPLES = '''
|
||||
- my-third-node
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
|
||||
|
||||
def main():
|
||||
@ -255,11 +255,11 @@ def main():
|
||||
required_if = [
|
||||
['state', 'absent', ['identifier']],
|
||||
['state', 'present', ['identifier']],
|
||||
['state', 'present', ['unified_job_template', 'approval_node', 'success_nodes', 'always_nodes', 'failure_nodes'], 'true'],
|
||||
['state', 'present', ['unified_job_template', 'approval_node', 'success_nodes', 'always_nodes', 'failure_nodes'], True],
|
||||
]
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(
|
||||
module = ControllerAPIModule(
|
||||
argument_spec=argument_spec,
|
||||
mutually_exclusive=mutually_exclusive,
|
||||
required_if=required_if,
|
||||
@ -283,7 +283,9 @@ def main():
|
||||
wfjt_search_fields['organization'] = organization_id
|
||||
wfjt_data = module.get_one('workflow_job_templates', name_or_id=workflow_job_template, **{'data': wfjt_search_fields})
|
||||
if wfjt_data is None:
|
||||
module.fail_json(msg="The workflow {0} in organization {1} was not found on the Tower server".format(workflow_job_template, organization))
|
||||
module.fail_json(
|
||||
msg="The workflow {0} in organization {1} was not found on the controller instance server".format(workflow_job_template, organization)
|
||||
)
|
||||
workflow_job_template_id = wfjt_data['id']
|
||||
search_fields['workflow_job_template'] = new_fields['workflow_job_template'] = workflow_job_template_id
|
||||
|
||||
@ -11,11 +11,11 @@ ANSIBLE_METADATA = {'metadata_version': '1.1', 'status': ['preview'], 'supported
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: tower_workflow_launch
|
||||
module: workflow_launch
|
||||
author: "John Westcott IV (@john-westcott-iv)"
|
||||
short_description: Run a workflow in Ansible Tower
|
||||
short_description: Run a workflow in Automation Platform Controller
|
||||
description:
|
||||
- Launch an Ansible Tower workflows. See
|
||||
- Launch an Automation Platform Controller workflows. See
|
||||
U(https://www.ansible.com/tower) for an overview.
|
||||
options:
|
||||
name:
|
||||
@ -55,7 +55,7 @@ options:
|
||||
type: bool
|
||||
interval:
|
||||
description:
|
||||
- The interval to request an update from Tower.
|
||||
- The interval to request an update from the controller.
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
@ -77,12 +77,12 @@ job_info:
|
||||
|
||||
EXAMPLES = '''
|
||||
- name: Launch a workflow with a timeout of 10 seconds
|
||||
tower_workflow_launch:
|
||||
workflow_launch:
|
||||
workflow_template: "Test Workflow"
|
||||
timeout: 10
|
||||
|
||||
- name: Launch a Workflow with extra_vars without waiting
|
||||
tower_workflow_launch:
|
||||
workflow_launch:
|
||||
workflow_template: "Test workflow"
|
||||
extra_vars:
|
||||
var1: My First Variable
|
||||
@ -90,7 +90,7 @@ EXAMPLES = '''
|
||||
wait: False
|
||||
'''
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
import json
|
||||
|
||||
|
||||
@ -109,7 +109,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
optional_args = {}
|
||||
# Extract our parameters
|
||||
@ -18,7 +18,7 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: tower_workflow_node_wait
|
||||
module: workflow_node_wait
|
||||
author: "Sean Sullivan (@sean-m-sullivan)"
|
||||
short_description: Approve an approval node in a workflow job.
|
||||
description:
|
||||
@ -37,7 +37,7 @@ options:
|
||||
type: str
|
||||
interval:
|
||||
description:
|
||||
- The interval in sections, to request an update from Tower.
|
||||
- The interval in sections, to request an update from the controller.
|
||||
required: False
|
||||
default: 1
|
||||
type: float
|
||||
@ -52,13 +52,13 @@ extends_documentation_fragment: awx.awx.auth
|
||||
|
||||
EXAMPLES = """
|
||||
- name: Launch a workflow with a timeout of 10 seconds
|
||||
tower_workflow_launch:
|
||||
workflow_launch:
|
||||
workflow_template: "Test Workflow"
|
||||
wait: False
|
||||
register: workflow
|
||||
|
||||
- name: Wait for a workflow node to finish
|
||||
tower_workflow_node_wait:
|
||||
workflow_node_wait:
|
||||
workflow_job_id: "{{ workflow.id }}"
|
||||
name: Approval Data Step
|
||||
timeout: 120
|
||||
@ -69,7 +69,7 @@ RETURN = """
|
||||
"""
|
||||
|
||||
|
||||
from ..module_utils.tower_api import TowerAPIModule
|
||||
from ..module_utils.controller_api import ControllerAPIModule
|
||||
import time
|
||||
|
||||
|
||||
@ -83,7 +83,7 @@ def main():
|
||||
)
|
||||
|
||||
# Create a module for ourselves
|
||||
module = TowerAPIModule(argument_spec=argument_spec)
|
||||
module = ControllerAPIModule(argument_spec=argument_spec)
|
||||
|
||||
# Extract our parameters
|
||||
workflow_job_id = module.params.get("workflow_job_id")
|
||||
@ -1,3 +1,3 @@
|
||||
pytz # for tower_schedule_rrule lookup plugin
|
||||
python-dateutil>=2.7.0 # tower_schedule_rrule
|
||||
pytz # for schedule_rrule lookup plugin
|
||||
python-dateutil>=2.7.0 # schedule_rrule
|
||||
awxkit # For import and export modules
|
||||
@ -150,14 +150,14 @@ def run_module(request, collection_import):
|
||||
def mock_load_params(self):
|
||||
self.params = module_params
|
||||
|
||||
if getattr(resource_module, 'TowerAWXKitModule', None):
|
||||
resource_class = resource_module.TowerAWXKitModule
|
||||
elif getattr(resource_module, 'TowerAPIModule', None):
|
||||
resource_class = resource_module.TowerAPIModule
|
||||
if getattr(resource_module, 'ControllerAWXKitModule', None):
|
||||
resource_class = resource_module.ControllerAWXKitModule
|
||||
elif getattr(resource_module, 'ControllerAPIModule', None):
|
||||
resource_class = resource_module.ControllerAPIModule
|
||||
elif getattr(resource_module, 'TowerLegacyModule', None):
|
||||
resource_class = resource_module.TowerLegacyModule
|
||||
else:
|
||||
raise ("The module has neither a TowerLegacyModule, TowerAWXKitModule or a TowerAPIModule")
|
||||
raise ("The module has neither a TowerLegacyModule, ControllerAWXKitModule or a ControllerAPIModule")
|
||||
|
||||
with mock.patch.object(resource_class, '_load_params', new=mock_load_params):
|
||||
# Call the test utility (like a mock server) instead of issuing HTTP requests
|
||||
@ -184,7 +184,7 @@ def run_module(request, collection_import):
|
||||
try:
|
||||
result = json.loads(module_stdout)
|
||||
except Exception as e:
|
||||
raise Exception('Module did not write valid JSON, error: {0}, stdout:\n{1}'.format(str(e), module_stdout))
|
||||
raise Exception('Module did not write valid JSON, error: {0}, stdout:\n{1}'.format(str(e), module_stdout)) from e
|
||||
# A module exception should never be a test expectation
|
||||
if 'exception' in result:
|
||||
if "ModuleNotFoundError: No module named 'tower_cli'" in result['exception']:
|
||||
|
||||
@ -11,7 +11,7 @@ from awx.main.models.ad_hoc_commands import AdHocCommand
|
||||
@pytest.mark.django_db
|
||||
def test_ad_hoc_command_wait_successful(run_module, admin_user):
|
||||
command = AdHocCommand.objects.create(status='successful', started=now(), finished=now())
|
||||
result = run_module('tower_ad_hoc_command_wait', dict(command_id=command.id), admin_user)
|
||||
result = run_module('ad_hoc_command_wait', dict(command_id=command.id), admin_user)
|
||||
result.pop('invocation', None)
|
||||
result['elapsed'] = float(result['elapsed'])
|
||||
assert result.pop('finished', '')[:10] == str(command.finished)[:10]
|
||||
@ -22,7 +22,7 @@ def test_ad_hoc_command_wait_successful(run_module, admin_user):
|
||||
@pytest.mark.django_db
|
||||
def test_ad_hoc_command_wait_failed(run_module, admin_user):
|
||||
command = AdHocCommand.objects.create(status='failed', started=now(), finished=now())
|
||||
result = run_module('tower_ad_hoc_command_wait', dict(command_id=command.id), admin_user)
|
||||
result = run_module('ad_hoc_command_wait', dict(command_id=command.id), admin_user)
|
||||
result.pop('invocation', None)
|
||||
result['elapsed'] = float(result['elapsed'])
|
||||
assert result.pop('finished', '')[:10] == str(command.finished)[:10]
|
||||
@ -39,6 +39,6 @@ def test_ad_hoc_command_wait_failed(run_module, admin_user):
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_ad_hoc_command_wait_not_found(run_module, admin_user):
|
||||
result = run_module('tower_ad_hoc_command_wait', dict(command_id=42), admin_user)
|
||||
result = run_module('ad_hoc_command_wait', dict(command_id=42), admin_user)
|
||||
result.pop('invocation', None)
|
||||
assert result == {"failed": True, "msg": "Unable to wait on ad hoc command 42; that ID does not exist in Tower."}
|
||||
assert result == {"failed": True, "msg": "Unable to wait on ad hoc command 42; that ID does not exist."}
|
||||
|
||||
@ -21,7 +21,7 @@ def test_create_application(run_module, admin_user):
|
||||
'organization': 'foo',
|
||||
}
|
||||
|
||||
result = run_module('tower_application', module_args, admin_user)
|
||||
result = run_module('application', module_args, admin_user)
|
||||
assert result.get('changed'), result
|
||||
|
||||
application = OAuth2Application.objects.get(name='foo_app')
|
||||
|
||||
@ -14,9 +14,9 @@ import re
|
||||
|
||||
# Read-only endpoints are dynamically created by an options page with no POST section.
|
||||
# Normally a read-only endpoint should not have a module (i.e. /api/v2/me) but sometimes we reuse a name
|
||||
# For example, we have a tower_role module but /api/v2/roles is a read only endpoint.
|
||||
# For example, we have a role module but /api/v2/roles is a read only endpoint.
|
||||
# This list indicates which read-only endpoints have associated modules with them.
|
||||
read_only_endpoints_with_modules = ['tower_settings', 'tower_role', 'tower_project_update']
|
||||
read_only_endpoints_with_modules = ['settings', 'role', 'project_update']
|
||||
|
||||
# If a module should not be created for an endpoint and the endpoint is not read-only add it here
|
||||
# THINK HARD ABOUT DOING THIS
|
||||
@ -24,23 +24,23 @@ no_module_for_endpoint = []
|
||||
|
||||
# Some modules work on the related fields of an endpoint. These modules will not have an auto-associated endpoint
|
||||
no_endpoint_for_module = [
|
||||
'tower_import',
|
||||
'tower_meta',
|
||||
'tower_export',
|
||||
'tower_inventory_source_update',
|
||||
'tower_job_launch',
|
||||
'tower_job_wait',
|
||||
'tower_job_list',
|
||||
'tower_license',
|
||||
'tower_ping',
|
||||
'tower_receive',
|
||||
'tower_send',
|
||||
'tower_workflow_launch',
|
||||
'tower_workflow_node_wait',
|
||||
'tower_job_cancel',
|
||||
'tower_workflow_template',
|
||||
'tower_ad_hoc_command_wait',
|
||||
'tower_ad_hoc_command_cancel',
|
||||
'import',
|
||||
'controller_meta',
|
||||
'export',
|
||||
'inventory_source_update',
|
||||
'job_launch',
|
||||
'job_wait',
|
||||
'job_list',
|
||||
'license',
|
||||
'ping',
|
||||
'receive',
|
||||
'send',
|
||||
'workflow_launch',
|
||||
'workflow_node_wait',
|
||||
'job_cancel',
|
||||
'workflow_template',
|
||||
'ad_hoc_command_wait',
|
||||
'ad_hoc_command_cancel',
|
||||
]
|
||||
|
||||
# Global module parameters we can ignore
|
||||
@ -50,32 +50,32 @@ ignore_parameters = ['state', 'new_name', 'update_secrets', 'copy_from']
|
||||
# Add the module name as the key with the value being the list of params to ignore
|
||||
no_api_parameter_ok = {
|
||||
# The wait is for whether or not to wait for a project update on change
|
||||
'tower_project': ['wait', 'interval', 'update_project'],
|
||||
'project': ['wait', 'interval', 'update_project'],
|
||||
# Existing_token and id are for working with an existing tokens
|
||||
'tower_token': ['existing_token', 'existing_token_id'],
|
||||
'token': ['existing_token', 'existing_token_id'],
|
||||
# /survey spec is now how we handle associations
|
||||
# We take an organization here to help with the lookups only
|
||||
'tower_job_template': ['survey_spec', 'organization'],
|
||||
'tower_inventory_source': ['organization'],
|
||||
'job_template': ['survey_spec', 'organization'],
|
||||
'inventory_source': ['organization'],
|
||||
# Organization is how we are looking up job templates, Approval node is for workflow_approval_templates
|
||||
'tower_workflow_job_template_node': ['organization', 'approval_node'],
|
||||
'workflow_job_template_node': ['organization', 'approval_node'],
|
||||
# Survey is how we handle associations
|
||||
'tower_workflow_job_template': ['survey_spec', 'destroy_current_schema'],
|
||||
# ad hoc commands support interval and timeout since its more like tower_job_launch
|
||||
'tower_ad_hoc_command': ['interval', 'timeout', 'wait'],
|
||||
# tower_group parameters to perserve hosts and children.
|
||||
'tower_group': ['preserve_existing_children', 'preserve_existing_hosts'],
|
||||
# tower_workflow_approval parameters that do not apply when approving an approval node.
|
||||
'tower_workflow_approval': ['action', 'interval', 'timeout', 'workflow_job_id'],
|
||||
'workflow_job_template': ['survey_spec', 'destroy_current_schema'],
|
||||
# ad hoc commands support interval and timeout since its more like job_launch
|
||||
'ad_hoc_command': ['interval', 'timeout', 'wait'],
|
||||
# group parameters to perserve hosts and children.
|
||||
'group': ['preserve_existing_children', 'preserve_existing_hosts'],
|
||||
# workflow_approval parameters that do not apply when approving an approval node.
|
||||
'workflow_approval': ['action', 'interval', 'timeout', 'workflow_job_id'],
|
||||
}
|
||||
|
||||
# When this tool was created we were not feature complete. Adding something in here indicates a module
|
||||
# that needs to be developed. If the module is found on the file system it will auto-detect that the
|
||||
# work is being done and will bypass this check. At some point this module should be removed from this list.
|
||||
needs_development = ['tower_inventory_script']
|
||||
needs_development = ['inventory_script']
|
||||
needs_param_development = {
|
||||
'tower_host': ['instance_id'],
|
||||
'tower_workflow_approval': ['description', 'execution_environment'],
|
||||
'host': ['instance_id'],
|
||||
'workflow_approval': ['description', 'execution_environment'],
|
||||
}
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
@ -169,7 +169,8 @@ def test_completeness(collection_import, request, admin_user, job_template, exec
|
||||
for root, dirs, files in os.walk(module_directory):
|
||||
if root == module_directory:
|
||||
for filename in files:
|
||||
if re.match('^tower_.*.py$', filename):
|
||||
# must begin with a letter a-z, and end in .py
|
||||
if re.match(r'^[a-z].*.py$', filename):
|
||||
module_name = filename[:-3]
|
||||
option_comparison[module_name] = {
|
||||
'endpoint': 'N/A',
|
||||
@ -192,7 +193,7 @@ def test_completeness(collection_import, request, admin_user, job_template, exec
|
||||
singular_endpoint = singular_endpoint[:-3]
|
||||
if singular_endpoint != 'settings' and singular_endpoint.endswith('s'):
|
||||
singular_endpoint = singular_endpoint[:-1]
|
||||
module_name = 'tower_{0}'.format(singular_endpoint)
|
||||
module_name = '{0}'.format(singular_endpoint)
|
||||
|
||||
endpoint_url = endpoint_response.data.get(endpoint)
|
||||
|
||||
|
||||
@ -29,7 +29,7 @@ def test_create_machine_credential(run_module, admin_user, organization, silence
|
||||
ct = CredentialType.defaults['ssh']()
|
||||
ct.save()
|
||||
# Example from docs
|
||||
result = run_module('tower_credential', dict(name='Test Machine Credential', organization=organization.name, kind='ssh', state='present'), admin_user)
|
||||
result = run_module('credential', dict(name='Test Machine Credential', organization=organization.name, kind='ssh', state='present'), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed'), result
|
||||
|
||||
@ -48,7 +48,7 @@ def test_create_vault_credential(run_module, admin_user, organization, silence_d
|
||||
ct.save()
|
||||
|
||||
result = run_module(
|
||||
'tower_credential',
|
||||
'credential',
|
||||
dict(name='Test Vault Credential', organization=organization.name, kind='vault', vault_id='bar', vault_password='foobar', state='present'),
|
||||
admin_user,
|
||||
)
|
||||
@ -67,7 +67,7 @@ def test_create_vault_credential(run_module, admin_user, organization, silence_d
|
||||
@pytest.mark.django_db
|
||||
def test_ct_precedence_over_kind(run_module, admin_user, organization, cred_type, silence_deprecation):
|
||||
result = run_module(
|
||||
'tower_credential', dict(name='A credential', organization=organization.name, kind='ssh', credential_type=cred_type.name, state='present'), admin_user
|
||||
'credential', dict(name='A credential', organization=organization.name, kind='ssh', credential_type=cred_type.name, state='present'), admin_user
|
||||
)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
@ -82,7 +82,7 @@ def test_input_overrides_old_fields(run_module, admin_user, organization, silenc
|
||||
ct = CredentialType.defaults['vault']()
|
||||
ct.save()
|
||||
result = run_module(
|
||||
'tower_credential',
|
||||
'credential',
|
||||
dict(
|
||||
name='A Vault credential',
|
||||
organization=organization.name,
|
||||
@ -103,7 +103,7 @@ def test_input_overrides_old_fields(run_module, admin_user, organization, silenc
|
||||
@pytest.mark.django_db
|
||||
def test_missing_credential_type(run_module, admin_user, organization):
|
||||
Organization.objects.create(name='test-org')
|
||||
result = run_module('tower_credential', dict(name='A credential', organization=organization.name, credential_type='foobar', state='present'), admin_user)
|
||||
result = run_module('credential', dict(name='A credential', organization=organization.name, credential_type='foobar', state='present'), admin_user)
|
||||
assert result.get('failed', False), result
|
||||
assert 'credential_type' in result['msg']
|
||||
assert 'foobar' in result['msg']
|
||||
@ -113,7 +113,7 @@ def test_missing_credential_type(run_module, admin_user, organization):
|
||||
@pytest.mark.django_db
|
||||
def test_make_use_of_custom_credential_type(run_module, organization, admin_user, cred_type):
|
||||
result = run_module(
|
||||
'tower_credential',
|
||||
'credential',
|
||||
dict(name='Galaxy Token for Steve', organization=organization.name, credential_type=cred_type.name, inputs={'token': '7rEZK38DJl58A7RxA6EC7lLvUHbBQ1'}),
|
||||
admin_user,
|
||||
)
|
||||
@ -137,7 +137,7 @@ def test_secret_field_write_twice(run_module, organization, admin_user, cred_typ
|
||||
val2 = '7rEZ238DJl5837rxA6xxxlLvUHbBQ1'
|
||||
for val in (val1, val2):
|
||||
result = run_module(
|
||||
'tower_credential',
|
||||
'credential',
|
||||
dict(
|
||||
name='Galaxy Token for Steve',
|
||||
organization=organization.name,
|
||||
|
||||
@ -29,7 +29,7 @@ def test_aim_credential_source(run_module, admin_user, organization, source_cred
|
||||
tgt_cred = Credential.objects.create(name='Test Machine Credential', organization=organization, credential_type=ct, inputs={'username': 'bob'})
|
||||
|
||||
result = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(
|
||||
source_credential=source_cred_aim.name,
|
||||
target_credential=tgt_cred.name,
|
||||
@ -73,7 +73,7 @@ def test_conjur_credential_source(run_module, admin_user, organization, source_c
|
||||
tgt_cred = Credential.objects.create(name='Test Machine Credential', organization=organization, credential_type=ct, inputs={'username': 'bob'})
|
||||
|
||||
result = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(
|
||||
source_credential=source_cred_conjur.name,
|
||||
target_credential=tgt_cred.name,
|
||||
@ -123,7 +123,7 @@ def test_hashi_secret_credential_source(run_module, admin_user, organization, so
|
||||
tgt_cred = Credential.objects.create(name='Test Machine Credential', organization=organization, credential_type=ct, inputs={'username': 'bob'})
|
||||
|
||||
result = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(
|
||||
source_credential=source_cred_hashi_secret.name,
|
||||
target_credential=tgt_cred.name,
|
||||
@ -170,7 +170,7 @@ def test_hashi_ssh_credential_source(run_module, admin_user, organization, sourc
|
||||
tgt_cred = Credential.objects.create(name='Test Machine Credential', organization=organization, credential_type=ct, inputs={'username': 'bob'})
|
||||
|
||||
result = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(
|
||||
source_credential=source_cred_hashi_ssh.name,
|
||||
target_credential=tgt_cred.name,
|
||||
@ -224,7 +224,7 @@ def test_azure_kv_credential_source(run_module, admin_user, organization, source
|
||||
tgt_cred = Credential.objects.create(name='Test Machine Credential', organization=organization, credential_type=ct, inputs={'username': 'bob'})
|
||||
|
||||
result = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(
|
||||
source_credential=source_cred_azure_kv.name,
|
||||
target_credential=tgt_cred.name,
|
||||
@ -265,7 +265,7 @@ def test_aim_credential_source(run_module, admin_user, organization, source_cred
|
||||
tgt_cred = Credential.objects.create(name='Test Machine Credential', organization=organization, credential_type=ct, inputs={'username': 'bob'})
|
||||
|
||||
result = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(
|
||||
source_credential=source_cred_aim.name,
|
||||
target_credential=tgt_cred.name,
|
||||
@ -280,7 +280,7 @@ def test_aim_credential_source(run_module, admin_user, organization, source_cred
|
||||
assert result.get('changed'), result
|
||||
|
||||
unchangedResult = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(
|
||||
source_credential=source_cred_aim.name,
|
||||
target_credential=tgt_cred.name,
|
||||
@ -295,7 +295,7 @@ def test_aim_credential_source(run_module, admin_user, organization, source_cred
|
||||
assert not unchangedResult.get('changed'), result
|
||||
|
||||
changedResult = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(source_credential=source_cred_aim_alt.name, target_credential=tgt_cred.name, input_field_name='password', state='present'),
|
||||
admin_user,
|
||||
)
|
||||
@ -336,7 +336,7 @@ def test_centrify_vault_credential_source(run_module, admin_user, organization,
|
||||
tgt_cred = Credential.objects.create(name='Test Machine Credential', organization=organization, credential_type=ct, inputs={'username': 'bob'})
|
||||
|
||||
result = run_module(
|
||||
'tower_credential_input_source',
|
||||
'credential_input_source',
|
||||
dict(
|
||||
source_credential=source_cred_centrify_secret.name,
|
||||
target_credential=tgt_cred.name,
|
||||
|
||||
@ -11,7 +11,7 @@ from awx.main.models import CredentialType
|
||||
def test_create_custom_credential_type(run_module, admin_user, silence_deprecation):
|
||||
# Example from docs
|
||||
result = run_module(
|
||||
'tower_credential_type',
|
||||
'credential_type',
|
||||
dict(
|
||||
name='Nexus',
|
||||
description='Credentials type for Nexus',
|
||||
@ -37,7 +37,7 @@ def test_create_custom_credential_type(run_module, admin_user, silence_deprecati
|
||||
@pytest.mark.django_db
|
||||
def test_changed_false_with_api_changes(run_module, admin_user):
|
||||
result = run_module(
|
||||
'tower_credential_type',
|
||||
'credential_type',
|
||||
dict(
|
||||
name='foo',
|
||||
kind='cloud',
|
||||
@ -50,7 +50,7 @@ def test_changed_false_with_api_changes(run_module, admin_user):
|
||||
assert result.get('changed'), result
|
||||
|
||||
result = run_module(
|
||||
'tower_credential_type',
|
||||
'credential_type',
|
||||
dict(
|
||||
name='foo',
|
||||
inputs={"fields": [{"id": "env_value", "label": "foo", "default": "foo"}]},
|
||||
|
||||
@ -13,7 +13,7 @@ def test_create_group(run_module, admin_user):
|
||||
inv = Inventory.objects.create(name='test-inv', organization=org)
|
||||
variables = {"ansible_network_os": "iosxr"}
|
||||
|
||||
result = run_module('tower_group', dict(name='Test Group', inventory='test-inv', variables=variables, state='present'), admin_user)
|
||||
result = run_module('group', dict(name='Test Group', inventory='test-inv', variables=variables, state='present'), admin_user)
|
||||
assert result.get('changed'), result
|
||||
|
||||
group = Group.objects.get(name='Test Group')
|
||||
@ -39,7 +39,7 @@ def test_associate_hosts_and_children(run_module, admin_user, organization):
|
||||
child = Group.objects.create(inventory=inv, name='child_group')
|
||||
|
||||
result = run_module(
|
||||
'tower_group',
|
||||
'group',
|
||||
dict(name='Test Group', inventory='test-inv', hosts=[inv_hosts[1].name, inv_hosts[2].name], children=[child.name], state='present'),
|
||||
admin_user,
|
||||
)
|
||||
@ -56,7 +56,7 @@ def test_associate_on_create(run_module, admin_user, organization):
|
||||
child = Group.objects.create(name='test-child', inventory=inv)
|
||||
host = Host.objects.create(name='test-host', inventory=inv)
|
||||
|
||||
result = run_module('tower_group', dict(name='Test Group', inventory='test-inv', hosts=[host.name], groups=[child.name], state='present'), admin_user)
|
||||
result = run_module('group', dict(name='Test Group', inventory='test-inv', hosts=[host.name], groups=[child.name], state='present'), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result['changed'] is True
|
||||
|
||||
@ -70,7 +70,7 @@ def test_children_alias_of_groups(run_module, admin_user, organization):
|
||||
inv = Inventory.objects.create(name='test-inv', organization=organization)
|
||||
group = Group.objects.create(name='Test Group', inventory=inv)
|
||||
child = Group.objects.create(inventory=inv, name='child_group')
|
||||
result = run_module('tower_group', dict(name='Test Group', inventory='test-inv', groups=[child.name], state='present'), admin_user)
|
||||
result = run_module('group', dict(name='Test Group', inventory='test-inv', groups=[child.name], state='present'), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result['changed'] is True
|
||||
|
||||
@ -78,7 +78,7 @@ def test_children_alias_of_groups(run_module, admin_user, organization):
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_tower_group_idempotent(run_module, admin_user):
|
||||
def test_group_idempotent(run_module, admin_user):
|
||||
# https://github.com/ansible/ansible/issues/46803
|
||||
org = Organization.objects.create(name='test-org')
|
||||
inv = Inventory.objects.create(name='test-inv', organization=org)
|
||||
@ -87,7 +87,7 @@ def test_tower_group_idempotent(run_module, admin_user):
|
||||
inventory=inv,
|
||||
)
|
||||
|
||||
result = run_module('tower_group', dict(name='Test Group', inventory='test-inv', state='present'), admin_user)
|
||||
result = run_module('group', dict(name='Test Group', inventory='test-inv', state='present'), admin_user)
|
||||
|
||||
result.pop('invocation')
|
||||
assert result == {
|
||||
|
||||
@ -11,7 +11,7 @@ from awx.main.tests.functional.conftest import kube_credential, credentialtype_k
|
||||
@pytest.mark.django_db
|
||||
def test_instance_group_create(run_module, admin_user):
|
||||
result = run_module(
|
||||
'tower_instance_group', {'name': 'foo-group', 'policy_instance_percentage': 34, 'policy_instance_minimum': 12, 'state': 'present'}, admin_user
|
||||
'instance_group', {'name': 'foo-group', 'policy_instance_percentage': 34, 'policy_instance_minimum': 12, 'state': 'present'}, admin_user
|
||||
)
|
||||
assert not result.get('failed', False), result
|
||||
assert result['changed']
|
||||
@ -24,7 +24,7 @@ def test_instance_group_create(run_module, admin_user):
|
||||
new_instance = Instance.objects.create(hostname='foo.example.com')
|
||||
|
||||
# Set the new instance group only to the one instnace
|
||||
result = run_module('tower_instance_group', {'name': 'foo-group', 'instances': [new_instance.hostname], 'state': 'present'}, admin_user)
|
||||
result = run_module('instance_group', {'name': 'foo-group', 'instances': [new_instance.hostname], 'state': 'present'}, admin_user)
|
||||
assert not result.get('failed', False), result
|
||||
assert result['changed']
|
||||
|
||||
@ -41,9 +41,7 @@ def test_instance_group_create(run_module, admin_user):
|
||||
def test_container_group_create(run_module, admin_user, kube_credential):
|
||||
pod_spec = "{ 'Nothing': True }"
|
||||
|
||||
result = run_module(
|
||||
'tower_instance_group', {'name': 'foo-c-group', 'credential': kube_credential.id, 'is_container_group': True, 'state': 'present'}, admin_user
|
||||
)
|
||||
result = run_module('instance_group', {'name': 'foo-c-group', 'credential': kube_credential.id, 'is_container_group': True, 'state': 'present'}, admin_user)
|
||||
assert not result.get('failed', False), result['msg']
|
||||
assert result['changed']
|
||||
|
||||
@ -51,7 +49,7 @@ def test_container_group_create(run_module, admin_user, kube_credential):
|
||||
assert ig.pod_spec_override == ''
|
||||
|
||||
result = run_module(
|
||||
'tower_instance_group',
|
||||
'instance_group',
|
||||
{'name': 'foo-c-group', 'credential': kube_credential.id, 'is_container_group': True, 'pod_spec_override': pod_spec, 'state': 'present'},
|
||||
admin_user,
|
||||
)
|
||||
|
||||
@ -13,7 +13,7 @@ def test_inventory_create(run_module, admin_user, organization, insights_credent
|
||||
# Create an insights credential
|
||||
|
||||
result = run_module(
|
||||
'tower_inventory',
|
||||
'inventory',
|
||||
{
|
||||
'name': 'foo-inventory',
|
||||
'organization': organization.name,
|
||||
@ -39,7 +39,7 @@ def test_inventory_create(run_module, admin_user, organization, insights_credent
|
||||
@pytest.mark.django_db
|
||||
def test_invalid_smart_inventory_create(run_module, admin_user, organization):
|
||||
result = run_module(
|
||||
'tower_inventory',
|
||||
'inventory',
|
||||
{'name': 'foo-inventory', 'organization': organization.name, 'kind': 'smart', 'host_filter': 'ansible', 'state': 'present'},
|
||||
admin_user,
|
||||
)
|
||||
@ -51,7 +51,7 @@ def test_invalid_smart_inventory_create(run_module, admin_user, organization):
|
||||
@pytest.mark.django_db
|
||||
def test_valid_smart_inventory_create(run_module, admin_user, organization):
|
||||
result = run_module(
|
||||
'tower_inventory',
|
||||
'inventory',
|
||||
{'name': 'foo-inventory', 'organization': organization.name, 'kind': 'smart', 'host_filter': 'name=my_host', 'state': 'present'},
|
||||
admin_user,
|
||||
)
|
||||
|
||||
@ -28,7 +28,7 @@ def project(base_inventory):
|
||||
def test_inventory_source_create(run_module, admin_user, base_inventory, project):
|
||||
source_path = '/var/lib/awx/example_source_path/'
|
||||
result = run_module(
|
||||
'tower_inventory_source',
|
||||
'inventory_source',
|
||||
dict(name='foo', inventory=base_inventory.name, state='present', source='scm', source_path=source_path, source_project=project.name),
|
||||
admin_user,
|
||||
)
|
||||
@ -49,7 +49,7 @@ def test_create_inventory_source_implied_org(run_module, admin_user):
|
||||
inv = Inventory.objects.create(name='test-inv', organization=org)
|
||||
|
||||
# Credential is not required for ec2 source, because of IAM roles
|
||||
result = run_module('tower_inventory_source', dict(name='Test Inventory Source', inventory='test-inv', source='ec2', state='present'), admin_user)
|
||||
result = run_module('inventory_source', dict(name='Test Inventory Source', inventory='test-inv', source='ec2', state='present'), admin_user)
|
||||
assert result.pop('changed', None), result
|
||||
|
||||
inv_src = InventorySource.objects.get(name='Test Inventory Source')
|
||||
@ -72,7 +72,7 @@ def test_create_inventory_source_multiple_orgs(run_module, admin_user):
|
||||
inv2 = Inventory.objects.create(name='test-inv', organization=org2)
|
||||
|
||||
result = run_module(
|
||||
'tower_inventory_source',
|
||||
'inventory_source',
|
||||
dict(name='Test Inventory Source', inventory=inv2.name, organization='test-org-number-two', source='ec2', state='present'),
|
||||
admin_user,
|
||||
)
|
||||
@ -90,14 +90,14 @@ def test_create_inventory_source_multiple_orgs(run_module, admin_user):
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_falsy_value(run_module, admin_user, base_inventory):
|
||||
result = run_module('tower_inventory_source', dict(name='falsy-test', inventory=base_inventory.name, source='ec2', update_on_launch=True), admin_user)
|
||||
result = run_module('inventory_source', dict(name='falsy-test', inventory=base_inventory.name, source='ec2', update_on_launch=True), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed', None), result
|
||||
|
||||
inv_src = InventorySource.objects.get(name='falsy-test')
|
||||
assert inv_src.update_on_launch is True
|
||||
|
||||
result = run_module('tower_inventory_source', dict(name='falsy-test', inventory=base_inventory.name, source='ec2', update_on_launch=False), admin_user)
|
||||
result = run_module('inventory_source', dict(name='falsy-test', inventory=base_inventory.name, source='ec2', update_on_launch=False), admin_user)
|
||||
|
||||
inv_src.refresh_from_db()
|
||||
assert inv_src.update_on_launch is False
|
||||
@ -127,7 +127,7 @@ def test_falsy_value(run_module, admin_user, base_inventory):
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_missing_required_credential(run_module, admin_user, base_inventory):
|
||||
result = run_module('tower_inventory_source', dict(name='Test Azure Source', inventory=base_inventory.name, source='azure_rm', state='present'), admin_user)
|
||||
result = run_module('inventory_source', dict(name='Test Azure Source', inventory=base_inventory.name, source='azure_rm', state='present'), admin_user)
|
||||
assert result.pop('failed', None) is True, result
|
||||
|
||||
assert 'Credential is required for a cloud source' in result.get('msg', '')
|
||||
@ -136,7 +136,7 @@ def test_missing_required_credential(run_module, admin_user, base_inventory):
|
||||
@pytest.mark.django_db
|
||||
def test_source_project_not_for_cloud(run_module, admin_user, base_inventory, project):
|
||||
result = run_module(
|
||||
'tower_inventory_source',
|
||||
'inventory_source',
|
||||
dict(name='Test ec2 Inventory Source', inventory=base_inventory.name, source='ec2', state='present', source_project=project.name),
|
||||
admin_user,
|
||||
)
|
||||
@ -148,7 +148,7 @@ def test_source_project_not_for_cloud(run_module, admin_user, base_inventory, pr
|
||||
@pytest.mark.django_db
|
||||
def test_source_path_not_for_cloud(run_module, admin_user, base_inventory):
|
||||
result = run_module(
|
||||
'tower_inventory_source',
|
||||
'inventory_source',
|
||||
dict(name='Test ec2 Inventory Source', inventory=base_inventory.name, source='ec2', state='present', source_path='where/am/I'),
|
||||
admin_user,
|
||||
)
|
||||
@ -160,7 +160,7 @@ def test_source_path_not_for_cloud(run_module, admin_user, base_inventory):
|
||||
@pytest.mark.django_db
|
||||
def test_scm_source_needs_project(run_module, admin_user, base_inventory):
|
||||
result = run_module(
|
||||
'tower_inventory_source',
|
||||
'inventory_source',
|
||||
dict(
|
||||
name='SCM inventory without project', inventory=base_inventory.name, state='present', source='scm', source_path='/var/lib/awx/example_source_path/'
|
||||
),
|
||||
|
||||
@ -11,7 +11,7 @@ from awx.main.models import Job
|
||||
@pytest.mark.django_db
|
||||
def test_job_wait_successful(run_module, admin_user):
|
||||
job = Job.objects.create(status='successful', started=now(), finished=now())
|
||||
result = run_module('tower_job_wait', dict(job_id=job.id), admin_user)
|
||||
result = run_module('job_wait', dict(job_id=job.id), admin_user)
|
||||
result.pop('invocation', None)
|
||||
result['elapsed'] = float(result['elapsed'])
|
||||
assert result.pop('finished', '')[:10] == str(job.finished)[:10]
|
||||
@ -22,7 +22,7 @@ def test_job_wait_successful(run_module, admin_user):
|
||||
@pytest.mark.django_db
|
||||
def test_job_wait_failed(run_module, admin_user):
|
||||
job = Job.objects.create(status='failed', started=now(), finished=now())
|
||||
result = run_module('tower_job_wait', dict(job_id=job.id), admin_user)
|
||||
result = run_module('job_wait', dict(job_id=job.id), admin_user)
|
||||
result.pop('invocation', None)
|
||||
result['elapsed'] = float(result['elapsed'])
|
||||
assert result.pop('finished', '')[:10] == str(job.finished)[:10]
|
||||
@ -32,6 +32,6 @@ def test_job_wait_failed(run_module, admin_user):
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_job_wait_not_found(run_module, admin_user):
|
||||
result = run_module('tower_job_wait', dict(job_id=42), admin_user)
|
||||
result = run_module('job_wait', dict(job_id=42), admin_user)
|
||||
result.pop('invocation', None)
|
||||
assert result == {"failed": True, "msg": "Unable to wait on job 42; that ID does not exist in Tower."}
|
||||
assert result == {"failed": True, "msg": "Unable to wait on job 42; that ID does not exist."}
|
||||
|
||||
@ -20,7 +20,7 @@ def test_create_job_template(run_module, admin_user, project, inventory):
|
||||
'state': 'present',
|
||||
}
|
||||
|
||||
result = run_module('tower_job_template', module_args, admin_user)
|
||||
result = run_module('job_template', module_args, admin_user)
|
||||
|
||||
jt = JobTemplate.objects.get(name='foo')
|
||||
assert jt.extra_vars == '{"foo": "bar"}'
|
||||
@ -48,7 +48,7 @@ def test_resets_job_template_values(run_module, admin_user, project, inventory):
|
||||
'ask_limit_on_launch': True,
|
||||
}
|
||||
|
||||
result = run_module('tower_job_template', module_args, admin_user)
|
||||
result = run_module('job_template', module_args, admin_user)
|
||||
|
||||
jt = JobTemplate.objects.get(name='foo')
|
||||
assert jt.forks == 20
|
||||
@ -70,7 +70,7 @@ def test_resets_job_template_values(run_module, admin_user, project, inventory):
|
||||
'ask_limit_on_launch': False,
|
||||
}
|
||||
|
||||
result = run_module('tower_job_template', module_args, admin_user)
|
||||
result = run_module('job_template', module_args, admin_user)
|
||||
assert result['changed']
|
||||
|
||||
jt = JobTemplate.objects.get(name='foo')
|
||||
@ -92,7 +92,7 @@ def test_job_launch_with_prompting(run_module, admin_user, project, organization
|
||||
ask_credential_on_launch=True,
|
||||
)
|
||||
result = run_module(
|
||||
'tower_job_launch',
|
||||
'job_launch',
|
||||
dict(
|
||||
job_template='foo',
|
||||
inventory=inventory.name,
|
||||
@ -112,7 +112,7 @@ def test_job_launch_with_prompting(run_module, admin_user, project, organization
|
||||
@pytest.mark.django_db
|
||||
def test_job_template_with_new_credentials(run_module, admin_user, project, inventory, machine_credential, vault_credential):
|
||||
result = run_module(
|
||||
'tower_job_template',
|
||||
'job_template',
|
||||
dict(
|
||||
name='foo', playbook='helloworld.yml', project=project.name, inventory=inventory.name, credentials=[machine_credential.name, vault_credential.name]
|
||||
),
|
||||
@ -126,7 +126,7 @@ def test_job_template_with_new_credentials(run_module, admin_user, project, inve
|
||||
|
||||
prior_ct = ActivityStream.objects.count()
|
||||
result = run_module(
|
||||
'tower_job_template',
|
||||
'job_template',
|
||||
dict(
|
||||
name='foo', playbook='helloworld.yml', project=project.name, inventory=inventory.name, credentials=[machine_credential.name, vault_credential.name]
|
||||
),
|
||||
@ -144,7 +144,7 @@ def test_job_template_with_new_credentials(run_module, admin_user, project, inve
|
||||
@pytest.mark.django_db
|
||||
def test_job_template_with_survey_spec(run_module, admin_user, project, inventory, survey_spec):
|
||||
result = run_module(
|
||||
'tower_job_template',
|
||||
'job_template',
|
||||
dict(name='foo', playbook='helloworld.yml', project=project.name, inventory=inventory.name, survey_spec=survey_spec, survey_enabled=True),
|
||||
admin_user,
|
||||
)
|
||||
@ -156,7 +156,7 @@ def test_job_template_with_survey_spec(run_module, admin_user, project, inventor
|
||||
|
||||
prior_ct = ActivityStream.objects.count()
|
||||
result = run_module(
|
||||
'tower_job_template',
|
||||
'job_template',
|
||||
dict(name='foo', playbook='helloworld.yml', project=project.name, inventory=inventory.name, survey_spec=survey_spec, survey_enabled=True),
|
||||
admin_user,
|
||||
)
|
||||
@ -172,7 +172,7 @@ def test_job_template_with_survey_spec(run_module, admin_user, project, inventor
|
||||
@pytest.mark.django_db
|
||||
def test_job_template_with_wrong_survey_spec(run_module, admin_user, project, inventory, survey_spec):
|
||||
result = run_module(
|
||||
'tower_job_template',
|
||||
'job_template',
|
||||
dict(name='foo', playbook='helloworld.yml', project=project.name, inventory=inventory.name, survey_spec=survey_spec, survey_enabled=True),
|
||||
admin_user,
|
||||
)
|
||||
@ -187,7 +187,7 @@ def test_job_template_with_wrong_survey_spec(run_module, admin_user, project, in
|
||||
del survey_spec['description']
|
||||
|
||||
result = run_module(
|
||||
'tower_job_template',
|
||||
'job_template',
|
||||
dict(name='foo', playbook='helloworld.yml', project=project.name, inventory=inventory.name, survey_spec=survey_spec, survey_enabled=True),
|
||||
admin_user,
|
||||
)
|
||||
@ -204,7 +204,7 @@ def test_job_template_with_survey_encrypted_default(run_module, admin_user, proj
|
||||
}
|
||||
for i in range(2):
|
||||
result = run_module(
|
||||
'tower_job_template',
|
||||
'job_template',
|
||||
dict(name='foo', playbook='helloworld.yml', project=project.name, inventory=inventory.name, survey_spec=spec, survey_enabled=True),
|
||||
admin_user,
|
||||
)
|
||||
@ -236,9 +236,7 @@ def test_associate_only_on_success(run_module, admin_user, organization, project
|
||||
jt.notification_templates_error.add(nt1)
|
||||
|
||||
# test preservation of error NTs when success NTs are added
|
||||
result = run_module(
|
||||
'tower_job_template', dict(name='foo', playbook='helloworld.yml', project=project.name, notification_templates_success=['nt2']), admin_user
|
||||
)
|
||||
result = run_module('job_template', dict(name='foo', playbook='helloworld.yml', project=project.name, notification_templates_success=['nt2']), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed', True), result
|
||||
|
||||
@ -246,7 +244,7 @@ def test_associate_only_on_success(run_module, admin_user, organization, project
|
||||
assert list(jt.notification_templates_error.values_list('id', flat=True)) == [nt1.id]
|
||||
|
||||
# test removal to empty list
|
||||
result = run_module('tower_job_template', dict(name='foo', playbook='helloworld.yml', project=project.name, notification_templates_success=[]), admin_user)
|
||||
result = run_module('job_template', dict(name='foo', playbook='helloworld.yml', project=project.name, notification_templates_success=[]), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed', True), result
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@ from awx.main.models import Label
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_label(run_module, admin_user, organization):
|
||||
result = run_module('tower_label', dict(name='test-label', organization=organization.name), admin_user)
|
||||
result = run_module('label', dict(name='test-label', organization=organization.name), admin_user)
|
||||
assert not result.get('failed'), result.get('msg', result)
|
||||
assert result.get('changed', False)
|
||||
|
||||
@ -18,7 +18,7 @@ def test_create_label(run_module, admin_user, organization):
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_label_using_org_id(run_module, admin_user, organization):
|
||||
result = run_module('tower_label', dict(name='test-label', organization=organization.id), admin_user)
|
||||
result = run_module('label', dict(name='test-label', organization=organization.id), admin_user)
|
||||
assert not result.get('failed'), result.get('msg', result)
|
||||
assert result.get('changed', False)
|
||||
|
||||
@ -29,7 +29,7 @@ def test_create_label_using_org_id(run_module, admin_user, organization):
|
||||
def test_modify_label(run_module, admin_user, organization):
|
||||
label = Label.objects.create(name='test-label', organization=organization)
|
||||
|
||||
result = run_module('tower_label', dict(name='test-label', new_name='renamed-label', organization=organization.name), admin_user)
|
||||
result = run_module('label', dict(name='test-label', new_name='renamed-label', organization=organization.name), admin_user)
|
||||
assert not result.get('failed'), result.get('msg', result)
|
||||
assert result.get('changed', False)
|
||||
|
||||
|
||||
@ -10,12 +10,12 @@ from requests.models import Response
|
||||
from unittest import mock
|
||||
|
||||
awx_name = 'AWX'
|
||||
tower_name = 'Red Hat Ansible Tower'
|
||||
controller_name = 'Red Hat Automation Platform Controller'
|
||||
ping_version = '1.2.3'
|
||||
|
||||
|
||||
def getTowerheader(self, header_name, default):
|
||||
mock_headers = {'X-API-Product-Name': tower_name, 'X-API-Product-Version': ping_version}
|
||||
mock_headers = {'X-API-Product-Name': controller_name, 'X-API-Product-Version': ping_version}
|
||||
return mock_headers.get(header_name, default)
|
||||
|
||||
|
||||
@ -32,7 +32,7 @@ def status(self):
|
||||
return 200
|
||||
|
||||
|
||||
def mock_tower_ping_response(self, method, url, **kwargs):
|
||||
def mock_controller_ping_response(self, method, url, **kwargs):
|
||||
r = Response()
|
||||
r.getheader = getTowerheader.__get__(r)
|
||||
r.read = read.__get__(r)
|
||||
@ -49,12 +49,12 @@ def mock_awx_ping_response(self, method, url, **kwargs):
|
||||
|
||||
|
||||
def test_version_warning(collection_import, silence_warning):
|
||||
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
|
||||
ControllerAPIModule = collection_import('plugins.module_utils.controller_api').ControllerAPIModule
|
||||
cli_data = {'ANSIBLE_MODULE_ARGS': {}}
|
||||
testargs = ['module_file2.py', json.dumps(cli_data)]
|
||||
with mock.patch.object(sys, 'argv', testargs):
|
||||
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_awx_ping_response):
|
||||
my_module = TowerAPIModule(argument_spec=dict())
|
||||
my_module = ControllerAPIModule(argument_spec=dict())
|
||||
my_module._COLLECTION_VERSION = "2.0.0"
|
||||
my_module._COLLECTION_TYPE = "awx"
|
||||
my_module.get_endpoint('ping')
|
||||
@ -64,13 +64,13 @@ def test_version_warning(collection_import, silence_warning):
|
||||
|
||||
|
||||
def test_version_warning_strictness_awx(collection_import, silence_warning):
|
||||
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
|
||||
ControllerAPIModule = collection_import('plugins.module_utils.controller_api').ControllerAPIModule
|
||||
cli_data = {'ANSIBLE_MODULE_ARGS': {}}
|
||||
testargs = ['module_file2.py', json.dumps(cli_data)]
|
||||
# Compare 1.0.0 to 1.2.3 (major matches)
|
||||
with mock.patch.object(sys, 'argv', testargs):
|
||||
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_awx_ping_response):
|
||||
my_module = TowerAPIModule(argument_spec=dict())
|
||||
my_module = ControllerAPIModule(argument_spec=dict())
|
||||
my_module._COLLECTION_VERSION = "1.0.0"
|
||||
my_module._COLLECTION_TYPE = "awx"
|
||||
my_module.get_endpoint('ping')
|
||||
@ -79,47 +79,47 @@ def test_version_warning_strictness_awx(collection_import, silence_warning):
|
||||
# Compare 1.2.0 to 1.2.3 (major matches minor does not count)
|
||||
with mock.patch.object(sys, 'argv', testargs):
|
||||
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_awx_ping_response):
|
||||
my_module = TowerAPIModule(argument_spec=dict())
|
||||
my_module = ControllerAPIModule(argument_spec=dict())
|
||||
my_module._COLLECTION_VERSION = "1.2.0"
|
||||
my_module._COLLECTION_TYPE = "awx"
|
||||
my_module.get_endpoint('ping')
|
||||
silence_warning.assert_not_called()
|
||||
|
||||
|
||||
def test_version_warning_strictness_tower(collection_import, silence_warning):
|
||||
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
|
||||
def test_version_warning_strictness_controller(collection_import, silence_warning):
|
||||
ControllerAPIModule = collection_import('plugins.module_utils.controller_api').ControllerAPIModule
|
||||
cli_data = {'ANSIBLE_MODULE_ARGS': {}}
|
||||
testargs = ['module_file2.py', json.dumps(cli_data)]
|
||||
# Compare 1.2.0 to 1.2.3 (major/minor matches)
|
||||
with mock.patch.object(sys, 'argv', testargs):
|
||||
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_tower_ping_response):
|
||||
my_module = TowerAPIModule(argument_spec=dict())
|
||||
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_controller_ping_response):
|
||||
my_module = ControllerAPIModule(argument_spec=dict())
|
||||
my_module._COLLECTION_VERSION = "1.2.0"
|
||||
my_module._COLLECTION_TYPE = "tower"
|
||||
my_module._COLLECTION_TYPE = "controller"
|
||||
my_module.get_endpoint('ping')
|
||||
silence_warning.assert_not_called()
|
||||
|
||||
# Compare 1.0.0 to 1.2.3 (major/minor fail to match)
|
||||
with mock.patch.object(sys, 'argv', testargs):
|
||||
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_tower_ping_response):
|
||||
my_module = TowerAPIModule(argument_spec=dict())
|
||||
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_controller_ping_response):
|
||||
my_module = ControllerAPIModule(argument_spec=dict())
|
||||
my_module._COLLECTION_VERSION = "1.0.0"
|
||||
my_module._COLLECTION_TYPE = "tower"
|
||||
my_module._COLLECTION_TYPE = "controller"
|
||||
my_module.get_endpoint('ping')
|
||||
silence_warning.assert_called_once_with(
|
||||
'You are running collection version {0} but connecting to {1} version {2}'.format(my_module._COLLECTION_VERSION, tower_name, ping_version)
|
||||
'You are running collection version {0} but connecting to {1} version {2}'.format(my_module._COLLECTION_VERSION, controller_name, ping_version)
|
||||
)
|
||||
|
||||
|
||||
def test_type_warning(collection_import, silence_warning):
|
||||
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
|
||||
ControllerAPIModule = collection_import('plugins.module_utils.controller_api').ControllerAPIModule
|
||||
cli_data = {'ANSIBLE_MODULE_ARGS': {}}
|
||||
testargs = ['module_file2.py', json.dumps(cli_data)]
|
||||
with mock.patch.object(sys, 'argv', testargs):
|
||||
with mock.patch('ansible.module_utils.urls.Request.open', new=mock_awx_ping_response):
|
||||
my_module = TowerAPIModule(argument_spec={})
|
||||
my_module = ControllerAPIModule(argument_spec={})
|
||||
my_module._COLLECTION_VERSION = ping_version
|
||||
my_module._COLLECTION_TYPE = "tower"
|
||||
my_module._COLLECTION_TYPE = "controller"
|
||||
my_module.get_endpoint('ping')
|
||||
silence_warning.assert_called_once_with(
|
||||
'You are using the {0} version of this collection but connecting to {1}'.format(my_module._COLLECTION_TYPE, awx_name)
|
||||
@ -128,20 +128,20 @@ def test_type_warning(collection_import, silence_warning):
|
||||
|
||||
def test_duplicate_config(collection_import, silence_warning):
|
||||
# imports done here because of PATH issues unique to this test suite
|
||||
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
|
||||
data = {'name': 'zigzoom', 'zig': 'zoom', 'tower_username': 'bob', 'tower_config_file': 'my_config'}
|
||||
ControllerAPIModule = collection_import('plugins.module_utils.controller_api').ControllerAPIModule
|
||||
data = {'name': 'zigzoom', 'zig': 'zoom', 'controller_username': 'bob', 'controller_config_file': 'my_config'}
|
||||
|
||||
with mock.patch.object(TowerAPIModule, 'load_config') as mock_load:
|
||||
with mock.patch.object(ControllerAPIModule, 'load_config') as mock_load:
|
||||
argument_spec = dict(
|
||||
name=dict(required=True),
|
||||
zig=dict(type='str'),
|
||||
)
|
||||
TowerAPIModule(argument_spec=argument_spec, direct_params=data)
|
||||
ControllerAPIModule(argument_spec=argument_spec, direct_params=data)
|
||||
assert mock_load.mock_calls[-1] == mock.call('my_config')
|
||||
|
||||
silence_warning.assert_called_once_with(
|
||||
'The parameter(s) tower_username were provided at the same time as '
|
||||
'tower_config_file. Precedence may be unstable, '
|
||||
'The parameter(s) controller_username were provided at the same time as '
|
||||
'controller_config_file. Precedence may be unstable, '
|
||||
'we suggest either using config file or params.'
|
||||
)
|
||||
|
||||
@ -152,12 +152,12 @@ def test_no_templated_values(collection_import):
|
||||
Those replacements should happen at build time, so they should not be
|
||||
checked into source.
|
||||
"""
|
||||
TowerAPIModule = collection_import('plugins.module_utils.tower_api').TowerAPIModule
|
||||
assert TowerAPIModule._COLLECTION_VERSION == "0.0.1-devel", (
|
||||
ControllerAPIModule = collection_import('plugins.module_utils.controller_api').ControllerAPIModule
|
||||
assert ControllerAPIModule._COLLECTION_VERSION == "0.0.1-devel", (
|
||||
'The collection version is templated when the collection is built ' 'and the code should retain the placeholder of "0.0.1-devel".'
|
||||
)
|
||||
InventoryModule = collection_import('plugins.inventory.tower').InventoryModule
|
||||
assert InventoryModule.NAME == 'awx.awx.tower', (
|
||||
InventoryModule = collection_import('plugins.inventory.controller').InventoryModule
|
||||
assert InventoryModule.NAME == 'awx.awx.controller', (
|
||||
'The inventory plugin FQCN is templated when the collection is built ' 'and the code should retain the default of awx.awx.'
|
||||
)
|
||||
|
||||
@ -167,12 +167,12 @@ def test_conflicting_name_and_id(run_module, admin_user):
|
||||
one item has an id that matches input
|
||||
one item has a name that matches input
|
||||
We should preference the id over the name.
|
||||
Otherwise, the universality of the tower_api lookup plugin is compromised.
|
||||
Otherwise, the universality of the controller_api lookup plugin is compromised.
|
||||
"""
|
||||
org_by_id = Organization.objects.create(name='foo')
|
||||
slug = str(org_by_id.id)
|
||||
org_by_name = Organization.objects.create(name=slug)
|
||||
result = run_module('tower_team', {'name': 'foo_team', 'description': 'fooin around', 'organization': slug}, admin_user)
|
||||
result = run_module('team', {'name': 'foo_team', 'description': 'fooin around', 'organization': slug}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
team = Team.objects.filter(name='foo_team').first()
|
||||
assert str(team.organization_id) == slug, 'Lookup by id should be preferenced over name in cases of conflict.'
|
||||
@ -195,9 +195,7 @@ def test_multiple_lookup(run_module, admin_user):
|
||||
scm_type='git',
|
||||
scm_url="https://github.com/ansible/ansible-tower-samples",
|
||||
)
|
||||
result = run_module(
|
||||
'tower_job_template', {'name': 'Demo Job Template', 'project': proj1.name, 'inventory': inv.id, 'playbook': 'hello_world.yml'}, admin_user
|
||||
)
|
||||
result = run_module('job_template', {'name': 'Demo Job Template', 'project': proj1.name, 'inventory': inv.id, 'playbook': 'hello_world.yml'}, admin_user)
|
||||
assert result.get('failed', False)
|
||||
assert 'projects' in result['msg']
|
||||
assert 'foo' in result['msg']
|
||||
|
||||
@ -35,7 +35,7 @@ def test_create_modify_notification_template(run_module, admin_user, organizatio
|
||||
'timeout': 4,
|
||||
}
|
||||
result = run_module(
|
||||
'tower_notification_template',
|
||||
'notification_template',
|
||||
dict(
|
||||
name='foo-notification-template',
|
||||
organization=organization.name,
|
||||
@ -54,7 +54,7 @@ def test_create_modify_notification_template(run_module, admin_user, organizatio
|
||||
# Test no-op, this is impossible if the notification_configuration is given
|
||||
# because we cannot determine if password fields changed
|
||||
result = run_module(
|
||||
'tower_notification_template',
|
||||
'notification_template',
|
||||
dict(
|
||||
name='foo-notification-template',
|
||||
organization=organization.name,
|
||||
@ -68,7 +68,7 @@ def test_create_modify_notification_template(run_module, admin_user, organizatio
|
||||
# Test a change in the configuration
|
||||
nt_config['timeout'] = 12
|
||||
result = run_module(
|
||||
'tower_notification_template',
|
||||
'notification_template',
|
||||
dict(
|
||||
name='foo-notification-template',
|
||||
organization=organization.name,
|
||||
@ -87,7 +87,7 @@ def test_create_modify_notification_template(run_module, admin_user, organizatio
|
||||
@pytest.mark.django_db
|
||||
def test_invalid_notification_configuration(run_module, admin_user, organization):
|
||||
result = run_module(
|
||||
'tower_notification_template',
|
||||
'notification_template',
|
||||
dict(
|
||||
name='foo-notification-template',
|
||||
organization=organization.name,
|
||||
@ -104,7 +104,7 @@ def test_invalid_notification_configuration(run_module, admin_user, organization
|
||||
def test_deprecated_to_modern_no_op(run_module, admin_user, organization):
|
||||
nt_config = {'url': 'http://www.example.com/hook', 'headers': {'X-Custom-Header': 'value123'}}
|
||||
result = run_module(
|
||||
'tower_notification_template',
|
||||
'notification_template',
|
||||
dict(
|
||||
name='foo-notification-template',
|
||||
organization=organization.name,
|
||||
@ -117,7 +117,7 @@ def test_deprecated_to_modern_no_op(run_module, admin_user, organization):
|
||||
assert result.pop('changed', None), result
|
||||
|
||||
result = run_module(
|
||||
'tower_notification_template',
|
||||
'notification_template',
|
||||
dict(
|
||||
name='foo-notification-template',
|
||||
organization=organization.name,
|
||||
@ -142,7 +142,7 @@ def test_build_notification_message_undefined(run_module, admin_user, organizati
|
||||
custom_start_template = {'body': '{"started_by": "{{ job.summary_fields.created_by.username | default(\'My Placeholder\') }}"}'}
|
||||
messages = {'started': custom_start_template, 'success': None, 'error': None, 'workflow_approval': None}
|
||||
result = run_module(
|
||||
'tower_notification_template',
|
||||
'notification_template',
|
||||
dict(
|
||||
name='foo-notification-template',
|
||||
organization=organization.name,
|
||||
|
||||
@ -15,15 +15,15 @@ def test_create_organization(run_module, admin_user):
|
||||
'description': 'barfoo',
|
||||
'state': 'present',
|
||||
'max_hosts': '0',
|
||||
'tower_host': None,
|
||||
'tower_username': None,
|
||||
'tower_password': None,
|
||||
'controller_host': None,
|
||||
'controller_username': None,
|
||||
'controller_password': None,
|
||||
'validate_certs': None,
|
||||
'tower_oauthtoken': None,
|
||||
'tower_config_file': None,
|
||||
'controller_oauthtoken': None,
|
||||
'controller_config_file': None,
|
||||
}
|
||||
|
||||
result = run_module('tower_organization', module_args, admin_user)
|
||||
result = run_module('organization', module_args, admin_user)
|
||||
assert result.get('changed'), result
|
||||
|
||||
org = Organization.objects.get(name='foo')
|
||||
|
||||
@ -10,7 +10,7 @@ from awx.main.models import Project
|
||||
@pytest.mark.django_db
|
||||
def test_create_project(run_module, admin_user, organization, silence_warning):
|
||||
result = run_module(
|
||||
'tower_project',
|
||||
'project',
|
||||
dict(name='foo', organization=organization.name, scm_type='git', scm_url='https://foo.invalid', wait=False, scm_update_cache_timeout=5),
|
||||
admin_user,
|
||||
)
|
||||
|
||||
@ -14,7 +14,7 @@ def test_grant_organization_permission(run_module, admin_user, organization, sta
|
||||
if state == 'absent':
|
||||
organization.admin_role.members.add(rando)
|
||||
|
||||
result = run_module('tower_role', {'user': rando.username, 'organization': organization.name, 'role': 'admin', 'state': state}, admin_user)
|
||||
result = run_module('role', {'user': rando.username, 'organization': organization.name, 'role': 'admin', 'state': state}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
if state == 'present':
|
||||
@ -31,7 +31,7 @@ def test_grant_workflow_permission(run_module, admin_user, organization, state):
|
||||
if state == 'absent':
|
||||
wfjt.execute_role.members.add(rando)
|
||||
|
||||
result = run_module('tower_role', {'user': rando.username, 'workflow': wfjt.name, 'role': 'execute', 'state': state}, admin_user)
|
||||
result = run_module('role', {'user': rando.username, 'workflow': wfjt.name, 'role': 'execute', 'state': state}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
if state == 'present':
|
||||
@ -49,7 +49,7 @@ def test_grant_workflow_list_permission(run_module, admin_user, organization, st
|
||||
wfjt.execute_role.members.add(rando)
|
||||
|
||||
result = run_module(
|
||||
'tower_role',
|
||||
'role',
|
||||
{'user': rando.username, 'lookup_organization': wfjt.organization.name, 'workflows': [wfjt.name], 'role': 'execute', 'state': state},
|
||||
admin_user,
|
||||
)
|
||||
@ -69,7 +69,7 @@ def test_grant_workflow_approval_permission(run_module, admin_user, organization
|
||||
if state == 'absent':
|
||||
wfjt.execute_role.members.add(rando)
|
||||
|
||||
result = run_module('tower_role', {'user': rando.username, 'workflow': wfjt.name, 'role': 'approval', 'state': state}, admin_user)
|
||||
result = run_module('role', {'user': rando.username, 'workflow': wfjt.name, 'role': 'approval', 'state': state}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
if state == 'present':
|
||||
@ -81,7 +81,7 @@ def test_grant_workflow_approval_permission(run_module, admin_user, organization
|
||||
@pytest.mark.django_db
|
||||
def test_invalid_role(run_module, admin_user, project):
|
||||
rando = User.objects.create(username='rando')
|
||||
result = run_module('tower_role', {'user': rando.username, 'project': project.name, 'role': 'adhoc', 'state': 'present'}, admin_user)
|
||||
result = run_module('role', {'user': rando.username, 'project': project.name, 'role': 'adhoc', 'state': 'present'}, admin_user)
|
||||
assert result.get('failed', False)
|
||||
msg = result.get('msg')
|
||||
assert 'has no role adhoc_role' in msg
|
||||
|
||||
@ -13,7 +13,7 @@ from awx.api.serializers import SchedulePreviewSerializer
|
||||
@pytest.mark.django_db
|
||||
def test_create_schedule(run_module, job_template, admin_user):
|
||||
my_rrule = 'DTSTART;TZID=Zulu:20200416T034507 RRULE:FREQ=MONTHLY;INTERVAL=1'
|
||||
result = run_module('tower_schedule', {'name': 'foo_schedule', 'unified_job_template': job_template.name, 'rrule': my_rrule}, admin_user)
|
||||
result = run_module('schedule', {'name': 'foo_schedule', 'unified_job_template': job_template.name, 'rrule': my_rrule}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
schedule = Schedule.objects.filter(name='foo_schedule').first()
|
||||
@ -68,7 +68,7 @@ def test_create_schedule(run_module, job_template, admin_user):
|
||||
],
|
||||
)
|
||||
def test_rrule_lookup_plugin(collection_import, freq, kwargs, expect):
|
||||
LookupModule = collection_import('plugins.lookup.tower_schedule_rrule').LookupModule
|
||||
LookupModule = collection_import('plugins.lookup.schedule_rrule').LookupModule
|
||||
generated_rule = LookupModule.get_rrule(freq, kwargs)
|
||||
assert generated_rule == expect
|
||||
rrule_checker = SchedulePreviewSerializer()
|
||||
@ -79,7 +79,7 @@ def test_rrule_lookup_plugin(collection_import, freq, kwargs, expect):
|
||||
|
||||
@pytest.mark.parametrize("freq", ('none', 'minute', 'hour', 'day', 'week', 'month'))
|
||||
def test_empty_schedule_rrule(collection_import, freq):
|
||||
LookupModule = collection_import('plugins.lookup.tower_schedule_rrule').LookupModule
|
||||
LookupModule = collection_import('plugins.lookup.schedule_rrule').LookupModule
|
||||
if freq == 'day':
|
||||
pfreq = 'DAILY'
|
||||
elif freq == 'none':
|
||||
@ -123,7 +123,7 @@ def test_empty_schedule_rrule(collection_import, freq):
|
||||
],
|
||||
)
|
||||
def test_rrule_lookup_plugin_failure(collection_import, freq, kwargs, msg):
|
||||
LookupModule = collection_import('plugins.lookup.tower_schedule_rrule').LookupModule
|
||||
LookupModule = collection_import('plugins.lookup.schedule_rrule').LookupModule
|
||||
with pytest.raises(AnsibleError) as e:
|
||||
assert LookupModule.get_rrule(freq, kwargs)
|
||||
assert msg in str(e.value)
|
||||
|
||||
@ -1,57 +0,0 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
import pytest
|
||||
import json
|
||||
|
||||
from awx.main.models import Organization, Project, Inventory, Host, CredentialType, Credential, JobTemplate
|
||||
|
||||
|
||||
# warns based on password_management param, but not security issue
|
||||
@pytest.mark.django_db
|
||||
def test_receive_send_jt(run_module, admin_user, mocker, silence_deprecation):
|
||||
org = Organization.objects.create(name='SRtest')
|
||||
proj = Project.objects.create(
|
||||
name='SRtest',
|
||||
playbook_files=['debug.yml'],
|
||||
scm_type='git',
|
||||
scm_url='https://github.com/ansible/test-playbooks.git',
|
||||
organization=org,
|
||||
allow_override=True, # so we do not require playbooks populated
|
||||
)
|
||||
inv = Inventory.objects.create(name='SRtest', organization=org)
|
||||
Host.objects.create(name='SRtest', inventory=inv)
|
||||
ct = CredentialType.defaults['ssh']()
|
||||
ct.save()
|
||||
cred = Credential.objects.create(name='SRtest', credential_type=ct, organization=org)
|
||||
jt = JobTemplate.objects.create(name='SRtest', project=proj, inventory=inv, playbook='helloworld.yml')
|
||||
jt.credentials.add(cred)
|
||||
jt.admin_role.members.add(admin_user) # work around send/receive bug
|
||||
|
||||
# receive everything
|
||||
result = run_module('tower_receive', dict(all=True), admin_user)
|
||||
|
||||
assert 'assets' in result, result
|
||||
assets = result['assets']
|
||||
assert not result.get('changed', True)
|
||||
assert set(a['asset_type'] for a in assets) == set(('organization', 'inventory', 'job_template', 'credential', 'project', 'user'))
|
||||
|
||||
# delete everything
|
||||
for obj in (jt, inv, proj, cred, org):
|
||||
obj.delete()
|
||||
|
||||
def fake_wait(self, pk, parent_pk=None, **kwargs):
|
||||
return {"changed": True}
|
||||
|
||||
# recreate everything
|
||||
with mocker.patch('sys.stdin.isatty', return_value=True):
|
||||
with mocker.patch('tower_cli.models.base.MonitorableResource.wait'):
|
||||
result = run_module('tower_send', dict(assets=json.dumps(assets)), admin_user)
|
||||
|
||||
assert not result.get('failed'), result
|
||||
|
||||
new = JobTemplate.objects.get(name='SRtest')
|
||||
assert new.project.name == 'SRtest'
|
||||
assert new.inventory.name == 'SRtest'
|
||||
assert [cred.name for cred in new.credentials.all()] == ['SRtest']
|
||||
@ -10,7 +10,7 @@ from awx.conf.models import Setting
|
||||
@pytest.mark.django_db
|
||||
def test_setting_flat_value(run_module, admin_user):
|
||||
the_value = 'CN=service_account,OU=ServiceAccounts,DC=domain,DC=company,DC=org'
|
||||
result = run_module('tower_settings', dict(name='AUTH_LDAP_BIND_DN', value=the_value), admin_user)
|
||||
result = run_module('settings', dict(name='AUTH_LDAP_BIND_DN', value=the_value), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed'), result
|
||||
|
||||
@ -20,7 +20,7 @@ def test_setting_flat_value(run_module, admin_user):
|
||||
@pytest.mark.django_db
|
||||
def test_setting_dict_value(run_module, admin_user):
|
||||
the_value = {'email': 'mail', 'first_name': 'givenName', 'last_name': 'surname'}
|
||||
result = run_module('tower_settings', dict(name='AUTH_LDAP_USER_ATTR_MAP', value=the_value), admin_user)
|
||||
result = run_module('settings', dict(name='AUTH_LDAP_USER_ATTR_MAP', value=the_value), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed'), result
|
||||
|
||||
@ -30,7 +30,7 @@ def test_setting_dict_value(run_module, admin_user):
|
||||
@pytest.mark.django_db
|
||||
def test_setting_nested_type(run_module, admin_user):
|
||||
the_value = {'email': 'mail', 'first_name': 'givenName', 'last_name': 'surname'}
|
||||
result = run_module('tower_settings', dict(settings={'AUTH_LDAP_USER_ATTR_MAP': the_value}), admin_user)
|
||||
result = run_module('settings', dict(settings={'AUTH_LDAP_USER_ATTR_MAP': the_value}), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed'), result
|
||||
|
||||
@ -40,7 +40,7 @@ def test_setting_nested_type(run_module, admin_user):
|
||||
@pytest.mark.django_db
|
||||
def test_setting_bool_value(run_module, admin_user):
|
||||
for the_value in (True, False):
|
||||
result = run_module('tower_settings', dict(name='ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC', value=the_value), admin_user)
|
||||
result = run_module('settings', dict(name='ACTIVITY_STREAM_ENABLED_FOR_INVENTORY_SYNC', value=the_value), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed'), result
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ from awx.main.models import Organization, Team
|
||||
def test_create_team(run_module, admin_user):
|
||||
org = Organization.objects.create(name='foo')
|
||||
|
||||
result = run_module('tower_team', {'name': 'foo_team', 'description': 'fooin around', 'state': 'present', 'organization': 'foo'}, admin_user)
|
||||
result = run_module('team', {'name': 'foo_team', 'description': 'fooin around', 'state': 'present', 'organization': 'foo'}, admin_user)
|
||||
|
||||
team = Team.objects.filter(name='foo_team').first()
|
||||
|
||||
@ -32,7 +32,7 @@ def test_modify_team(run_module, admin_user):
|
||||
team = Team.objects.create(name='foo_team', organization=org, description='flat foo')
|
||||
assert team.description == 'flat foo'
|
||||
|
||||
result = run_module('tower_team', {'name': 'foo_team', 'description': 'fooin around', 'organization': 'foo'}, admin_user)
|
||||
result = run_module('team', {'name': 'foo_team', 'description': 'fooin around', 'organization': 'foo'}, admin_user)
|
||||
team.refresh_from_db()
|
||||
result.pop('invocation')
|
||||
assert result == {
|
||||
@ -42,6 +42,6 @@ def test_modify_team(run_module, admin_user):
|
||||
assert team.description == 'fooin around'
|
||||
|
||||
# 2nd modification, should cause no change
|
||||
result = run_module('tower_team', {'name': 'foo_team', 'description': 'fooin around', 'organization': 'foo'}, admin_user)
|
||||
result = run_module('team', {'name': 'foo_team', 'description': 'fooin around', 'organization': 'foo'}, admin_user)
|
||||
result.pop('invocation')
|
||||
assert result == {"id": team.id, "changed": False}
|
||||
|
||||
@ -14,15 +14,15 @@ def test_create_token(run_module, admin_user):
|
||||
'description': 'barfoo',
|
||||
'state': 'present',
|
||||
'scope': 'read',
|
||||
'tower_host': None,
|
||||
'tower_username': None,
|
||||
'tower_password': None,
|
||||
'controller_host': None,
|
||||
'controller_username': None,
|
||||
'controller_password': None,
|
||||
'validate_certs': None,
|
||||
'tower_oauthtoken': None,
|
||||
'tower_config_file': None,
|
||||
'controller_oauthtoken': None,
|
||||
'controller_config_file': None,
|
||||
}
|
||||
|
||||
result = run_module('tower_token', module_args, admin_user)
|
||||
result = run_module('token', module_args, admin_user)
|
||||
assert result.get('changed'), result
|
||||
|
||||
tokens = OAuth2AccessToken.objects.filter(description='barfoo')
|
||||
|
||||
@ -20,7 +20,7 @@ def mock_auth_stuff():
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_user(run_module, admin_user, mock_auth_stuff):
|
||||
result = run_module('tower_user', dict(username='Bob', password='pass4word'), admin_user)
|
||||
result = run_module('user', dict(username='Bob', password='pass4word'), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed'), result
|
||||
|
||||
@ -31,7 +31,7 @@ def test_create_user(run_module, admin_user, mock_auth_stuff):
|
||||
@pytest.mark.django_db
|
||||
def test_password_no_op_warning(run_module, admin_user, mock_auth_stuff, silence_warning):
|
||||
for i in range(2):
|
||||
result = run_module('tower_user', dict(username='Bob', password='pass4word'), admin_user)
|
||||
result = run_module('user', dict(username='Bob', password='pass4word'), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
assert result.get('changed') # not actually desired, but assert for sanity
|
||||
@ -44,7 +44,7 @@ def test_password_no_op_warning(run_module, admin_user, mock_auth_stuff, silence
|
||||
@pytest.mark.django_db
|
||||
def test_update_password_on_create(run_module, admin_user, mock_auth_stuff):
|
||||
for i in range(2):
|
||||
result = run_module('tower_user', dict(username='Bob', password='pass4word', update_secrets=False), admin_user)
|
||||
result = run_module('user', dict(username='Bob', password='pass4word', update_secrets=False), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
assert not result.get('changed')
|
||||
@ -52,11 +52,11 @@ def test_update_password_on_create(run_module, admin_user, mock_auth_stuff):
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_update_user(run_module, admin_user, mock_auth_stuff):
|
||||
result = run_module('tower_user', dict(username='Bob', password='pass4word', is_system_auditor=True), admin_user)
|
||||
result = run_module('user', dict(username='Bob', password='pass4word', is_system_auditor=True), admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed'), result
|
||||
|
||||
update_result = run_module('tower_user', dict(username='Bob', is_system_auditor=False), admin_user)
|
||||
update_result = run_module('user', dict(username='Bob', is_system_auditor=False), admin_user)
|
||||
|
||||
assert update_result.get('changed')
|
||||
user = User.objects.get(id=result['id'])
|
||||
|
||||
@ -10,7 +10,7 @@ from awx.main.models import WorkflowJobTemplate, NotificationTemplate
|
||||
@pytest.mark.django_db
|
||||
def test_create_workflow_job_template(run_module, admin_user, organization, survey_spec):
|
||||
result = run_module(
|
||||
'tower_workflow_job_template',
|
||||
'workflow_job_template',
|
||||
{
|
||||
'name': 'foo-workflow',
|
||||
'organization': organization.name,
|
||||
@ -35,7 +35,7 @@ def test_create_workflow_job_template(run_module, admin_user, organization, surv
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_modify_no_survey(run_module, admin_user, organization, survey_spec):
|
||||
result = run_module('tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name}, admin_user)
|
||||
result = run_module('workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed', False), result
|
||||
|
||||
@ -45,7 +45,7 @@ def test_create_modify_no_survey(run_module, admin_user, organization, survey_sp
|
||||
result.pop('invocation', None)
|
||||
assert result == {"name": "foo-workflow", "id": wfjt.id, "changed": True}
|
||||
|
||||
result = run_module('tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name}, admin_user)
|
||||
result = run_module('workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert not result.get('changed', True), result
|
||||
|
||||
@ -53,7 +53,7 @@ def test_create_modify_no_survey(run_module, admin_user, organization, survey_sp
|
||||
@pytest.mark.django_db
|
||||
def test_survey_spec_only_changed(run_module, admin_user, organization, survey_spec):
|
||||
wfjt = WorkflowJobTemplate.objects.create(organization=organization, name='foo-workflow', survey_enabled=True, survey_spec=survey_spec)
|
||||
result = run_module('tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'state': 'present'}, admin_user)
|
||||
result = run_module('workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'state': 'present'}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert not result.get('changed', True), result
|
||||
wfjt.refresh_from_db()
|
||||
@ -62,7 +62,7 @@ def test_survey_spec_only_changed(run_module, admin_user, organization, survey_s
|
||||
survey_spec['description'] = 'changed description'
|
||||
|
||||
result = run_module(
|
||||
'tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'survey_spec': survey_spec, 'state': 'present'}, admin_user
|
||||
'workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'survey_spec': survey_spec, 'state': 'present'}, admin_user
|
||||
)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed', True), result
|
||||
@ -73,7 +73,7 @@ def test_survey_spec_only_changed(run_module, admin_user, organization, survey_s
|
||||
@pytest.mark.django_db
|
||||
def test_survey_spec_only_changed(run_module, admin_user, organization, survey_spec):
|
||||
wfjt = WorkflowJobTemplate.objects.create(organization=organization, name='foo-workflow', survey_enabled=True, survey_spec=survey_spec)
|
||||
result = run_module('tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'state': 'present'}, admin_user)
|
||||
result = run_module('workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'state': 'present'}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert not result.get('changed', True), result
|
||||
wfjt.refresh_from_db()
|
||||
@ -82,7 +82,7 @@ def test_survey_spec_only_changed(run_module, admin_user, organization, survey_s
|
||||
del survey_spec['description']
|
||||
|
||||
result = run_module(
|
||||
'tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'survey_spec': survey_spec, 'state': 'present'}, admin_user
|
||||
'workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'survey_spec': survey_spec, 'state': 'present'}, admin_user
|
||||
)
|
||||
assert result.get('failed', True)
|
||||
assert result.get('msg') == "Failed to update survey: Field 'description' is missing from survey spec."
|
||||
@ -107,7 +107,7 @@ def test_associate_only_on_success(run_module, admin_user, organization, project
|
||||
|
||||
# test preservation of error NTs when success NTs are added
|
||||
result = run_module(
|
||||
'tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'notification_templates_success': ['nt2']}, admin_user
|
||||
'workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'notification_templates_success': ['nt2']}, admin_user
|
||||
)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed', True), result
|
||||
@ -116,9 +116,7 @@ def test_associate_only_on_success(run_module, admin_user, organization, project
|
||||
assert list(wfjt.notification_templates_error.values_list('id', flat=True)) == [nt1.id]
|
||||
|
||||
# test removal to empty list
|
||||
result = run_module(
|
||||
'tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'notification_templates_success': []}, admin_user
|
||||
)
|
||||
result = run_module('workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'notification_templates_success': []}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed', True), result
|
||||
|
||||
@ -129,7 +127,7 @@ def test_associate_only_on_success(run_module, admin_user, organization, project
|
||||
@pytest.mark.django_db
|
||||
def test_delete_with_spec(run_module, admin_user, organization, survey_spec):
|
||||
WorkflowJobTemplate.objects.create(organization=organization, name='foo-workflow', survey_enabled=True, survey_spec=survey_spec)
|
||||
result = run_module('tower_workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'state': 'absent'}, admin_user)
|
||||
result = run_module('workflow_job_template', {'name': 'foo-workflow', 'organization': organization.name, 'state': 'absent'}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
assert result.get('changed', True), result
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ def wfjt(organization):
|
||||
def test_create_workflow_job_template_node(run_module, admin_user, wfjt, job_template):
|
||||
this_identifier = '42🐉'
|
||||
result = run_module(
|
||||
'tower_workflow_job_template_node',
|
||||
'workflow_job_template_node',
|
||||
{
|
||||
'identifier': this_identifier,
|
||||
'workflow_job_template': 'foo-workflow',
|
||||
@ -58,7 +58,7 @@ def test_create_workflow_job_template_node_approval_node(run_module, admin_user,
|
||||
"""This is a part of the API contract for creating approval nodes"""
|
||||
this_identifier = '42🐉'
|
||||
result = run_module(
|
||||
'tower_workflow_job_template_node',
|
||||
'workflow_job_template_node',
|
||||
{
|
||||
'identifier': this_identifier,
|
||||
'workflow_job_template': wfjt.name,
|
||||
@ -83,7 +83,7 @@ def test_create_workflow_job_template_node_approval_node(run_module, admin_user,
|
||||
@pytest.mark.django_db
|
||||
def test_make_use_of_prompts(run_module, admin_user, wfjt, job_template, machine_credential, vault_credential):
|
||||
result = run_module(
|
||||
'tower_workflow_job_template_node',
|
||||
'workflow_job_template_node',
|
||||
{
|
||||
'identifier': '42',
|
||||
'workflow_job_template': 'foo-workflow',
|
||||
@ -113,7 +113,7 @@ def test_create_with_edges(run_module, admin_user, wfjt, job_template):
|
||||
]
|
||||
|
||||
result = run_module(
|
||||
'tower_workflow_job_template_node',
|
||||
'workflow_job_template_node',
|
||||
{
|
||||
'identifier': '42',
|
||||
'workflow_job_template': 'foo-workflow',
|
||||
|
||||
@ -1,102 +0,0 @@
|
||||
from __future__ import absolute_import, division, print_function
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
import pytest
|
||||
|
||||
from awx.main.models import WorkflowJobTemplate, JobTemplate, Project, InventorySource, Inventory, WorkflowJobTemplateNode
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_create_workflow_job_template(run_module, admin_user, organization, survey_spec, silence_deprecation):
|
||||
result = run_module(
|
||||
'tower_workflow_template',
|
||||
{
|
||||
'name': 'foo-workflow',
|
||||
'organization': organization.name,
|
||||
'extra_vars': {'foo': 'bar', 'another-foo': {'barz': 'bar2'}},
|
||||
'survey': survey_spec,
|
||||
'survey_enabled': True,
|
||||
'state': 'present',
|
||||
},
|
||||
admin_user,
|
||||
)
|
||||
|
||||
wfjt = WorkflowJobTemplate.objects.get(name='foo-workflow')
|
||||
assert wfjt.extra_vars == '{"foo": "bar", "another-foo": {"barz": "bar2"}}'
|
||||
|
||||
result.pop('invocation', None)
|
||||
assert result == {"workflow_template": "foo-workflow", "state": "present", "id": wfjt.id, "changed": True} # TODO: remove after refactor
|
||||
|
||||
assert wfjt.organization_id == organization.id
|
||||
assert wfjt.survey_spec == survey_spec
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_with_nested_workflow(run_module, admin_user, organization, silence_deprecation):
|
||||
wfjt1 = WorkflowJobTemplate.objects.create(name='first', organization=organization)
|
||||
|
||||
result = run_module(
|
||||
'tower_workflow_template',
|
||||
{'name': 'foo-workflow', 'organization': organization.name, 'schema': [{'workflow': wfjt1.name}], 'state': 'present'},
|
||||
admin_user,
|
||||
)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
wfjt = WorkflowJobTemplate.objects.get(name='foo-workflow')
|
||||
node = wfjt.workflow_nodes.first()
|
||||
assert node is not None
|
||||
assert node.unified_job_template == wfjt1
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_schema_with_branches(run_module, admin_user, organization, silence_deprecation):
|
||||
|
||||
proj = Project.objects.create(organization=organization, name='Ansible Examples')
|
||||
inv = Inventory.objects.create(organization=organization, name='test-inv')
|
||||
jt = JobTemplate.objects.create(project=proj, playbook='helloworld.yml', inventory=inv, name='Hello world')
|
||||
inv_src = InventorySource.objects.create(inventory=inv, name='AWS servers', source='ec2')
|
||||
|
||||
result = run_module(
|
||||
'tower_workflow_template',
|
||||
{
|
||||
'name': 'foo-workflow',
|
||||
'organization': organization.name,
|
||||
'schema': [
|
||||
{
|
||||
'job_template': 'Hello world',
|
||||
'failure': [{'inventory_source': 'AWS servers', 'success': [{'project': 'Ansible Examples', 'always': [{'job_template': "Hello world"}]}]}],
|
||||
}
|
||||
],
|
||||
'state': 'present',
|
||||
},
|
||||
admin_user,
|
||||
)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
wfjt = WorkflowJobTemplate.objects.get(name='foo-workflow')
|
||||
root_nodes = wfjt.workflow_nodes.filter(
|
||||
**{
|
||||
'%ss_success__isnull' % WorkflowJobTemplateNode.__name__.lower(): True,
|
||||
'%ss_failure__isnull' % WorkflowJobTemplateNode.__name__.lower(): True,
|
||||
'%ss_always__isnull' % WorkflowJobTemplateNode.__name__.lower(): True,
|
||||
}
|
||||
)
|
||||
assert len(root_nodes) == 1
|
||||
node = root_nodes[0]
|
||||
assert node.unified_job_template == jt
|
||||
second = node.failure_nodes.first()
|
||||
assert second.unified_job_template == inv_src
|
||||
third = second.success_nodes.first()
|
||||
assert third.unified_job_template == proj
|
||||
fourth = third.always_nodes.first()
|
||||
assert fourth.unified_job_template == jt
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_with_missing_ujt(run_module, admin_user, organization, silence_deprecation):
|
||||
result = run_module(
|
||||
'tower_workflow_template', {'name': 'foo-workflow', 'organization': organization.name, 'schema': [{'foo': 'bar'}], 'state': 'present'}, admin_user
|
||||
)
|
||||
assert result.get('failed', False), result
|
||||
assert 'You should provide exactly one of the attributes job_template,' in result['msg']
|
||||
@ -6,36 +6,36 @@
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
inv_name: "AWX-Collection-tests-tower_tower_ad_hoc_command-inventory-{{ test_id }}"
|
||||
ssh_cred_name: "AWX-Collection-tests-tower_tower_ad_hoc_command-ssh-cred-{{ test_id }}"
|
||||
org_name: "AWX-Collection-tests-tower_tower_ad_hoc_command-org-{{ test_id }}"
|
||||
inv_name: "AWX-Collection-tests-ad_hoc_command-inventory-{{ test_id }}"
|
||||
ssh_cred_name: "AWX-Collection-tests-ad_hoc_command-ssh-cred-{{ test_id }}"
|
||||
org_name: "AWX-Collection-tests-ad_hoc_command-org-{{ test_id }}"
|
||||
|
||||
- name: Create a New Organization
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ org_name }}"
|
||||
|
||||
- name: Create an Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
state: present
|
||||
|
||||
- name: Add localhost to the Inventory
|
||||
tower_host:
|
||||
host:
|
||||
name: localhost
|
||||
inventory: "{{ inv_name }}"
|
||||
variables:
|
||||
ansible_connection: local
|
||||
|
||||
- name: Create a Credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
credential_type: 'Machine'
|
||||
state: present
|
||||
|
||||
- name: Launch an Ad Hoc Command waiting for it to finish
|
||||
tower_ad_hoc_command:
|
||||
ad_hoc_command:
|
||||
inventory: "{{ inv_name }}"
|
||||
credential: "{{ ssh_cred_name }}"
|
||||
module_name: "command"
|
||||
@ -49,7 +49,7 @@
|
||||
- "result.status == 'successful'"
|
||||
|
||||
- name: Launch an Ad Hoc Command without module argument
|
||||
tower_ad_hoc_command:
|
||||
ad_hoc_command:
|
||||
inventory: "Demo Inventory"
|
||||
credential: "{{ ssh_cred_name }}"
|
||||
module_name: "ping"
|
||||
@ -62,7 +62,7 @@
|
||||
- "result.status == 'successful'"
|
||||
|
||||
- name: Check module fails with correct msg
|
||||
tower_ad_hoc_command:
|
||||
ad_hoc_command:
|
||||
inventory: "{{ inv_name }}"
|
||||
credential: "{{ ssh_cred_name }}"
|
||||
module_name: "Does not exist"
|
||||
@ -76,19 +76,19 @@
|
||||
- "'Does not exist' in result.response['json']['module_name'][0]"
|
||||
|
||||
- name: Delete the Credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
credential_type: 'Machine'
|
||||
state: absent
|
||||
|
||||
- name: Delete the Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove the Organization
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ org_name }}"
|
||||
state: absent
|
||||
@ -6,36 +6,36 @@
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
inv_name: "AWX-Collection-tests-tower_tower_ad_hoc_command_cancel-inventory-{{ test_id }}"
|
||||
ssh_cred_name: "AWX-Collection-tests-tower_tower_ad_hoc_command_cancel-ssh-cred-{{ test_id }}"
|
||||
org_name: "AWX-Collection-tests-tower_tower_ad_hoc_command_cancel-org-{{ test_id }}"
|
||||
inv_name: "AWX-Collection-tests-ad_hoc_command_cancel-inventory-{{ test_id }}"
|
||||
ssh_cred_name: "AWX-Collection-tests-ad_hoc_command_cancel-ssh-cred-{{ test_id }}"
|
||||
org_name: "AWX-Collection-tests-ad_hoc_command_cancel-org-{{ test_id }}"
|
||||
|
||||
- name: Create a New Organization
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ org_name }}"
|
||||
|
||||
- name: Create an Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
state: present
|
||||
|
||||
- name: Add localhost to the Inventory
|
||||
tower_host:
|
||||
host:
|
||||
name: localhost
|
||||
inventory: "{{ inv_name }}"
|
||||
variables:
|
||||
ansible_connection: local
|
||||
|
||||
- name: Create a Credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
credential_type: 'Machine'
|
||||
state: present
|
||||
|
||||
- name: Launch an Ad Hoc Command
|
||||
tower_ad_hoc_command:
|
||||
ad_hoc_command:
|
||||
inventory: "{{ inv_name }}"
|
||||
credential: "{{ ssh_cred_name }}"
|
||||
module_name: "command"
|
||||
@ -47,7 +47,7 @@
|
||||
- "command is changed"
|
||||
|
||||
- name: Timeout waiting for the command to cancel
|
||||
tower_ad_hoc_command_cancel:
|
||||
ad_hoc_command_cancel:
|
||||
command_id: "{{ command.id }}"
|
||||
timeout: -1
|
||||
register: results
|
||||
@ -59,7 +59,7 @@
|
||||
- "results['msg'] == 'Monitoring of ad hoc command aborted due to timeout'"
|
||||
|
||||
- name: Cancel the command with hard error if it's not running
|
||||
tower_ad_hoc_command_cancel:
|
||||
ad_hoc_command_cancel:
|
||||
command_id: "{{ command.id }}"
|
||||
fail_if_not_running: true
|
||||
register: results
|
||||
@ -70,7 +70,7 @@
|
||||
- results is failed
|
||||
|
||||
- name: Cancel an already canceled command (assert failure)
|
||||
tower_ad_hoc_command_cancel:
|
||||
ad_hoc_command_cancel:
|
||||
command_id: "{{ command.id }}"
|
||||
fail_if_not_running: true
|
||||
register: results
|
||||
@ -81,7 +81,7 @@
|
||||
- results is failed
|
||||
|
||||
- name: Check module fails with correct msg
|
||||
tower_ad_hoc_command_cancel:
|
||||
ad_hoc_command_cancel:
|
||||
command_id: 9999999999
|
||||
register: result
|
||||
ignore_errors: true
|
||||
@ -91,19 +91,19 @@
|
||||
- "result.msg == 'Unable to find command with id 9999999999'"
|
||||
|
||||
- name: Delete the Credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
credential_type: 'Machine'
|
||||
state: absent
|
||||
|
||||
- name: Delete the Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove the Organization
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ org_name }}"
|
||||
state: absent
|
||||
@ -6,36 +6,36 @@
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
inv_name: "AWX-Collection-tests-tower_ad_hoc_command_wait-inventory-{{ test_id }}"
|
||||
ssh_cred_name: "AWX-Collection-tests-tower_ad_hoc_command_wait-ssh-cred-{{ test_id }}"
|
||||
org_name: "AWX-Collection-tests-tower_ad_hoc_command_wait-org-{{ test_id }}"
|
||||
inv_name: "AWX-Collection-tests-ad_hoc_command_wait-inventory-{{ test_id }}"
|
||||
ssh_cred_name: "AWX-Collection-tests-ad_hoc_command_wait-ssh-cred-{{ test_id }}"
|
||||
org_name: "AWX-Collection-tests-ad_hoc_command_wait-org-{{ test_id }}"
|
||||
|
||||
- name: Create a New Organization
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ org_name }}"
|
||||
|
||||
- name: Create an Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
state: present
|
||||
|
||||
- name: Add localhost to the Inventory
|
||||
tower_host:
|
||||
host:
|
||||
name: localhost
|
||||
inventory: "{{ inv_name }}"
|
||||
variables:
|
||||
ansible_connection: local
|
||||
|
||||
- name: Create a Credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
credential_type: 'Machine'
|
||||
state: present
|
||||
|
||||
- name: Check module fails with correct msg
|
||||
tower_ad_hoc_command_wait:
|
||||
ad_hoc_command_wait:
|
||||
command_id: "99999999"
|
||||
register: result
|
||||
ignore_errors: true
|
||||
@ -43,10 +43,10 @@
|
||||
- assert:
|
||||
that:
|
||||
- result is failed
|
||||
- "result.msg == 'Unable to wait on ad hoc command 99999999; that ID does not exist in Tower.'"
|
||||
- "result.msg == 'Unable to wait on ad hoc command 99999999; that ID does not exist.'"
|
||||
|
||||
- name: Launch command module with sleep 10
|
||||
tower_ad_hoc_command:
|
||||
ad_hoc_command:
|
||||
inventory: "{{ inv_name }}"
|
||||
credential: "{{ ssh_cred_name }}"
|
||||
module_name: "command"
|
||||
@ -58,7 +58,7 @@
|
||||
- command is changed
|
||||
|
||||
- name: Wait for the Job to finish
|
||||
tower_ad_hoc_command_wait:
|
||||
ad_hoc_command_wait:
|
||||
command_id: "{{ command.id }}"
|
||||
register: wait_results
|
||||
|
||||
@ -70,7 +70,7 @@
|
||||
- "'id' in wait_results"
|
||||
|
||||
- name: Launch a long running command
|
||||
tower_ad_hoc_command:
|
||||
ad_hoc_command:
|
||||
inventory: "{{ inv_name }}"
|
||||
credential: "{{ ssh_cred_name }}"
|
||||
module_name: "command"
|
||||
@ -82,7 +82,7 @@
|
||||
- command is changed
|
||||
|
||||
- name: Timeout waiting for the command to complete
|
||||
tower_ad_hoc_command_wait:
|
||||
ad_hoc_command_wait:
|
||||
command_id: "{{ command.id }}"
|
||||
timeout: 1
|
||||
ignore_errors: true
|
||||
@ -95,13 +95,13 @@
|
||||
- "'id' in wait_results"
|
||||
|
||||
- name: Async cancel the long-running command
|
||||
tower_ad_hoc_command_cancel:
|
||||
ad_hoc_command_cancel:
|
||||
command_id: "{{ command.id }}"
|
||||
async: 3600
|
||||
poll: 0
|
||||
|
||||
- name: Wait for the command to exit on cancel
|
||||
tower_ad_hoc_command_wait:
|
||||
ad_hoc_command_wait:
|
||||
command_id: "{{ command.id }}"
|
||||
register: wait_results
|
||||
ignore_errors: true
|
||||
@ -113,19 +113,19 @@
|
||||
- "wait_results.msg == 'The ad hoc command - {{ command.id }}, failed'"
|
||||
|
||||
- name: Delete the Credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
credential_type: 'Machine'
|
||||
state: absent
|
||||
|
||||
- name: Delete the Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: "{{ org_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove the Organization
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ org_name }}"
|
||||
state: absent
|
||||
@ -5,13 +5,13 @@
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
app1_name: "AWX-Collection-tests-tower_application-app1-{{ test_id }}"
|
||||
app2_name: "AWX-Collection-tests-tower_application-app2-{{ test_id }}"
|
||||
app3_name: "AWX-Collection-tests-tower_application-app3-{{ test_id }}"
|
||||
app1_name: "AWX-Collection-tests-application-app1-{{ test_id }}"
|
||||
app2_name: "AWX-Collection-tests-application-app2-{{ test_id }}"
|
||||
app3_name: "AWX-Collection-tests-application-app3-{{ test_id }}"
|
||||
|
||||
- block:
|
||||
- name: Create an application
|
||||
tower_application:
|
||||
application:
|
||||
name: "{{ app1_name }}"
|
||||
authorization_grant_type: "password"
|
||||
client_type: "public"
|
||||
@ -24,7 +24,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete our application
|
||||
tower_application:
|
||||
application:
|
||||
name: "{{ app1_name }}"
|
||||
organization: "Default"
|
||||
state: absent
|
||||
@ -35,7 +35,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a second application
|
||||
tower_application:
|
||||
application:
|
||||
name: "{{ app2_name }}"
|
||||
authorization_grant_type: "authorization-code"
|
||||
client_type: "confidential"
|
||||
@ -52,7 +52,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create an all trusting application
|
||||
tower_application:
|
||||
application:
|
||||
name: "{{ app3_name }}"
|
||||
organization: "Default"
|
||||
description: "All Trusting Application"
|
||||
@ -68,7 +68,7 @@
|
||||
|
||||
always:
|
||||
- name: Delete our application
|
||||
tower_application:
|
||||
application:
|
||||
name: "{{ item }}"
|
||||
organization: "Default"
|
||||
state: absent
|
||||
@ -6,23 +6,23 @@
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
ssh_cred_name1: "AWX-Collection-tests-tower_credential-ssh-cred1-{{ test_id }}"
|
||||
ssh_cred_name2: "AWX-Collection-tests-tower_credential-ssh-cred2-{{ test_id }}"
|
||||
ssh_cred_name3: "AWX-Collection-tests-tower_credential-ssh-cred-lookup-source-{{ test_id }}"
|
||||
ssh_cred_name4: "AWX-Collection-tests-tower_credential-ssh-cred-file-source-{{ test_id }}"
|
||||
vault_cred_name1: "AWX-Collection-tests-tower_credential-vault-cred1-{{ test_id }}"
|
||||
vault_cred_name2: "AWX-Collection-tests-tower_credential-vault-ssh-cred1-{{ test_id }}"
|
||||
net_cred_name1: "AWX-Collection-tests-tower_credential-net-cred1-{{ test_id }}"
|
||||
scm_cred_name1: "AWX-Collection-tests-tower_credential-scm-cred1-{{ test_id }}"
|
||||
aws_cred_name1: "AWX-Collection-tests-tower_credential-aws-cred1-{{ test_id }}"
|
||||
vmware_cred_name1: "AWX-Collection-tests-tower_credential-vmware-cred1-{{ test_id }}"
|
||||
sat6_cred_name1: "AWX-Collection-tests-tower_credential-sat6-cred1-{{ test_id }}"
|
||||
gce_cred_name1: "AWX-Collection-tests-tower_credential-gce-cred1-{{ test_id }}"
|
||||
azurerm_cred_name1: "AWX-Collection-tests-tower_credential-azurerm-cred1-{{ test_id }}"
|
||||
openstack_cred_name1: "AWX-Collection-tests-tower_credential-openstack-cred1-{{ test_id }}"
|
||||
rhv_cred_name1: "AWX-Collection-tests-tower_credential-rhv-cred1-{{ test_id }}"
|
||||
insights_cred_name1: "AWX-Collection-tests-tower_credential-insights-cred1-{{ test_id }}"
|
||||
tower_cred_name1: "AWX-Collection-tests-tower_credential-tower-cred1-{{ test_id }}"
|
||||
ssh_cred_name1: "AWX-Collection-tests-credential-ssh-cred1-{{ test_id }}"
|
||||
ssh_cred_name2: "AWX-Collection-tests-credential-ssh-cred2-{{ test_id }}"
|
||||
ssh_cred_name3: "AWX-Collection-tests-credential-ssh-cred-lookup-source-{{ test_id }}"
|
||||
ssh_cred_name4: "AWX-Collection-tests-credential-ssh-cred-file-source-{{ test_id }}"
|
||||
vault_cred_name1: "AWX-Collection-tests-credential-vault-cred1-{{ test_id }}"
|
||||
vault_cred_name2: "AWX-Collection-tests-credential-vault-ssh-cred1-{{ test_id }}"
|
||||
net_cred_name1: "AWX-Collection-tests-credential-net-cred1-{{ test_id }}"
|
||||
scm_cred_name1: "AWX-Collection-tests-credential-scm-cred1-{{ test_id }}"
|
||||
aws_cred_name1: "AWX-Collection-tests-credential-aws-cred1-{{ test_id }}"
|
||||
vmware_cred_name1: "AWX-Collection-tests-credential-vmware-cred1-{{ test_id }}"
|
||||
sat6_cred_name1: "AWX-Collection-tests-credential-sat6-cred1-{{ test_id }}"
|
||||
gce_cred_name1: "AWX-Collection-tests-credential-gce-cred1-{{ test_id }}"
|
||||
azurerm_cred_name1: "AWX-Collection-tests-credential-azurerm-cred1-{{ test_id }}"
|
||||
openstack_cred_name1: "AWX-Collection-tests-credential-openstack-cred1-{{ test_id }}"
|
||||
rhv_cred_name1: "AWX-Collection-tests-credential-rhv-cred1-{{ test_id }}"
|
||||
insights_cred_name1: "AWX-Collection-tests-credential-insights-cred1-{{ test_id }}"
|
||||
tower_cred_name1: "AWX-Collection-tests-credential-tower-cred1-{{ test_id }}"
|
||||
|
||||
- name: create a tempdir for an SSH key
|
||||
local_action: shell mktemp -d
|
||||
@ -36,7 +36,7 @@
|
||||
ssh_key_data: "{{ lookup('file', tempdir.stdout + '/id_rsa') }}"
|
||||
|
||||
- name: Test deprecation warnings
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name1 }}"
|
||||
organization: Default
|
||||
kind: ssh
|
||||
@ -70,7 +70,7 @@
|
||||
- result['deprecations'] | length() == 20
|
||||
|
||||
- name: Create an Org-specific credential (old school)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -82,7 +82,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Re-create the Org-specific credential (new school) with an ID
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ result.id }}"
|
||||
organization: Default
|
||||
credential_type: 'Machine'
|
||||
@ -94,7 +94,7 @@
|
||||
- "result is not changed"
|
||||
|
||||
- name: Delete a Org-specific credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -106,7 +106,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create the User-specific credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name1 }}"
|
||||
user: admin
|
||||
credential_type: 'Machine'
|
||||
@ -118,7 +118,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a User-specific credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name1 }}"
|
||||
user: admin
|
||||
state: absent
|
||||
@ -130,7 +130,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid SSH credential (old school)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name2 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -150,7 +150,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid SSH credential (new school)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name2 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -173,7 +173,7 @@
|
||||
- result is changed
|
||||
|
||||
- name: Create a valid SSH credential (new school)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name2 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -191,7 +191,7 @@
|
||||
- result is changed
|
||||
|
||||
- name: Check for inputs idempotency (when "inputs" is blank)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name2 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -204,7 +204,7 @@
|
||||
- result is not changed
|
||||
|
||||
- name: Copy ssh Credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "copy_{{ ssh_cred_name2 }}"
|
||||
copy_from: "{{ ssh_cred_name2 }}"
|
||||
credential_type: Machine
|
||||
@ -215,7 +215,7 @@
|
||||
- result.copied
|
||||
|
||||
- name: Delete an SSH credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "copy_{{ ssh_cred_name2 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -227,7 +227,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid SSH credential from lookup source (old school)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name3 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -247,7 +247,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid SSH credential from lookup source (new school)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name3 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -269,7 +269,7 @@
|
||||
- result is changed
|
||||
|
||||
- name: Fail to create an SSH credential from a file source (old school format)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name4 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -292,7 +292,7 @@
|
||||
- "'Invalid certificate or key' in result.msg"
|
||||
|
||||
- name: Create an invalid SSH credential (passphrase required)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: SSH Credential
|
||||
organization: Default
|
||||
state: present
|
||||
@ -308,7 +308,7 @@
|
||||
- "'must be set when SSH key is encrypted' in result.msg"
|
||||
|
||||
- name: Create an invalid SSH credential (Organization not found)
|
||||
tower_credential:
|
||||
credential:
|
||||
name: SSH Credential
|
||||
organization: Missing_Organization
|
||||
state: present
|
||||
@ -325,7 +325,7 @@
|
||||
- "result.total_results == 0"
|
||||
|
||||
- name: Delete an SSH credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name2 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -337,7 +337,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an SSH credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name3 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -349,7 +349,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an SSH credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ ssh_cred_name4 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -362,7 +362,7 @@
|
||||
- "result is not changed"
|
||||
|
||||
- name: Create a valid Vault credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ vault_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -376,7 +376,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Vault credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ vault_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -388,7 +388,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Vault credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ vault_cred_name2 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -401,7 +401,7 @@
|
||||
- "result is not changed"
|
||||
|
||||
- name: Create a valid Network credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ net_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -417,7 +417,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Network credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ net_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -429,7 +429,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid SCM credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ scm_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -445,7 +445,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an SCM credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ scm_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -457,7 +457,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid AWS credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ aws_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -472,7 +472,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an AWS credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ aws_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -484,7 +484,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid VMWare credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ vmware_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -499,7 +499,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an VMWare credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ vmware_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -511,7 +511,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid Satellite6 credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ sat6_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -526,7 +526,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Satellite6 credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ sat6_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -538,7 +538,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid GCE credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ gce_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -553,7 +553,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a GCE credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ gce_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -565,7 +565,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid AzureRM credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ azurerm_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -580,7 +580,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid AzureRM credential with a tenant
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ azurerm_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -596,7 +596,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an AzureRM credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ azurerm_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -608,7 +608,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid OpenStack credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ openstack_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -625,7 +625,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a OpenStack credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ openstack_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -637,7 +637,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid RHV credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ rhv_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -652,7 +652,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an RHV credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ rhv_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -664,7 +664,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid Insights credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ insights_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
@ -678,7 +678,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an Insights credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ insights_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -690,12 +690,12 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a valid Tower-to-Tower credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ tower_cred_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
kind: tower
|
||||
host: https://tower.example.org
|
||||
host: https://controller.example.org
|
||||
username: joe
|
||||
password: secret
|
||||
register: result
|
||||
@ -705,7 +705,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Tower-to-Tower credential
|
||||
tower_credential:
|
||||
credential:
|
||||
name: "{{ tower_cred_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -717,7 +717,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Check module fails with correct msg
|
||||
tower_credential:
|
||||
credential:
|
||||
name: test-credential
|
||||
description: Credential Description
|
||||
kind: ssh
|
||||
@ -6,12 +6,12 @@
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
src_cred_name: "AWX-Collection-tests-tower_credential_input_source-src_cred-{{ test_id }}"
|
||||
target_cred_name: "AWX-Collection-tests-tower_credential_input_source-target_cred-{{ test_id }}"
|
||||
src_cred_name: "AWX-Collection-tests-credential_input_source-src_cred-{{ test_id }}"
|
||||
target_cred_name: "AWX-Collection-tests-credential_input_source-target_cred-{{ test_id }}"
|
||||
|
||||
- block:
|
||||
- name: Add Tower credential Lookup
|
||||
tower_credential:
|
||||
- name: Add credential Lookup
|
||||
credential:
|
||||
description: Credential for Testing Source
|
||||
name: "{{ src_cred_name }}"
|
||||
credential_type: CyberArk AIM Central Credential Provider Lookup
|
||||
@ -25,8 +25,8 @@
|
||||
that:
|
||||
- "src_cred_result is changed"
|
||||
|
||||
- name: Add Tower credential Target
|
||||
tower_credential:
|
||||
- name: Add credential Target
|
||||
credential:
|
||||
description: Credential for Testing Target
|
||||
name: "{{ target_cred_name }}"
|
||||
credential_type: Machine
|
||||
@ -40,7 +40,7 @@
|
||||
- "target_cred_result is changed"
|
||||
|
||||
- name: Add credential Input Source
|
||||
tower_credential_input_source:
|
||||
credential_input_source:
|
||||
input_field_name: password
|
||||
target_credential: "{{ target_cred_result.id }}"
|
||||
source_credential: "{{ src_cred_result.id }}"
|
||||
@ -54,8 +54,8 @@
|
||||
that:
|
||||
- "result is changed"
|
||||
|
||||
- name: Add Second Tower credential Lookup
|
||||
tower_credential:
|
||||
- name: Add Second credential Lookup
|
||||
credential:
|
||||
description: Credential for Testing Source Change
|
||||
name: "{{ src_cred_name }}-2"
|
||||
credential_type: CyberArk AIM Central Credential Provider Lookup
|
||||
@ -66,7 +66,7 @@
|
||||
register: result
|
||||
|
||||
- name: Change credential Input Source
|
||||
tower_credential_input_source:
|
||||
credential_input_source:
|
||||
input_field_name: password
|
||||
target_credential: "{{ target_cred_name }}"
|
||||
source_credential: "{{ src_cred_name }}-2"
|
||||
@ -77,8 +77,8 @@
|
||||
- "result is changed"
|
||||
|
||||
always:
|
||||
- name: Remove a Tower credential source
|
||||
tower_credential_input_source:
|
||||
- name: Remove a credential source
|
||||
credential_input_source:
|
||||
input_field_name: password
|
||||
target_credential: "{{ target_cred_name }}"
|
||||
state: absent
|
||||
@ -88,24 +88,24 @@
|
||||
that:
|
||||
- "result is changed"
|
||||
|
||||
- name: Remove Tower credential Lookup
|
||||
tower_credential:
|
||||
- name: Remove credential Lookup
|
||||
credential:
|
||||
name: "{{ src_cred_name }}"
|
||||
organization: Default
|
||||
credential_type: CyberArk AIM Central Credential Provider Lookup
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: Remove Alt Tower credential Lookup
|
||||
tower_credential:
|
||||
- name: Remove Alt credential Lookup
|
||||
credential:
|
||||
name: "{{ src_cred_name }}-2"
|
||||
organization: Default
|
||||
credential_type: CyberArk AIM Central Credential Provider Lookup
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- name: Remove Tower credential
|
||||
tower_credential:
|
||||
- name: Remove credential
|
||||
credential:
|
||||
name: "{{ target_cred_name }}"
|
||||
organization: Default
|
||||
credential_type: Machine
|
||||
@ -1,10 +1,10 @@
|
||||
---
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
cred_type_name: "AWX-Collection-tests-tower_credential_type-cred-type-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
cred_type_name: "AWX-Collection-tests-credential_type-cred-type-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
|
||||
- name: Add Tower credential type
|
||||
tower_credential_type:
|
||||
credential_type:
|
||||
description: Credential type for Test
|
||||
name: "{{ cred_type_name }}"
|
||||
kind: cloud
|
||||
@ -17,7 +17,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Remove a Tower credential type
|
||||
tower_credential_type:
|
||||
credential_type:
|
||||
name: "{{ result.id }}"
|
||||
state: absent
|
||||
register: result
|
||||
@ -1,22 +1,22 @@
|
||||
---
|
||||
- name: Assure that default organization exists
|
||||
tower_organization:
|
||||
organization:
|
||||
name: Default
|
||||
|
||||
- name: HACK - delete orphaned projects from preload data where organization deletd
|
||||
tower_project:
|
||||
project:
|
||||
name: "{{ item['id'] }}"
|
||||
scm_type: git
|
||||
state: absent
|
||||
loop: >
|
||||
{{ query('awx.awx.tower_api', 'projects',
|
||||
{{ query('awx.awx.controller_api', 'projects',
|
||||
query_params={'organization__isnull': true, 'name': 'Demo Project'})
|
||||
}}
|
||||
loop_control:
|
||||
label: "Deleting Demo Project with null organization id={{ item['id'] }}"
|
||||
|
||||
- name: Assure that demo project exists
|
||||
tower_project:
|
||||
project:
|
||||
name: "Demo Project"
|
||||
scm_type: 'git'
|
||||
scm_url: 'https://github.com/ansible/ansible-tower-samples'
|
||||
@ -24,12 +24,12 @@
|
||||
organization: Default
|
||||
|
||||
- name: Assure that demo inventory exists
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "Demo Inventory"
|
||||
organization: Default
|
||||
|
||||
- name: Create a Host
|
||||
tower_host:
|
||||
host:
|
||||
name: "localhost"
|
||||
inventory: "Demo Inventory"
|
||||
state: present
|
||||
@ -38,7 +38,7 @@
|
||||
register: result
|
||||
|
||||
- name: Assure that demo job template exists
|
||||
tower_job_template:
|
||||
job_template:
|
||||
name: "Demo Job Template"
|
||||
project: "Demo Project"
|
||||
inventory: "Demo Inventory"
|
||||
|
||||
@ -6,25 +6,25 @@
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
org_name1: "AWX-Collection-tests-tower_export-organization-{{ test_id }}"
|
||||
org_name2: "AWX-Collection-tests-tower_export-organization2-{{ test_id }}"
|
||||
inventory_name1: "AWX-Collection-tests-tower_export-inv1-{{ test_id }}"
|
||||
org_name1: "AWX-Collection-tests-export-organization-{{ test_id }}"
|
||||
org_name2: "AWX-Collection-tests-export-organization2-{{ test_id }}"
|
||||
inventory_name1: "AWX-Collection-tests-export-inv1-{{ test_id }}"
|
||||
|
||||
- block:
|
||||
- name: Create some organizations
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ item }}"
|
||||
loop:
|
||||
- "{{ org_name1 }}"
|
||||
- "{{ org_name2 }}"
|
||||
|
||||
- name: Create an inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inventory_name1 }}"
|
||||
organization: "{{ org_name1 }}"
|
||||
|
||||
- name: Export all tower assets
|
||||
tower_export:
|
||||
- name: Export all assets
|
||||
export:
|
||||
all: true
|
||||
register: all_assets
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
- all_assets['assets']['organizations'] | length() >= 2
|
||||
|
||||
- name: Export all inventories
|
||||
tower_export:
|
||||
export:
|
||||
inventory: 'all'
|
||||
register: inventory_export
|
||||
|
||||
@ -48,7 +48,7 @@
|
||||
|
||||
# This mimics the example in the module
|
||||
- name: Export an all and a specific
|
||||
tower_export:
|
||||
export:
|
||||
inventory: 'all'
|
||||
organizations: "{{ org_name1 }}"
|
||||
register: mixed_export
|
||||
@ -63,13 +63,13 @@
|
||||
|
||||
always:
|
||||
- name: Remove our inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inventory_name1 }}"
|
||||
organization: "{{ org_name1 }}"
|
||||
state: absent
|
||||
|
||||
- name: Remove test organizations
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
@ -1,23 +1,23 @@
|
||||
---
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
group_name1: "AWX-Collection-tests-tower_group-group-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
group_name2: "AWX-Collection-tests-tower_group-group-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
group_name3: "AWX-Collection-tests-tower_group-group-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
inv_name: "AWX-Collection-test-tower_group-inv-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
host_name1: "AWX-Collection-test-tower_group-host-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
host_name2: "AWX-Collection-test-tower_group-host-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
host_name3: "AWX-Collection-test-tower_group-host-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
group_name1: "AWX-Collection-tests-group-group-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
group_name2: "AWX-Collection-tests-group-group-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
group_name3: "AWX-Collection-tests-group-group-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
inv_name: "AWX-Collection-tests-group-inv-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
host_name1: "AWX-Collection-tests-group-host-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
host_name2: "AWX-Collection-tests-group-host-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
host_name3: "AWX-Collection-tests-group-host-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
|
||||
- name: Create an Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: Default
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- name: Create a Group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name1 }}"
|
||||
inventory: "{{ result.id }}"
|
||||
state: present
|
||||
@ -30,7 +30,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a Group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name2 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
state: present
|
||||
@ -43,7 +43,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Create a Group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name3 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
state: present
|
||||
@ -56,7 +56,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: add hosts
|
||||
tower_host:
|
||||
host:
|
||||
name: "{{ item }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
loop:
|
||||
@ -65,7 +65,7 @@
|
||||
- "{{ host_name3 }}"
|
||||
|
||||
- name: Create a Group with hosts and sub group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name1 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
hosts:
|
||||
@ -79,7 +79,7 @@
|
||||
register: result
|
||||
|
||||
- name: Create a Group with hosts and sub group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name1 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
hosts:
|
||||
@ -93,14 +93,14 @@
|
||||
|
||||
- name: "Find number of hosts in {{ group_name1 }}"
|
||||
set_fact:
|
||||
group1_host_count: "{{ lookup('awx.awx.tower_api', 'groups/{{result.id}}/all_hosts/') |length}}"
|
||||
group1_host_count: "{{ lookup('awx.awx.controller_api', 'groups/{{result.id}}/all_hosts/') |length}}"
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- group1_host_count == "3"
|
||||
|
||||
- name: Delete a Group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name1 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
state: absent
|
||||
@ -111,7 +111,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name2 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
state: absent
|
||||
@ -122,7 +122,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name3 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
state: absent
|
||||
@ -133,7 +133,7 @@
|
||||
- "result is not changed"
|
||||
|
||||
- name: Check module fails with correct msg
|
||||
tower_group:
|
||||
group:
|
||||
name: test-group
|
||||
description: Group Description
|
||||
inventory: test-non-existing-inventory
|
||||
@ -149,7 +149,7 @@
|
||||
- "result.total_results == 0"
|
||||
|
||||
- name: add hosts
|
||||
tower_host:
|
||||
host:
|
||||
name: "{{ item }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
loop:
|
||||
@ -158,14 +158,14 @@
|
||||
- "{{ host_name3 }}"
|
||||
|
||||
- name: add mid level group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name2 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
hosts:
|
||||
- "{{ host_name3 }}"
|
||||
|
||||
- name: add top group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name3 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
hosts:
|
||||
@ -175,19 +175,19 @@
|
||||
- "{{ group_name2 }}"
|
||||
|
||||
- name: Delete the parent group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name3 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Delete the child group
|
||||
tower_group:
|
||||
group:
|
||||
name: "{{ group_name2 }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
state: absent
|
||||
|
||||
- name: Delete an Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
@ -1,18 +1,18 @@
|
||||
---
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
host_name: "AWX-Collection-tests-tower_host-host-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
inv_name: "AWX-Collection-tests-tower_host-inv-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
host_name: "AWX-Collection-tests-host-host-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
inv_name: "AWX-Collection-tests-host-inv-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
|
||||
- name: Create an Inventory
|
||||
tower_inventory:
|
||||
inventory:
|
||||
name: "{{ inv_name }}"
|
||||
organization: Default
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- name: Create a Host
|
||||
tower_host:
|
||||
host:
|
||||
name: "{{ host_name }}"
|
||||
inventory: "{{ result.id }}"
|
||||
state: present
|
||||
@ -25,7 +25,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Host
|
||||
tower_host:
|
||||
host:
|
||||
name: "{{ result.id }}"
|
||||
inventory: "{{ inv_name }}"
|
||||
state: absent
|
||||
@ -36,7 +36,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Check module fails with correct msg
|
||||
tower_host:
|
||||
host:
|
||||
name: test-host
|
||||
description: Host Description
|
||||
inventory: test-non-existing-inventory
|
||||
@ -6,12 +6,12 @@
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
org_name1: "AWX-Collection-tests-tower_import-organization-{{ test_id }}"
|
||||
org_name2: "AWX-Collection-tests-tower_import-organization2-{{ test_id }}"
|
||||
org_name1: "AWX-Collection-tests-import-organization-{{ test_id }}"
|
||||
org_name2: "AWX-Collection-tests-import-organization2-{{ test_id }}"
|
||||
|
||||
- block:
|
||||
- name: "Import something"
|
||||
tower_import:
|
||||
import:
|
||||
assets:
|
||||
organizations:
|
||||
- name: "{{ org_name1 }}"
|
||||
@ -33,7 +33,7 @@
|
||||
- import_output is changed
|
||||
|
||||
- name: "Import the same thing again"
|
||||
tower_import:
|
||||
import:
|
||||
assets:
|
||||
organizations:
|
||||
- name: "{{ org_name1 }}"
|
||||
@ -82,7 +82,7 @@
|
||||
dest: ./org.json
|
||||
|
||||
- name: "Load assets from a file"
|
||||
tower_import:
|
||||
import:
|
||||
assets: "{{ lookup('file', 'org.json') | from_json() }}"
|
||||
register: import_output
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
|
||||
always:
|
||||
- name: Remove organizations
|
||||
tower_organization:
|
||||
organization:
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user