mirror of
https://github.com/ansible/awx.git
synced 2026-03-25 12:55:04 -02:30
AAP-67740 Pass plugin_description through to CredentialType.description (#16364)
* Pass plugin_description through to CredentialType.description Propagate the plugin_description field from credential plugins into the CredentialType description when loading and creating managed credential types, including updates to existing records. Assisted-by: Claude * Add unit tests for plugin_description passthrough to CredentialType Tests cover load_plugin, get_creation_params, and _setup_tower_managed_defaults handling of the description field. Assisted-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: PabloHiro <palonso@redhat.com>
This commit is contained in:
@@ -531,6 +531,7 @@ class CredentialType(CommonModelNameNotUnique):
|
||||
existing = ct_class.objects.filter(name=default.name, kind=default.kind).first()
|
||||
if existing is not None:
|
||||
existing.namespace = default.namespace
|
||||
existing.description = getattr(default, 'description', '')
|
||||
existing.inputs = {}
|
||||
existing.injectors = {}
|
||||
existing.save()
|
||||
@@ -570,7 +571,14 @@ class CredentialType(CommonModelNameNotUnique):
|
||||
@classmethod
|
||||
def load_plugin(cls, ns, plugin):
|
||||
# TODO: User "side-loaded" credential custom_injectors isn't supported
|
||||
ManagedCredentialType.registry[ns] = SimpleNamespace(namespace=ns, name=plugin.name, kind='external', inputs=plugin.inputs, backend=plugin.backend)
|
||||
ManagedCredentialType.registry[ns] = SimpleNamespace(
|
||||
namespace=ns,
|
||||
name=plugin.name,
|
||||
kind='external',
|
||||
inputs=plugin.inputs,
|
||||
backend=plugin.backend,
|
||||
description=getattr(plugin, 'plugin_description', ''),
|
||||
)
|
||||
|
||||
def inject_credential(self, credential, env, safe_env, args, private_data_dir, container_root=None):
|
||||
from awx_plugins.interfaces._temporary_private_inject_api import inject_credential
|
||||
@@ -582,7 +590,13 @@ class CredentialTypeHelper:
|
||||
@classmethod
|
||||
def get_creation_params(cls, cred_type):
|
||||
if cred_type.kind == 'external':
|
||||
return dict(namespace=cred_type.namespace, kind=cred_type.kind, name=cred_type.name, managed=True)
|
||||
return {
|
||||
'namespace': cred_type.namespace,
|
||||
'kind': cred_type.kind,
|
||||
'name': cred_type.name,
|
||||
'managed': True,
|
||||
'description': getattr(cred_type, 'description', ''),
|
||||
}
|
||||
return dict(
|
||||
namespace=cred_type.namespace,
|
||||
kind=cred_type.kind,
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
import pytest
|
||||
|
||||
from types import SimpleNamespace
|
||||
from unittest import mock
|
||||
|
||||
from awx.main.models import Credential, CredentialType
|
||||
from awx.main.models.credential import CredentialTypeHelper, ManagedCredentialType
|
||||
|
||||
from django.apps import apps
|
||||
|
||||
@@ -78,3 +82,53 @@ def test_credential_context_property_independent_instances():
|
||||
assert cred1.context == {'key1': 'value1'}
|
||||
assert cred2.context == {'key2': 'value2'}
|
||||
assert cred1.context is not cred2.context
|
||||
|
||||
|
||||
def test_load_plugin_passes_description():
|
||||
plugin = SimpleNamespace(name='test_plugin', inputs={'fields': []}, backend=None, plugin_description='A test plugin')
|
||||
CredentialType.load_plugin('test_ns', plugin)
|
||||
entry = ManagedCredentialType.registry['test_ns']
|
||||
assert entry.description == 'A test plugin'
|
||||
del ManagedCredentialType.registry['test_ns']
|
||||
|
||||
|
||||
def test_load_plugin_missing_description():
|
||||
plugin = SimpleNamespace(name='test_plugin', inputs={'fields': []}, backend=None)
|
||||
CredentialType.load_plugin('test_ns', plugin)
|
||||
entry = ManagedCredentialType.registry['test_ns']
|
||||
assert entry.description == ''
|
||||
del ManagedCredentialType.registry['test_ns']
|
||||
|
||||
|
||||
def test_get_creation_params_external_includes_description():
|
||||
cred_type = SimpleNamespace(namespace='test_ns', kind='external', name='Test', description='My description')
|
||||
params = CredentialTypeHelper.get_creation_params(cred_type)
|
||||
assert params['description'] == 'My description'
|
||||
|
||||
|
||||
def test_get_creation_params_external_missing_description():
|
||||
cred_type = SimpleNamespace(namespace='test_ns', kind='external', name='Test')
|
||||
params = CredentialTypeHelper.get_creation_params(cred_type)
|
||||
assert params['description'] == ''
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_setup_tower_managed_defaults_updates_description():
|
||||
registry_entry = SimpleNamespace(
|
||||
namespace='test_ns',
|
||||
kind='external',
|
||||
name='Test Plugin',
|
||||
inputs={'fields': []},
|
||||
backend=None,
|
||||
description='Updated description',
|
||||
)
|
||||
# Create an existing credential type with no description
|
||||
ct = CredentialType.objects.create(name='Test Plugin', kind='external', namespace='old_ns')
|
||||
assert ct.description == ''
|
||||
|
||||
with mock.patch.dict(ManagedCredentialType.registry, {'test_ns': registry_entry}, clear=True):
|
||||
CredentialType._setup_tower_managed_defaults()
|
||||
|
||||
ct.refresh_from_db()
|
||||
assert ct.description == 'Updated description'
|
||||
assert ct.namespace == 'test_ns'
|
||||
|
||||
Reference in New Issue
Block a user