summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJake Jackson <jljacks93@gmail.com>2025-01-15 22:10:28 +0100
committerGitHub <noreply@github.com>2025-01-15 22:10:28 +0100
commitf05173cb65cbbd1de90e0b95740cffe22859f222 (patch)
tree2cf0cf4730197e393adb5e7e36c7ab17c6bc31d3
parentAdd changelog to awx collection (diff)
downloadawx-f05173cb65cbbd1de90e0b95740cffe22859f222.tar.xz
awx-f05173cb65cbbd1de90e0b95740cffe22859f222.zip
Add new credential entry point discovery (#15685)
* - add new entry points - add logic to check what version of the project is running * remove former discovery method * update custom_injectors and remove unused import * fix how we load external creds * remove stale code to match devel * fix cloudforms test and move credential loading * add load credentials method to get tests passing * Conditionalize integration tests if the cred is present * remove inventory source test * inventory source is covered in the workflow job template target
-rw-r--r--awx/main/apps.py3
-rw-r--r--awx/main/models/credential.py83
-rw-r--r--awx/main/tests/conftest.py9
-rw-r--r--awx/main/tests/functional/migrations/test_inventory_source_migration.py16
-rw-r--r--awx/main/tests/live/tests/conftest.py1
-rw-r--r--awx_collection/test/awx/conftest.py1
-rw-r--r--awx_collection/tests/integration/targets/credential/tasks/main.yml53
-rw-r--r--awx_collection/tests/integration/targets/credential_input_source/tasks/main.yml16
-rw-r--r--awx_collection/tests/integration/targets/inventory/tasks/main.yml23
-rw-r--r--awx_collection/tests/integration/targets/inventory_source/tasks/main.yml143
-rw-r--r--awx_collection/tests/integration/targets/workflow_job_template/tasks/main.yml41
-rw-r--r--requirements/requirements_git.txt2
12 files changed, 172 insertions, 219 deletions
diff --git a/awx/main/apps.py b/awx/main/apps.py
index 3d98963747..c1c90f83c7 100644
--- a/awx/main/apps.py
+++ b/awx/main/apps.py
@@ -60,6 +60,9 @@ class MainConfig(AppConfig):
@bypass_in_test
def load_credential_types_feature(self):
+ from awx.main.models.credential import load_credentials
+
+ load_credentials()
return self._load_credential_types_feature()
def load_inventory_plugins(self):
diff --git a/awx/main/models/credential.py b/awx/main/models/credential.py
index 09cc4bde7c..b9bacaae4c 100644
--- a/awx/main/models/credential.py
+++ b/awx/main/models/credential.py
@@ -2,6 +2,7 @@
# All Rights Reserved.
from contextlib import nullcontext
import functools
+
import inspect
import logging
from importlib.metadata import entry_points
@@ -47,6 +48,8 @@ from awx.main.models.rbac import (
)
from awx.main.models import Team, Organization
from awx.main.utils import encrypt_field
+from awx_plugins.interfaces._temporary_private_licensing_api import detect_server_product_name
+
# DAB
from ansible_base.resource_registry.tasks.sync import get_resource_server_client
@@ -56,7 +59,6 @@ from ansible_base.resource_registry.utils.settings import resource_server_define
__all__ = ['Credential', 'CredentialType', 'CredentialInputSource', 'build_safe_env']
logger = logging.getLogger('awx.main.models.credential')
-credential_plugins = {entry_point.name: entry_point.load() for entry_point in entry_points(group='awx_plugins.credentials')}
HIDDEN_PASSWORD = '**********'
@@ -462,8 +464,7 @@ class CredentialType(CommonModelNameNotUnique):
def plugin(self):
if self.kind != 'external':
raise AttributeError('plugin')
- [plugin] = [plugin for ns, plugin in credential_plugins.items() if ns == self.namespace]
- return plugin
+ return ManagedCredentialType.registry.get(self.namespace, None)
def default_for_field(self, field_id):
for field in self.inputs.get('fields', []):
@@ -474,7 +475,7 @@ class CredentialType(CommonModelNameNotUnique):
@classproperty
def defaults(cls):
- return dict((k, functools.partial(v.create)) for k, v in ManagedCredentialType.registry.items())
+ return dict((k, functools.partial(CredentialTypeHelper.create, v)) for k, v in ManagedCredentialType.registry.items())
@classmethod
def _get_credential_type_class(cls, apps: Apps = None, app_config: AppConfig = None):
@@ -509,7 +510,7 @@ class CredentialType(CommonModelNameNotUnique):
existing.save()
continue
logger.debug(_("adding %s credential type" % default.name))
- params = default.get_creation_params()
+ params = CredentialTypeHelper.get_creation_params(default)
if 'managed' not in [f.name for f in ct_class._meta.get_fields()]:
params['managed_by_tower'] = params.pop('managed')
params['created'] = params['modified'] = now() # CreatedModifiedModel service
@@ -543,7 +544,7 @@ class CredentialType(CommonModelNameNotUnique):
@classmethod
def load_plugin(cls, ns, plugin):
# TODO: User "side-loaded" credential custom_injectors isn't supported
- ManagedCredentialType(namespace=ns, name=plugin.name, kind='external', inputs=plugin.inputs)
+ ManagedCredentialType.registry[ns] = ManagedCredentialType(namespace=ns, name=plugin.name, kind='external', inputs=plugin.inputs, injectors={})
def inject_credential(self, credential, env, safe_env, args, private_data_dir):
from awx_plugins.interfaces._temporary_private_inject_api import inject_credential
@@ -551,38 +552,29 @@ class CredentialType(CommonModelNameNotUnique):
inject_credential(self, credential, env, safe_env, args, private_data_dir)
-class ManagedCredentialType(SimpleNamespace):
- registry = {}
-
- def __init__(self, namespace, **kwargs):
- for k in ('inputs', 'injectors'):
- if k not in kwargs:
- kwargs[k] = {}
- super(ManagedCredentialType, self).__init__(namespace=namespace, **kwargs)
- if namespace in ManagedCredentialType.registry:
- raise ValueError(
- 'a ManagedCredentialType with namespace={} is already defined in {}'.format(
- namespace, inspect.getsourcefile(ManagedCredentialType.registry[namespace].__class__)
- )
- )
- ManagedCredentialType.registry[namespace] = self
-
- def get_creation_params(self):
+class CredentialTypeHelper:
+ @classmethod
+ def get_creation_params(cls, cred_type):
return dict(
- namespace=self.namespace,
- kind=self.kind,
- name=self.name,
+ namespace=cred_type.namespace,
+ kind=cred_type.kind,
+ name=cred_type.name,
managed=True,
- inputs=self.inputs,
- injectors=self.injectors,
+ inputs=cred_type.inputs,
+ injectors=cred_type.injectors,
)
- def create(self):
- res = CredentialType(**self.get_creation_params())
- res.custom_injectors = getattr(self, 'custom_injectors', None)
+ @classmethod
+ def create(cls, cred_type):
+ res = CredentialType(**CredentialTypeHelper.get_creation_params(cred_type))
+ res.custom_injectors = getattr(cred_type, "custom_injectors", None)
return res
+class ManagedCredentialType(SimpleNamespace):
+ registry = {}
+
+
class CredentialInputSource(PrimordialModel):
class Meta:
app_label = 'main'
@@ -647,7 +639,30 @@ class CredentialInputSource(PrimordialModel):
return reverse(view_name, kwargs={'pk': self.pk}, request=request)
-from awx_plugins.credentials.plugins import * # noqa
+def load_credentials():
+
+ awx_entry_points = {ep.name: ep for ep in entry_points(group='awx_plugins.managed_credentials')}
+ supported_entry_points = {ep.name: ep for ep in entry_points(group='awx_plugins.managed_credentials.supported')}
+ plugin_entry_points = awx_entry_points if detect_server_product_name() == 'AWX' else {**awx_entry_points, **supported_entry_points}
+
+ for ns, ep in plugin_entry_points.items():
+ cred_plugin = ep.load()
+ if not hasattr(cred_plugin, 'inputs'):
+ setattr(cred_plugin, 'inputs', {})
+ if not hasattr(cred_plugin, 'injectors'):
+ setattr(cred_plugin, 'injectors', {})
+ if ns in ManagedCredentialType.registry:
+ raise ValueError(
+ 'a ManagedCredentialType with namespace={} is already defined in {}'.format(
+ ns, inspect.getsourcefile(ManagedCredentialType.registry[ns].__class__)
+ )
+ )
+ ManagedCredentialType.registry[ns] = cred_plugin
+
+ credential_plugins = {ep.name: ep for ep in entry_points(group='awx_plugins.credentials')}
+ if detect_server_product_name() == 'AWX':
+ credential_plugins = {}
-for ns, plugin in credential_plugins.items():
- CredentialType.load_plugin(ns, plugin)
+ for ns, ep in credential_plugins.items():
+ plugin = ep.load()
+ CredentialType.load_plugin(ns, plugin)
diff --git a/awx/main/tests/conftest.py b/awx/main/tests/conftest.py
index e1a1c05e00..fbfb6489f0 100644
--- a/awx/main/tests/conftest.py
+++ b/awx/main/tests/conftest.py
@@ -229,3 +229,12 @@ def me_inst():
me_mock = mock.MagicMock(return_value=inst)
with mock.patch.object(Instance.objects, 'me', me_mock):
yield inst
+
+
+@pytest.fixture(scope="session", autouse=True)
+def load_all_credentials():
+ with mock.patch('awx.main.models.credential.detect_server_product_name', return_value='NOT_AWX'):
+ from awx.main.models.credential import load_credentials
+
+ load_credentials()
+ yield
diff --git a/awx/main/tests/functional/migrations/test_inventory_source_migration.py b/awx/main/tests/functional/migrations/test_inventory_source_migration.py
index fe0b537426..6d17e22936 100644
--- a/awx/main/tests/functional/migrations/test_inventory_source_migration.py
+++ b/awx/main/tests/functional/migrations/test_inventory_source_migration.py
@@ -37,16 +37,24 @@ def cleanup_cloudforms():
assert 'cloudforms' not in CredentialType.defaults
-@pytest.mark.django_db
-def test_cloudforms_inventory_removal(request, inventory):
- request.addfinalizer(cleanup_cloudforms)
- ManagedCredentialType(
+@pytest.fixture
+def cloudforms_mct():
+ ManagedCredentialType.registry['cloudforms'] = ManagedCredentialType(
name='Red Hat CloudForms',
namespace='cloudforms',
kind='cloud',
managed=True,
inputs={},
+ injectors={},
)
+ yield
+ ManagedCredentialType.registry.pop('cloudforms', None)
+
+
+@pytest.mark.django_db
+def test_cloudforms_inventory_removal(request, inventory, cloudforms_mct):
+ request.addfinalizer(cleanup_cloudforms)
+
CredentialType.defaults['cloudforms']().save()
cloudforms = CredentialType.objects.get(namespace='cloudforms')
Credential.objects.create(
diff --git a/awx/main/tests/live/tests/conftest.py b/awx/main/tests/live/tests/conftest.py
index 0fae039189..f7c197199f 100644
--- a/awx/main/tests/live/tests/conftest.py
+++ b/awx/main/tests/live/tests/conftest.py
@@ -5,6 +5,7 @@ import pytest
# These tests are invoked from the awx/main/tests/live/ subfolder
# so any fixtures from higher-up conftest files must be explicitly included
from awx.main.tests.functional.conftest import * # noqa
+from awx.main.tests.conftest import load_all_credentials # noqa: F401; pylint: disable=unused-import
from awx.main.models import Organization
diff --git a/awx_collection/test/awx/conftest.py b/awx_collection/test/awx/conftest.py
index 42500342ac..6de5ed9c25 100644
--- a/awx_collection/test/awx/conftest.py
+++ b/awx_collection/test/awx/conftest.py
@@ -18,6 +18,7 @@ import pytest
from ansible.module_utils.six import raise_from
from ansible_base.rbac.models import RoleDefinition, DABPermission
+from awx.main.tests.conftest import load_all_credentials # noqa: F401; pylint: disable=unused-import
from awx.main.tests.functional.conftest import _request
from awx.main.tests.functional.conftest import credentialtype_scm, credentialtype_ssh # noqa: F401; pylint: disable=unused-import
from awx.main.models import (
diff --git a/awx_collection/tests/integration/targets/credential/tasks/main.yml b/awx_collection/tests/integration/targets/credential/tasks/main.yml
index 043deea185..76be783454 100644
--- a/awx_collection/tests/integration/targets/credential/tasks/main.yml
+++ b/awx_collection/tests/integration/targets/credential/tasks/main.yml
@@ -25,6 +25,21 @@
insights_cred_name2: "AWX-Collection-tests-credential-insights-cred2-{{ test_id }}"
tower_cred_name1: "AWX-Collection-tests-credential-tower-cred1-{{ test_id }}"
+- name: Get current Credential Types available
+ ansible.builtin.set_fact:
+ credentials: "{{ lookup('awx.awx.controller_api', 'credential_types') }}"
+
+- name: Register Credentials found
+ set_fact:
+ aws_found: "{{ 'Amazon Web Services' in credentials | map(attribute='name') | list }}"
+ vmware_found: "{{ 'VMware vCenter' in credentials | map(attribute='name') | list }}"
+ azure_found: "{{ 'Microsoft Azure Resource Manager' in credentials | map(attribute='name') | list }}"
+ gce_found: "{{ 'Google Compute Engine' in credentials | map(attribute='name') | list }}"
+ insights_found: "{{ 'Red Hat Insights' in credentials | map(attribute='name') | list }}"
+ satellite_found: "{{ 'Red Hat Satellite 6' in credentials | map(attribute='name') | list }}"
+ openstack_found: "{{ 'OpenStack' in credentials | map(attribute='name') | list }}"
+ rhv_found: "{{ 'Red Hat Virtualization' in credentials | map(attribute='name') | list }}"
+
- name: create a tempdir for an SSH key
local_action: shell mktemp -d
register: tempdir
@@ -464,10 +479,12 @@
password: secret
security_token: aws-token
register: result
+ when: aws_found
- assert:
that:
- "result is changed"
+ when: aws_found
- name: Delete an AWS credential
credential:
@@ -476,10 +493,12 @@
state: absent
credential_type: Amazon Web Services
register: result
+ when: aws_found
- assert:
that:
- "result is changed"
+ when: aws_found
- name: Create a valid VMWare credential
credential:
@@ -492,10 +511,12 @@
username: joe
password: secret
register: result
+ when: vmware_found
- assert:
that:
- "result is changed"
+ when: vmware_found
- name: Delete an VMWare credential
credential:
@@ -504,10 +525,12 @@
state: absent
credential_type: VMware vCenter
register: result
+ when: vmware_found
- assert:
that:
- "result is changed"
+ when: vmware_found
- name: Create a valid Satellite6 credential
credential:
@@ -520,10 +543,12 @@
username: joe
password: secret
register: result
+ when: satellite_found
- assert:
that:
- "result is changed"
+ when: satellite_found
- name: Delete a Satellite6 credential
credential:
@@ -532,10 +557,12 @@
state: absent
credential_type: Red Hat Satellite 6
register: result
+ when: satellite_found
- assert:
that:
- "result is changed"
+ when: satellite_found
- name: Create a valid GCE credential
credential:
@@ -548,10 +575,12 @@
project: ABC123
ssh_key_data: "{{ ssh_key_data }}"
register: result
+ when: gce_found
- assert:
that:
- "result is changed"
+ when: gce_found
- name: Delete a GCE credential
credential:
@@ -560,10 +589,12 @@
state: absent
credential_type: Google Compute Engine
register: result
+ when: gce_found
- assert:
that:
- "result is changed"
+ when: gce_found
- name: Create a valid AzureRM credential
credential:
@@ -576,10 +607,12 @@
password: secret
subscription: some-subscription
register: result
+ when: azure_found
- assert:
that:
- "result is changed"
+ when: azure_found
- name: Create a valid AzureRM credential with a tenant
credential:
@@ -593,10 +626,12 @@
tenant: some-tenant
subscription: some-subscription
register: result
+ when: azure_found
- assert:
that:
- "result is changed"
+ when: azure_found
- name: Delete an AzureRM credential
credential:
@@ -605,10 +640,12 @@
state: absent
credential_type: Microsoft Azure Resource Manager
register: result
+ when: azure_found
- assert:
that:
- "result is changed"
+ when: azure_found
- name: Create a valid OpenStack credential
credential:
@@ -623,10 +660,12 @@
project: tenant123
domain: some-domain
register: result
+ when: openstack_found
- assert:
that:
- "result is changed"
+ when: openstack_found
- name: Delete a OpenStack credential
credential:
@@ -635,10 +674,12 @@
state: absent
credential_type: OpenStack
register: result
+ when: openstack_found
- assert:
that:
- "result is changed"
+ when: openstack_found
- name: Create a valid RHV credential
credential:
@@ -651,10 +692,12 @@
username: joe
password: secret
register: result
+ when: rhv_found
- assert:
that:
- "result is changed"
+ when: rhv_found
- name: Delete an RHV credential
credential:
@@ -663,10 +706,12 @@
state: absent
credential_type: Red Hat Virtualization
register: result
+ when: rhv_found
- assert:
that:
- "result is changed"
+ when: rhv_found
- name: Create a valid Insights credential
credential:
@@ -678,10 +723,12 @@
username: joe
password: secret
register: result
+ when: insights_found
- assert:
that:
- "result is changed"
+ when: insights_found
- name: Delete an Insights credential
credential:
@@ -690,10 +737,12 @@
state: absent
credential_type: Insights
register: result
+ when: insights_found
- assert:
that:
- "result is changed"
+ when: insights_found
- name: Create a valid Insights token credential
credential:
@@ -705,10 +754,12 @@
client_id: joe
client_secret: secret
register: result
+ when: insights_found
- assert:
that:
- "result is changed"
+ when: insights_found
- name: Delete an Insights token credential
credential:
@@ -717,10 +768,12 @@
state: absent
credential_type: Insights
register: result
+ when: insights_found
- assert:
that:
- "result is changed"
+ when: insights_found
- name: Create a valid Tower-to-Tower credential
credential:
diff --git a/awx_collection/tests/integration/targets/credential_input_source/tasks/main.yml b/awx_collection/tests/integration/targets/credential_input_source/tasks/main.yml
index 1d56d5e4b1..d5568fdd8d 100644
--- a/awx_collection/tests/integration/targets/credential_input_source/tasks/main.yml
+++ b/awx_collection/tests/integration/targets/credential_input_source/tasks/main.yml
@@ -9,7 +9,17 @@
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: detect credential types
+ ansible.builtin.set_fact:
+ credentials: "{{ lookup('awx.awx.controller_api', 'credential_types') }}"
+
+- name: Register Credentials found
+ set_fact:
+ cyberark_found: "{{ 'CyberArk Central Credential Provider Lookup' in credentials | map(attribute='name') | list }}"
+
+- name: Test credential lookup workflow
+ when: cyberark_found
+ block:
- name: Add credential Lookup
credential:
description: Credential for Testing Source
@@ -121,7 +131,9 @@
that:
- "result is changed"
- always:
+- name: Clean up if previous block ran
+ when: cyberark_found
+ block:
- name: Remove a credential source
credential_input_source:
input_field_name: password
diff --git a/awx_collection/tests/integration/targets/inventory/tasks/main.yml b/awx_collection/tests/integration/targets/inventory/tasks/main.yml
index dbaf7dbcec..b3a72fd033 100644
--- a/awx_collection/tests/integration/targets/inventory/tasks/main.yml
+++ b/awx_collection/tests/integration/targets/inventory/tasks/main.yml
@@ -8,7 +8,6 @@
set_fact:
inv_name1: "AWX-Collection-tests-inventory-inv1-{{ test_id }}"
inv_name2: "AWX-Collection-tests-inventory-inv2-{{ test_id }}"
- cred_name1: "AWX-Collection-tests-inventory-cred1-{{ test_id }}"
group_name1: "AWX-Collection-tests-instance_group-group1-{{ test_id }}"
- block:
@@ -23,21 +22,6 @@
that:
- "result is changed"
- - name: Create an Insights Credential
- credential:
- name: "{{ cred_name1 }}"
- organization: Default
- credential_type: Insights
- inputs:
- username: joe
- password: secret
- state: present
- register: result
-
- - assert:
- that:
- - "result is changed"
-
- name: Create an Inventory
inventory:
name: "{{ inv_name1 }}"
@@ -227,10 +211,3 @@
instance_group:
name: "{{ group_name1 }}"
state: absent
-
- - name: Delete Insights Credential
- credential:
- name: "{{ cred_name1 }}"
- organization: "Default"
- credential_type: Insights
- state: absent
diff --git a/awx_collection/tests/integration/targets/inventory_source/tasks/main.yml b/awx_collection/tests/integration/targets/inventory_source/tasks/main.yml
deleted file mode 100644
index a0442eeaf2..0000000000
--- a/awx_collection/tests/integration/targets/inventory_source/tasks/main.yml
+++ /dev/null
@@ -1,143 +0,0 @@
----
-- name: Generate a test ID
- set_fact:
- test_id: "{{ lookup('password', '/dev/null chars=ascii_letters length=16') }}"
- when: test_id is not defined
-
-- name: Generate names
- set_fact:
- openstack_cred: "AWX-Collection-tests-inventory_source-cred-openstack-{{ test_id }}"
- openstack_inv: "AWX-Collection-tests-inventory_source-inv-openstack-{{ test_id }}"
- openstack_inv_source: "AWX-Collection-tests-inventory_source-inv-source-openstack-{{ test_id }}"
-
-- name: Add a credential
- credential:
- description: Credentials for Openstack Test project
- name: "{{ openstack_cred }}"
- credential_type: OpenStack
- organization: Default
- inputs:
- project: Test
- username: admin
- host: https://example.org:5000
- password: passw0rd
- domain: test
- register: credential_result
-
-- name: Add an inventory
- inventory:
- description: Test inventory
- organization: Default
- name: "{{ openstack_inv }}"
-
-- name: Create an source inventory
- inventory_source:
- name: "{{ openstack_inv_source }}"
- description: Source for Test inventory
- inventory: "{{ openstack_inv }}"
- credential: "{{ credential_result.id }}"
- overwrite: true
- update_on_launch: true
- source_vars:
- private: false
- source: openstack
- register: result
-
-- assert:
- that:
- - "result is changed"
-
-- name: Create an source inventory with exists
- inventory_source:
- name: "{{ openstack_inv_source }}"
- description: Source for Test inventory
- inventory: "{{ openstack_inv }}"
- credential: "{{ credential_result.id }}"
- overwrite: true
- update_on_launch: true
- source_vars:
- private: false
- source: openstack
- state: exists
- register: result
-
-- assert:
- that:
- - "result is not changed"
-
-- name: Delete an source inventory
- inventory_source:
- name: "{{ openstack_inv_source }}"
- description: Source for Test inventory
- inventory: "{{ openstack_inv }}"
- credential: "{{ credential_result.id }}"
- overwrite: true
- update_on_launch: true
- source_vars:
- private: false
- source: openstack
- state: absent
- register: result
-
-- assert:
- that:
- - "result is changed"
-
-- name: Create an source inventory with exists
- inventory_source:
- name: "{{ openstack_inv_source }}"
- description: Source for Test inventory
- inventory: "{{ openstack_inv }}"
- credential: "{{ credential_result.id }}"
- overwrite: true
- update_on_launch: true
- source_vars:
- private: false
- source: openstack
- state: exists
- register: result
-
-- assert:
- that:
- - "result is changed"
-
-- name: Delete the inventory source with an invalid cred and source_project specified
- inventory_source:
- name: "{{ result.id }}"
- inventory: "{{ openstack_inv }}"
- credential: "Does Not Exit"
- source_project: "Does Not Exist"
- state: absent
-
-- assert:
- that:
- - "result is changed"
-
-- name: Delete the credential
- credential:
- description: Credentials for Openstack Test project
- name: "{{ openstack_cred }}"
- credential_type: OpenStack
- organization: Default
- inputs:
- project: Test
- username: admin
- host: https://example.org:5000
- password: passw0rd
- domain: test
- state: absent
-
-- assert:
- that:
- - "result is changed"
-
-- name: Delete the inventory
- inventory:
- description: Test inventory
- organization: Default
- name: "{{ openstack_inv }}"
- state: absent
-
-- assert:
- that:
- - "result is changed"
diff --git a/awx_collection/tests/integration/targets/workflow_job_template/tasks/main.yml b/awx_collection/tests/integration/targets/workflow_job_template/tasks/main.yml
index f051e47ad9..e3f25c415d 100644
--- a/awx_collection/tests/integration/targets/workflow_job_template/tasks/main.yml
+++ b/awx_collection/tests/integration/targets/workflow_job_template/tasks/main.yml
@@ -28,6 +28,14 @@
ig2: "AWX-Collection-tests-workflow_job_template-ig2-{{ test_id }}"
host1: "AWX-Collection-tests-workflow_job_template-h1-{{ test_id }}"
+- name: detect credential types
+ ansible.builtin.set_fact:
+ credentials: "{{ lookup('awx.awx.controller_api', 'credential_types') }}"
+
+- name: Register Credentials found
+ set_fact:
+ github_found: "{{ 'Github Personal Access Token' in credentials | map(attribute='name') | list }}"
+
- block:
- name: "Create a new organization"
organization:
@@ -36,22 +44,30 @@
- Ansible Galaxy
register: result
- - name: Create Credentials
+ - name: Create SCM Credential
credential:
- name: "{{ item.name }}"
+ name: "{{ scm_cred_name }}"
organization: Default
- credential_type: "{{ item.type }}"
+ credential_type: Source Control
register: result
- loop:
- - name: "{{ scm_cred_name }}"
- type: Source Control
- - name: "{{ github_webhook_credential_name }}"
- type: GitHub Personal Access Token
- assert:
that:
- "result is changed"
+ - name: Create Github PAT Credential
+ credential:
+ name: "{{ github_webhook_credential_name }}"
+ organization: Default
+ credential_type: Github Personal Access Token
+ register: result
+ when: github_found
+
+ - assert:
+ that:
+ - "result is changed"
+ when: github_found
+
- name: Add email notification
notification_template:
name: "{{ email_not }}"
@@ -867,8 +883,8 @@
name: "{{ webhook_wfjt_name }}"
organization: Default
inventory: Demo Inventory
- webhook_service: gitlab
- webhook_credential: "{{ github_webhook_credential_name }}"
+ webhook_service: "{{ 'gitlab' if github_found else omit }}"
+ webhook_credential: "{{ github_webhook_credential_name if github_found else omit }}"
ignore_errors: true
register: result
@@ -876,14 +892,15 @@
that:
- result is failed
- "'Must match the selected webhook service' in result['msg']"
+ when: github_found and gitlab_found
- name: Create a workflow job template with a GitHub webhook and a GitHub credential
workflow_job_template:
name: "{{ webhook_wfjt_name }}"
organization: Default
inventory: Demo Inventory
- webhook_service: github
- webhook_credential: "{{ github_webhook_credential_name }}"
+ webhook_service: "{{ 'github' if github_found else omit }}"
+ webhook_credential: "{{ github_webhook_credential_name if github_found else omit }}"
register: result
- assert:
diff --git a/requirements/requirements_git.txt b/requirements/requirements_git.txt
index 9818bb7f52..07e0b8878c 100644
--- a/requirements/requirements_git.txt
+++ b/requirements/requirements_git.txt
@@ -2,5 +2,5 @@ git+https://github.com/ansible/system-certifi.git@devel#egg=certifi
# Remove pbr from requirements.in when moving ansible-runner to requirements.in
git+https://github.com/ansible/ansible-runner.git@devel#egg=ansible-runner
django-ansible-base @ git+https://github.com/ansible/django-ansible-base@devel#egg=django-ansible-base[rest-filters,jwt_consumer,resource-registry,rbac]
-awx-plugins-core @ git+https://git@github.com/ansible/awx-plugins.git@devel#egg=awx-plugins-core
+awx-plugins-core @ git+https://github.com/ansible/awx-plugins.git@devel#egg=awx-plugins-core
awx_plugins.interfaces @ git+https://github.com/ansible/awx_plugins.interfaces.git