diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 6e16646de1..7cf2b5a5c5 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -288,11 +288,12 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour @classmethod def _get_unified_job_field_names(cls): return ['name', 'description', 'job_type', 'inventory', 'project', - 'playbook', 'credential', 'extra_credentials', 'forks', - 'schedule', 'limit', 'verbosity', 'job_tags', 'extra_vars', - 'launch_type', 'force_handlers', 'skip_tags', 'start_at_task', - 'become_enabled', 'labels', 'survey_passwords', - 'allow_simultaneous', 'timeout', 'use_fact_cache',] + 'playbook', 'credential', 'vault_credential', + 'extra_credentials', 'forks', 'schedule', 'limit', 'verbosity', + 'job_tags', 'extra_vars', 'launch_type', 'force_handlers', + 'skip_tags', 'start_at_task', 'become_enabled', 'labels', + 'survey_passwords', 'allow_simultaneous', 'timeout', + 'use_fact_cache',] def resource_validation_data(self): ''' diff --git a/awx/main/tasks.py b/awx/main/tasks.py index b32e5bfb16..4d68c18fa6 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -872,15 +872,19 @@ class RunJob(BaseTask): and ansible-vault. ''' passwords = super(RunJob, self).build_passwords(job, **kwargs) - creds = job.credential - if creds: - for field in ('ssh_key_unlock', 'ssh_password', 'become_password', 'vault_password'): - if field == 'ssh_password': - value = kwargs.get(field, decrypt_field(creds, 'password')) - else: - value = kwargs.get(field, decrypt_field(creds, field)) - if value not in ('', 'ASK'): - passwords[field] = value + for cred, fields in { + 'credential': ('ssh_key_unlock', 'ssh_password', 'become_password'), + 'vault_credential': ('vault_password',) + }.items(): + cred = getattr(job, cred, None) + if cred: + for field in fields: + if field == 'ssh_password': + value = kwargs.get(field, decrypt_field(cred, 'password')) + else: + value = kwargs.get(field, decrypt_field(cred, field)) + if value not in ('', 'ASK'): + passwords[field] = value return passwords def build_env(self, job, **kwargs): diff --git a/awx/main/tests/functional/api/test_job_runtime_params.py b/awx/main/tests/functional/api/test_job_runtime_params.py index 3626ae89a7..1089242043 100644 --- a/awx/main/tests/functional/api/test_job_runtime_params.py +++ b/awx/main/tests/functional/api/test_job_runtime_params.py @@ -315,6 +315,22 @@ def test_job_launch_JT_enforces_unique_extra_credential_kinds(machine_credential assert validated is False +@pytest.mark.django_db +def test_job_launch_JT_with_default_vault_credential(machine_credential, vault_credential, deploy_jobtemplate): + deploy_jobtemplate.credential = machine_credential + deploy_jobtemplate.vault_credential = vault_credential + serializer = JobLaunchSerializer( + instance=deploy_jobtemplate, data={}, + context={'obj': deploy_jobtemplate, 'data': {}, 'passwords': {}}) + validated = serializer.is_valid() + assert validated + + prompted_fields, ignored_fields = deploy_jobtemplate._accept_or_ignore_job_kwargs(**{}) + job_obj = deploy_jobtemplate.create_unified_job(**prompted_fields) + + assert job_obj.vault_credential.pk == vault_credential.pk + + @pytest.mark.django_db def test_job_launch_JT_with_extra_credentials(machine_credential, credential, net_credential, deploy_jobtemplate): deploy_jobtemplate.ask_credential_on_launch = True diff --git a/awx/main/tests/unit/test_tasks.py b/awx/main/tests/unit/test_tasks.py index ef913e9914..4df45596ba 100644 --- a/awx/main/tests/unit/test_tasks.py +++ b/awx/main/tests/unit/test_tasks.py @@ -4,6 +4,7 @@ from functools import partial import ConfigParser import json import os +import re import shutil import tempfile @@ -404,7 +405,6 @@ class TestJobCredentials(TestJobExecution): dict(field='password', password_name='ssh_password', expected_flag='--ask-pass'), dict(field='ssh_key_unlock', password_name='ssh_key_unlock', expected_flag=None), dict(field='become_password', password_name='become_password', expected_flag='--ask-become-pass'), - dict(field='vault_password', password_name='vault_password', expected_flag='--ask-vault-pass'), ] } @@ -428,6 +428,26 @@ class TestJobCredentials(TestJobExecution): if expected_flag: assert expected_flag in ' '.join(args) + def test_vault_password(self): + vault = CredentialType.defaults['vault']() + credential = Credential( + pk=1, + credential_type=vault, + inputs={'vault_password': 'vault-me'} + ) + credential.inputs['vault_password'] = encrypt_field(credential, 'vault_password') + self.instance.vault_credential = credential + self.task.run(self.pk) + + assert self.run_pexpect.call_count == 1 + call_args, call_kwargs = self.run_pexpect.call_args_list[0] + args, cwd, env, stdout = call_args + + assert call_kwargs.get('expect_passwords')[ + re.compile(r'Vault password:\s*?$', re.M) + ] == 'vault-me' + assert '--ask-vault-pass' in ' '.join(args) + def test_ssh_key_with_agent(self): ssh = CredentialType.defaults['ssh']() credential = Credential(