fix a variety of bugs that break vault pass injection for playbook runs

see: #6924
This commit is contained in:
Ryan Petrello 2017-07-07 12:19:31 -04:00
parent 463ef9d4b0
commit 3c2fe5e6db
4 changed files with 56 additions and 15 deletions

View File

@ -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):
'''

View File

@ -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):

View File

@ -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

View File

@ -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(