mirror of
https://github.com/ansible/awx.git
synced 2026-03-23 20:05:03 -02:30
@@ -91,9 +91,9 @@ The following notes are changes that may require changes to playbooks:
|
||||
- Specified `tower_config` file used to handle `k=v` pairs on a single line; this is no longer supported. Please use a file formatted as `yaml`, `json` or `ini` only.
|
||||
- Some return values (e.g., `credential_type`) have been removed. Use of `id` is recommended.
|
||||
- `tower_job_template` no longer supports the deprecated `extra_vars_path` parameter, please use `extra_vars` with the lookup plugin to replace this functionality.
|
||||
- The `notification_configuration` parameter of `tower_notification` has changed from a string to a dict. Please use the `lookup` plugin to read an existing file into a dict.
|
||||
- The `notification_configuration` parameter of `tower_notification_template` has changed from a string to a dict. Please use the `lookup` plugin to read an existing file into a dict.
|
||||
- `tower_credential` no longer supports passing a file name to ssh_key_data.
|
||||
- The HipChat `notification_type` has been removed and can no longer be created using the `tower_notification` module.
|
||||
- The HipChat `notification_type` has been removed and can no longer be created using the `tower_notification_template` module.
|
||||
|
||||
## Running Unit Tests
|
||||
|
||||
|
||||
@@ -13,5 +13,5 @@ plugin_routing:
|
||||
deprecation:
|
||||
removal_date: TBD
|
||||
warning_text: see plugin documentation for details
|
||||
tower_notifitcation:
|
||||
tower_notification:
|
||||
redirect: tower_notification_template
|
||||
|
||||
@@ -552,7 +552,7 @@ class TowerAPIModule(TowerModule):
|
||||
return self.create_if_needed(existing_item, new_item, endpoint, on_create=on_create, item_type=item_type, associations=associations)
|
||||
|
||||
def logout(self):
|
||||
if self.authenticated:
|
||||
if self.authenticated and self.oauth_token_id:
|
||||
# Attempt to delete our current token from /api/v2/tokens/
|
||||
# Post to the tokens endpoint with baisc auth to try and get a token
|
||||
api_token_url = (
|
||||
|
||||
@@ -48,7 +48,11 @@ options:
|
||||
type: str
|
||||
host_filter:
|
||||
description:
|
||||
- The host_filter field. Only useful when C(kind=smart).
|
||||
- The host_filter field. Only useful when C(kind=smart).
|
||||
type: str
|
||||
insights_credential:
|
||||
description:
|
||||
- Credentials to be used by hosts belonging to this inventory when accessing Red Hat Insights API.
|
||||
type: str
|
||||
state:
|
||||
description:
|
||||
@@ -84,6 +88,7 @@ def main():
|
||||
variables=dict(type='dict'),
|
||||
kind=dict(choices=['', 'smart'], default=''),
|
||||
host_filter=dict(),
|
||||
insights_credential=dict(),
|
||||
state=dict(choices=['present', 'absent'], default='present'),
|
||||
)
|
||||
|
||||
@@ -98,6 +103,7 @@ def main():
|
||||
state = module.params.get('state')
|
||||
kind = module.params.get('kind')
|
||||
host_filter = module.params.get('host_filter')
|
||||
insights_credential = module.params.get('insights_credential')
|
||||
|
||||
# Attempt to look up the related items the user specified (these will fail the module if not found)
|
||||
org_id = module.resolve_name_to_id('organizations', organization)
|
||||
@@ -125,6 +131,8 @@ def main():
|
||||
inventory_fields['description'] = description
|
||||
if variables is not None:
|
||||
inventory_fields['variables'] = json.dumps(variables)
|
||||
if insights_credential is not None:
|
||||
inventory_fields['insights_credential'] = module.resolve_name_to_id('credentials', insights_credential)
|
||||
|
||||
# We need to perform a check to make sure you are not trying to convert a regular inventory into a smart one.
|
||||
if inventory and inventory['kind'] == '' and inventory_fields['kind'] == 'smart':
|
||||
|
||||
@@ -17,6 +17,8 @@ import pytest
|
||||
from awx.main.tests.functional.conftest import _request
|
||||
from awx.main.models import Organization, Project, Inventory, JobTemplate, Credential, CredentialType
|
||||
|
||||
from django.db import transaction
|
||||
|
||||
try:
|
||||
import tower_cli # noqa
|
||||
HAS_TOWER_CLI = True
|
||||
@@ -107,8 +109,9 @@ def run_module(request, collection_import):
|
||||
kwargs_copy['data'][k] = v
|
||||
|
||||
# make request
|
||||
rf = _request(method.lower())
|
||||
django_response = rf(url, user=request_user, expect=None, **kwargs_copy)
|
||||
with transaction.atomic():
|
||||
rf = _request(method.lower())
|
||||
django_response = rf(url, user=request_user, expect=None, **kwargs_copy)
|
||||
|
||||
# requests library response object is different from the Django response, but they are the same concept
|
||||
# this converts the Django response object into a requests response object for consumption
|
||||
|
||||
@@ -58,7 +58,6 @@ needs_development = [
|
||||
]
|
||||
needs_param_development = {
|
||||
'tower_host': ['instance_id'],
|
||||
'tower_inventory': ['insights_credential'],
|
||||
}
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -3,20 +3,26 @@ __metaclass__ = type
|
||||
|
||||
import pytest
|
||||
|
||||
from awx.main.models import Inventory
|
||||
from awx.main.models import Inventory, Credential
|
||||
from awx.main.tests.functional.conftest import insights_credential, credentialtype_insights
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_inventory_create(run_module, admin_user, organization):
|
||||
def test_inventory_create(run_module, admin_user, organization, insights_credential):
|
||||
# Create an insights credential
|
||||
|
||||
result = run_module('tower_inventory', {
|
||||
'name': 'foo-inventory',
|
||||
'organization': organization.name,
|
||||
'variables': {'foo': 'bar', 'another-foo': {'barz': 'bar2'}},
|
||||
'insights_credential': insights_credential.name,
|
||||
'state': 'present'
|
||||
}, admin_user)
|
||||
assert not result.get('failed', False), result.get('msg', result)
|
||||
|
||||
inv = Inventory.objects.get(name='foo-inventory')
|
||||
assert inv.variables == '{"foo": "bar", "another-foo": {"barz": "bar2"}}'
|
||||
assert inv.insights_credential.name == insights_credential.name
|
||||
|
||||
result.pop('module_args', None)
|
||||
result.pop('invocation', None)
|
||||
|
||||
@@ -1,101 +1,140 @@
|
||||
---
|
||||
- name: Generate a test ID
|
||||
set_fact:
|
||||
test_id: "{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
|
||||
- name: Generate names
|
||||
set_fact:
|
||||
inv_name1: "AWX-Collection-tests-tower_inventory-inv1-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
inv_name2: "AWX-Collection-tests-tower_inventory-inv2-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
inv_name1: "AWX-Collection-tests-tower_inventory-inv1-{{ test_id }}"
|
||||
inv_name2: "AWX-Collection-tests-tower_inventory-inv2-{{ test_id }}"
|
||||
cred_name1: "AWX-Collection-tests-tower_inventory-cred1-{{ test_id }}"
|
||||
|
||||
- name: Create an Inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
register: result
|
||||
- block:
|
||||
- name: Create an Insights Credential
|
||||
tower_credential:
|
||||
name: "{{ cred_name1 }}"
|
||||
organization: Default
|
||||
kind: insights
|
||||
inputs:
|
||||
username: joe
|
||||
password: secret
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
|
||||
- name: Test Inventory module idempotency
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
state: present
|
||||
register: result
|
||||
- name: Create an Inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
insights_credential: "{{ cred_name1 }}"
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is not changed"
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
|
||||
- name: Fail Change Regular to Smart
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
kind: smart
|
||||
register: result
|
||||
ignore_errors: true
|
||||
- name: Test Inventory module idempotency
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
insights_credential: "{{ cred_name1 }}"
|
||||
state: present
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is failed"
|
||||
- assert:
|
||||
that:
|
||||
- "result is not changed"
|
||||
|
||||
- name: Create a smart inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name2 }}"
|
||||
organization: Default
|
||||
kind: smart
|
||||
host_filter: name=foo
|
||||
register: result
|
||||
- name: Fail Change Regular to Smart
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
kind: smart
|
||||
register: result
|
||||
ignore_errors: true
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
- assert:
|
||||
that:
|
||||
- "result is failed"
|
||||
|
||||
- name: Delete a smart inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name2 }}"
|
||||
organization: Default
|
||||
kind: smart
|
||||
host_filter: name=foo
|
||||
state: absent
|
||||
register: result
|
||||
- name: Create a smart inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name2 }}"
|
||||
organization: Default
|
||||
kind: smart
|
||||
host_filter: name=foo
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete an Inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
register: result
|
||||
- name: Delete a smart inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name2 }}"
|
||||
organization: Default
|
||||
kind: smart
|
||||
host_filter: name=foo
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete a Non-Existent Inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
register: result
|
||||
- name: Delete an Inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is not changed"
|
||||
- assert:
|
||||
that:
|
||||
- "result is changed"
|
||||
|
||||
- name: Check module fails with correct msg
|
||||
tower_inventory:
|
||||
name: test-inventory
|
||||
description: Inventory Description
|
||||
organization: test-non-existing-org
|
||||
state: present
|
||||
register: result
|
||||
ignore_errors: true
|
||||
- name: Delete a Non-Existent Inventory
|
||||
tower_inventory:
|
||||
name: "{{ inv_name1 }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
register: result
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is not changed"
|
||||
- "result.msg =='Failed to update inventory, organization not found: The requested object could not be found.'
|
||||
or result.msg =='The organizations test-non-existing-org was not found on the Tower server'"
|
||||
- assert:
|
||||
that:
|
||||
- "result is not changed"
|
||||
|
||||
- name: Check module fails with correct msg
|
||||
tower_inventory:
|
||||
name: test-inventory
|
||||
description: Inventory Description
|
||||
organization: test-non-existing-org
|
||||
state: present
|
||||
register: result
|
||||
ignore_errors: true
|
||||
|
||||
- assert:
|
||||
that:
|
||||
- "result is not changed"
|
||||
- "result.msg =='Failed to update inventory, organization not found: The requested object could not be found.'
|
||||
or result.msg =='The organizations test-non-existing-org was not found on the Tower server'"
|
||||
always:
|
||||
- name: Delete Inventories
|
||||
tower_inventory:
|
||||
name: "{{ item }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
loop:
|
||||
- "{{ inv_name1 }}"
|
||||
- "{{ inv_name2 }}"
|
||||
|
||||
- name: Delete Insights Credential
|
||||
tower_credential:
|
||||
name: "{{ cred_name1 }}"
|
||||
organization: "Default"
|
||||
kind: insights
|
||||
state: absent
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
jt2: "AWX-Collection-tests-tower_job_template-jt2-{{ test_id }}"
|
||||
lab1: "AWX-Collection-tests-tower_job_template-lab1-{{ test_id }}"
|
||||
email_not: "AWX-Collection-tests-tower_job_template-email-not-{{ test_id }}"
|
||||
webhook_not: "AWX-Collection-tests-tower_notification-wehbook-not-{{ test_id }}"
|
||||
webhook_not: "AWX-Collection-tests-tower_notification_template-wehbook-not-{{ test_id }}"
|
||||
|
||||
- name: Create a Demo Project
|
||||
tower_project:
|
||||
@@ -49,7 +49,7 @@
|
||||
organization: Default
|
||||
|
||||
- name: Add email notification
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ email_not }}"
|
||||
organization: Default
|
||||
notification_type: email
|
||||
@@ -65,7 +65,7 @@
|
||||
state: present
|
||||
|
||||
- name: Add webhook notification
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ webhook_not }}"
|
||||
organization: Default
|
||||
notification_type: webhook
|
||||
@@ -366,13 +366,13 @@
|
||||
# You can't delete a label directly so no cleanup needed
|
||||
|
||||
- name: Delete email notification
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ email_not }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
|
||||
- name: Delete webhook notification
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ webhook_not }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
irc_not: "AWX-Collection-tests-tower_notification_template-irc-not-{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||
|
||||
- name: Test deprecation warnings with legacy name
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ slack_not }}"
|
||||
organization: Default
|
||||
notification_type: slack
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
jt2_name: "AWX-Collection-tests-tower_workflow_job_template-jt2-{{ test_id }}"
|
||||
wfjt_name: "AWX-Collection-tests-tower_workflow_job_template-wfjt-{{ test_id }}"
|
||||
email_not: "AWX-Collection-tests-tower_job_template-email-not-{{ test_id }}"
|
||||
webhook_not: "AWX-Collection-tests-tower_notification-wehbook-not-{{ test_id }}"
|
||||
webhook_not: "AWX-Collection-tests-tower_notification_template-wehbook-not-{{ test_id }}"
|
||||
|
||||
- name: Create an SCM Credential
|
||||
tower_credential:
|
||||
@@ -25,7 +25,7 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Add email notification
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ email_not }}"
|
||||
organization: Default
|
||||
notification_type: email
|
||||
@@ -41,7 +41,7 @@
|
||||
state: present
|
||||
|
||||
- name: Add webhook notification
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ webhook_not }}"
|
||||
organization: Default
|
||||
notification_type: webhook
|
||||
@@ -264,13 +264,13 @@
|
||||
- "result is changed"
|
||||
|
||||
- name: Delete email notification
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ email_not }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
|
||||
- name: Delete webhook notification
|
||||
tower_notification:
|
||||
tower_notification_template:
|
||||
name: "{{ webhook_not }}"
|
||||
organization: Default
|
||||
state: absent
|
||||
|
||||
@@ -3,7 +3,7 @@ plugins/modules/tower_send.py validate-modules:deprecation-mismatch
|
||||
plugins/modules/tower_workflow_template.py validate-modules:deprecation-mismatch
|
||||
plugins/modules/tower_credential.py pylint:wrong-collection-deprecated-version-tag
|
||||
plugins/modules/tower_job_wait.py pylint:wrong-collection-deprecated-version-tag
|
||||
plugins/modules/tower_notification.py pylint:wrong-collection-deprecated-version-tag
|
||||
plugins/modules/tower_notification_template.py pylint:wrong-collection-deprecated-version-tag
|
||||
plugins/inventory/tower.py pylint:raise-missing-from
|
||||
plugins/inventory/tower.py pylint:super-with-arguments
|
||||
plugins/lookup/tower_schedule_rrule.py pylint:raise-missing-from
|
||||
|
||||
@@ -80,6 +80,7 @@ Notable releases of the `{{ collection_namespace }}.{{ collection_package }}` co
|
||||
|
||||
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.
|
||||
- Creating a "scan" type job template is no longer supported.
|
||||
- Specifying a custom certificate via the `TOWER_CERTIFICATE` environment variable no longer works.
|
||||
@@ -100,9 +101,9 @@ The following notes are changes that may require changes to playbooks:
|
||||
- Specified `tower_config` file used to handle `k=v` pairs on a single line; this is no longer supported. Please use a file formatted as `yaml`, `json` or `ini` only.
|
||||
- Some return values (e.g., `credential_type`) have been removed. Use of `id` is recommended.
|
||||
- `tower_job_template` no longer supports the deprecated `extra_vars_path` parameter, please use `extra_vars` with the lookup plugin to replace this functionality.
|
||||
- The `notification_configuration` parameter of `tower_notification` has changed from a string to a dict. Please use the `lookup` plugin to read an existing file into a dict.
|
||||
- The `notification_configuration` parameter of `tower_notification_template` has changed from a string to a dict. Please use the `lookup` plugin to read an existing file into a dict.
|
||||
- `tower_credential` no longer supports passing a file name to ssh_key_data.
|
||||
- The HipChat `notification_type` has been removed and can no longer be created using the `tower_notification` module.
|
||||
- The HipChat `notification_type` has been removed and can no longer be created using the `tower_notification_template` module.
|
||||
|
||||
{% if collection_package | lower() == "awx" %}
|
||||
## Running Unit Tests
|
||||
|
||||
Reference in New Issue
Block a user