Skip to content

Commit

Permalink
Added support to collection for named urls
Browse files Browse the repository at this point in the history
  • Loading branch information
john-westcott-iv committed Jul 11, 2023
1 parent 07e30a3 commit 07407ec
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 24 deletions.
1 change: 1 addition & 0 deletions awx_collection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
- 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
- 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.

The following notes are changes that may require changes to playbooks:
Expand Down
69 changes: 45 additions & 24 deletions awx_collection/plugins/module_utils/controller_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from ansible.module_utils.six.moves import StringIO
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.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 socket import getaddrinfo, IPPROTO_TCP
import time
Expand Down Expand Up @@ -381,29 +381,51 @@ def get_all_endpoint(self, endpoint, *args, **kwargs):

def get_one(self, endpoint, name_or_id=None, allow_none=True, check_exists=False, **kwargs):
new_kwargs = kwargs.copy()
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))
response = None

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")
# A named URL is pretty unique so if we have a ++ in the name then lets start by looking for that
# 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
if name_or_id is not None and '++' in name_or_id:
# Maybe someone gave us a named URL so lets see if we get anything from that.
url_quoted_name = quote(name_or_id, safe="+")
named_endpoint = '{0}/{1}/'.format(endpoint, url_quoted_name)
named_response = self.get_endpoint(named_endpoint)

if named_response['status_code'] == 200 and 'json' in named_response:
# We found a named item but we expect to deal with a list view so mock that up
response = {
'json': {
'count': 1,
'results': [named_response['json']],
}
}

# Since we didn't have a named URL, lets try and find it with a general search
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 allow_none:
Expand All @@ -421,7 +443,6 @@ def get_one(self, endpoint, name_or_id=None, allow_none=True, check_exists=False
self.fail_wanted_one(response, endpoint, new_kwargs.get('data'))

if check_exists:
name_field = self.get_name_field_from_endpoint(endpoint)
self.json_output['id'] = response['json']['results'][0]['id']
self.exit_json(**self.json_output)

Expand Down
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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/).
- 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.
- 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.
{% else %}
- 3.7.0 initial release
Expand Down

0 comments on commit 07407ec

Please sign in to comment.