mirror of
https://github.com/ansible/awx.git
synced 2026-05-08 01:47:35 -02:30
Added support to collection for named urls (#14205)
This commit is contained in:
@@ -68,6 +68,7 @@ Notable releases of the `awx.awx` collection:
|
|||||||
- 7.0.0 is intended to be identical to the content prior to the migration, aside from changes necessary to function as a collection.
|
- 7.0.0 is intended to be identical to the content prior to the migration, aside from changes necessary to function as a collection.
|
||||||
- 11.0.0 has no non-deprecated modules that depend on the deprecated `tower-cli` [PyPI](https://pypi.org/project/ansible-tower-cli/).
|
- 11.0.0 has no non-deprecated modules that depend on the deprecated `tower-cli` [PyPI](https://pypi.org/project/ansible-tower-cli/).
|
||||||
- 19.2.1 large renaming purged "tower" names (like options and module names), adding redirects for old names
|
- 19.2.1 large renaming purged "tower" names (like options and module names), adding redirects for old names
|
||||||
|
- X.X.X added support of named URLs to all modules. Anywhere that previously accepted name or id can also support named URLs
|
||||||
- 0.0.1-devel is the version you should see if installing from source, which is intended for development and expected to be unstable.
|
- 0.0.1-devel is the version you should see if installing from source, which is intended for development and expected to be unstable.
|
||||||
|
|
||||||
The following notes are changes that may require changes to playbooks:
|
The following notes are changes that may require changes to playbooks:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from ansible.module_utils.six import raise_from, string_types
|
|||||||
from ansible.module_utils.six.moves import StringIO
|
from ansible.module_utils.six.moves import StringIO
|
||||||
from ansible.module_utils.six.moves.urllib.error import HTTPError
|
from ansible.module_utils.six.moves.urllib.error import HTTPError
|
||||||
from ansible.module_utils.six.moves.http_cookiejar import CookieJar
|
from ansible.module_utils.six.moves.http_cookiejar import CookieJar
|
||||||
from ansible.module_utils.six.moves.urllib.parse import urlparse, urlencode
|
from ansible.module_utils.six.moves.urllib.parse import urlparse, urlencode, quote
|
||||||
from ansible.module_utils.six.moves.configparser import ConfigParser, NoOptionError
|
from ansible.module_utils.six.moves.configparser import ConfigParser, NoOptionError
|
||||||
from socket import getaddrinfo, IPPROTO_TCP
|
from socket import getaddrinfo, IPPROTO_TCP
|
||||||
import time
|
import time
|
||||||
@@ -383,29 +383,51 @@ class ControllerAPIModule(ControllerModule):
|
|||||||
|
|
||||||
def get_one(self, endpoint, name_or_id=None, allow_none=True, check_exists=False, **kwargs):
|
def get_one(self, endpoint, name_or_id=None, allow_none=True, check_exists=False, **kwargs):
|
||||||
new_kwargs = kwargs.copy()
|
new_kwargs = kwargs.copy()
|
||||||
if name_or_id:
|
response = None
|
||||||
name_field = self.get_name_field_from_endpoint(endpoint)
|
|
||||||
new_data = kwargs.get('data', {}).copy()
|
|
||||||
if name_field in new_data:
|
|
||||||
self.fail_json(msg="You can't specify the field {0} in your search data if using the name_or_id field".format(name_field))
|
|
||||||
|
|
||||||
try:
|
# A named URL is pretty unique so if we have a ++ in the name then lets start by looking for that
|
||||||
new_data['or__id'] = int(name_or_id)
|
# This also needs to go first because if there was data passed in kwargs and we do the next lookup first there may be results
|
||||||
new_data['or__{0}'.format(name_field)] = name_or_id
|
if name_or_id is not None and '++' in name_or_id:
|
||||||
except ValueError:
|
# Maybe someone gave us a named URL so lets see if we get anything from that.
|
||||||
# If we get a value error, then we didn't have an integer so we can just pass and fall down to the fail
|
url_quoted_name = quote(name_or_id, safe="+")
|
||||||
new_data[name_field] = name_or_id
|
named_endpoint = '{0}/{1}/'.format(endpoint, url_quoted_name)
|
||||||
new_kwargs['data'] = new_data
|
named_response = self.get_endpoint(named_endpoint)
|
||||||
|
|
||||||
response = self.get_endpoint(endpoint, **new_kwargs)
|
if named_response['status_code'] == 200 and 'json' in named_response:
|
||||||
if response['status_code'] != 200:
|
# We found a named item but we expect to deal with a list view so mock that up
|
||||||
fail_msg = "Got a {0} response when trying to get one from {1}".format(response['status_code'], endpoint)
|
response = {
|
||||||
if 'detail' in response.get('json', {}):
|
'json': {
|
||||||
fail_msg += ', detail: {0}'.format(response['json']['detail'])
|
'count': 1,
|
||||||
self.fail_json(msg=fail_msg)
|
'results': [named_response['json']],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if 'count' not in response['json'] or 'results' not in response['json']:
|
# Since we didn't have a named URL, lets try and find it with a general search
|
||||||
self.fail_json(msg="The endpoint did not provide count and results")
|
if response is None:
|
||||||
|
if name_or_id:
|
||||||
|
name_field = self.get_name_field_from_endpoint(endpoint)
|
||||||
|
new_data = kwargs.get('data', {}).copy()
|
||||||
|
if name_field in new_data:
|
||||||
|
self.fail_json(msg="You can't specify the field {0} in your search data if using the name_or_id field".format(name_field))
|
||||||
|
|
||||||
|
try:
|
||||||
|
new_data['or__id'] = int(name_or_id)
|
||||||
|
new_data['or__{0}'.format(name_field)] = name_or_id
|
||||||
|
except ValueError:
|
||||||
|
# If we get a value error, then we didn't have an integer so we can just pass and fall down to the fail
|
||||||
|
new_data[name_field] = name_or_id
|
||||||
|
new_kwargs['data'] = new_data
|
||||||
|
|
||||||
|
response = self.get_endpoint(endpoint, **new_kwargs)
|
||||||
|
|
||||||
|
if response['status_code'] != 200:
|
||||||
|
fail_msg = "Got a {0} response when trying to get one from {1}".format(response['status_code'], endpoint)
|
||||||
|
if 'detail' in response.get('json', {}):
|
||||||
|
fail_msg += ', detail: {0}'.format(response['json']['detail'])
|
||||||
|
self.fail_json(msg=fail_msg)
|
||||||
|
|
||||||
|
if 'count' not in response['json'] or 'results' not in response['json']:
|
||||||
|
self.fail_json(msg="The endpoint did not provide count and results")
|
||||||
|
|
||||||
if response['json']['count'] == 0:
|
if response['json']['count'] == 0:
|
||||||
if allow_none:
|
if allow_none:
|
||||||
@@ -423,7 +445,6 @@ class ControllerAPIModule(ControllerModule):
|
|||||||
self.fail_wanted_one(response, endpoint, new_kwargs.get('data'))
|
self.fail_wanted_one(response, endpoint, new_kwargs.get('data'))
|
||||||
|
|
||||||
if check_exists:
|
if check_exists:
|
||||||
name_field = self.get_name_field_from_endpoint(endpoint)
|
|
||||||
self.json_output['id'] = response['json']['results'][0]['id']
|
self.json_output['id'] = response['json']['results'][0]['id']
|
||||||
self.exit_json(**self.json_output)
|
self.exit_json(**self.json_output)
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
- name: Generate a random string for test
|
||||||
|
set_fact:
|
||||||
|
test_id: "{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
|
||||||
|
when: test_id is not defined
|
||||||
|
|
||||||
|
- include_tasks:
|
||||||
|
file: test_named_reference.yml
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- name: generate random string for project
|
||||||
|
set_fact:
|
||||||
|
org_name: "AWX-Collection-tests-organization-org-{{ test_id }}"
|
||||||
|
cred: "AWX-Collection-tests-job_template-cred-{{ test_id }}"
|
||||||
|
inv: "AWX-Collection-tests-job_template-inv-{{ test_id }}"
|
||||||
|
proj: "AWX-Collection-tests-job_template-proj-{{ test_id }}"
|
||||||
|
jt: "AWX-Collection-tests-job_template-jt-{{ test_id }}"
|
||||||
|
|
||||||
|
- name: "Create a new organization"
|
||||||
|
organization:
|
||||||
|
name: "{{ org_name }}"
|
||||||
|
galaxy_credentials:
|
||||||
|
- Ansible Galaxy
|
||||||
|
|
||||||
|
- name: Create an inventory
|
||||||
|
inventory:
|
||||||
|
name: "{{ inv }}"
|
||||||
|
organization: "{{ org_name }}"
|
||||||
|
|
||||||
|
- name: Create a Demo Project
|
||||||
|
project:
|
||||||
|
name: "{{ proj }}"
|
||||||
|
organization: "{{ org_name }}"
|
||||||
|
state: present
|
||||||
|
scm_type: git
|
||||||
|
scm_url: https://github.com/ansible/ansible-tower-samples.git
|
||||||
|
|
||||||
|
- name: Create Credential
|
||||||
|
credential:
|
||||||
|
name: "{{ cred }}"
|
||||||
|
organization: "{{ org_name }}"
|
||||||
|
credential_type: Machine
|
||||||
|
|
||||||
|
- name: Create Job Template
|
||||||
|
job_template:
|
||||||
|
name: "{{ jt }}"
|
||||||
|
project: "{{ proj }}++{{ org_name }}"
|
||||||
|
inventory: "{{ inv }}++{{ org_name }}"
|
||||||
|
playbook: hello_world.yml
|
||||||
|
credentials:
|
||||||
|
- "{{ cred }}++Machine+ssh++"
|
||||||
|
job_type: run
|
||||||
|
state: present
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Delete the Job Template
|
||||||
|
job_template:
|
||||||
|
name: "{{ jt }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Delete the Demo Project
|
||||||
|
project:
|
||||||
|
name: "{{ proj }}++{{ org_name }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Delete Credential
|
||||||
|
credential:
|
||||||
|
name: "{{ cred }}++Machine+ssh++{{ org_name }}"
|
||||||
|
credential_type: Machine
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Delete the inventory
|
||||||
|
inventory:
|
||||||
|
name: "{{ inv }}++{{ org_name }}"
|
||||||
|
organization: "{{ org_name }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Remove the organization
|
||||||
|
organization:
|
||||||
|
name: "{{ org_name }}"
|
||||||
|
state: absent
|
||||||
@@ -75,6 +75,7 @@ Notable releases of the `{{ collection_namespace }}.{{ collection_package }}` co
|
|||||||
- 11.0.0 has no non-deprecated modules that depend on the deprecated `tower-cli` [PyPI](https://pypi.org/project/ansible-tower-cli/).
|
- 11.0.0 has no non-deprecated modules that depend on the deprecated `tower-cli` [PyPI](https://pypi.org/project/ansible-tower-cli/).
|
||||||
- 19.2.1 large renaming purged "tower" names (like options and module names), adding redirects for old names
|
- 19.2.1 large renaming purged "tower" names (like options and module names), adding redirects for old names
|
||||||
- 21.11.0 "tower" modules deprecated and symlinks removed.
|
- 21.11.0 "tower" modules deprecated and symlinks removed.
|
||||||
|
- X.X.X added support of named URLs to all modules. Anywhere that previously accepted name or id can also support named URLs
|
||||||
- 0.0.1-devel is the version you should see if installing from source, which is intended for development and expected to be unstable.
|
- 0.0.1-devel is the version you should see if installing from source, which is intended for development and expected to be unstable.
|
||||||
{% else %}
|
{% else %}
|
||||||
- 3.7.0 initial release
|
- 3.7.0 initial release
|
||||||
|
|||||||
Reference in New Issue
Block a user