mirror of
https://github.com/ansible/awx.git
synced 2026-07-12 08:54:31 -02:30
Merge pull request #1233 from AlanCoding/no_turning_back
Raise 400 error on removal of credential on launch
This commit is contained in:
@@ -3734,15 +3734,30 @@ class JobLaunchSerializer(BaseSerializer):
|
||||
distinct_cred_kinds = []
|
||||
for cred in accepted.get('credentials', []):
|
||||
if cred.unique_hash() in distinct_cred_kinds:
|
||||
errors['credentials'] = _('Cannot assign multiple %s credentials.' % cred.credential_type.name)
|
||||
errors.setdefault('credentials', []).append(_(
|
||||
'Cannot assign multiple {} credentials.'
|
||||
).format(cred.unique_hash(display=True)))
|
||||
distinct_cred_kinds.append(cred.unique_hash())
|
||||
|
||||
# Prohibit removing credentials from the JT list (unsupported for now)
|
||||
template_credentials = template.credentials.all()
|
||||
if 'credentials' in attrs:
|
||||
removed_creds = set(template_credentials) - set(attrs['credentials'])
|
||||
provided_mapping = Credential.unique_dict(attrs['credentials'])
|
||||
for cred in removed_creds:
|
||||
if cred.unique_hash() in provided_mapping.keys():
|
||||
continue # User replaced credential with new of same type
|
||||
errors.setdefault('credentials', []).append(_(
|
||||
'Removing {} credential at launch time without replacement is not supported. '
|
||||
'Provided list lacked credential(s): {}.'
|
||||
).format(cred.unique_hash(display=True), ', '.join([str(c) for c in removed_creds])))
|
||||
|
||||
# verify that credentials (either provided or existing) don't
|
||||
# require launch-time passwords that have not been provided
|
||||
if 'credentials' in accepted:
|
||||
launch_credentials = accepted['credentials']
|
||||
else:
|
||||
launch_credentials = template.credentials.all()
|
||||
launch_credentials = template_credentials
|
||||
passwords = attrs.get('credential_passwords', {}) # get from original attrs
|
||||
passwords_lacking = []
|
||||
for cred in launch_credentials:
|
||||
|
||||
@@ -2884,6 +2884,7 @@ class JobTemplateLaunch(RetrieveAPIView):
|
||||
):
|
||||
# make a list of the current credentials
|
||||
existing_credentials = obj.credentials.all()
|
||||
template_credentials = list(existing_credentials) # save copy of existing
|
||||
new_credentials = []
|
||||
for key, conditional in (
|
||||
('credential', lambda cred: cred.credential_type.kind != 'ssh'),
|
||||
@@ -2910,6 +2911,11 @@ class JobTemplateLaunch(RetrieveAPIView):
|
||||
# combine the list of "new" and the filtered list of "old"
|
||||
new_credentials.extend([cred.pk for cred in existing_credentials])
|
||||
if new_credentials:
|
||||
# If provided list doesn't contain the pre-existing credentials
|
||||
# defined on the template, add them back here
|
||||
for cred_obj in template_credentials:
|
||||
if cred_obj.pk not in new_credentials:
|
||||
new_credentials.append(cred_obj.pk)
|
||||
modern_data['credentials'] = new_credentials
|
||||
|
||||
# credential passwords were historically provided as top-level attributes
|
||||
|
||||
@@ -283,7 +283,7 @@ def test_job_launch_JT_with_validation(machine_credential, credential, deploy_jo
|
||||
deploy_jobtemplate.ask_variables_on_launch = True
|
||||
deploy_jobtemplate.save()
|
||||
|
||||
kv = dict(extra_vars={"job_launch_var": 4}, credentials=[machine_credential.pk])
|
||||
kv = dict(extra_vars={"job_launch_var": 4}, credentials=[machine_credential.pk, credential.pk])
|
||||
serializer = JobLaunchSerializer(data=kv, context={'template': deploy_jobtemplate})
|
||||
validated = serializer.is_valid()
|
||||
assert validated, serializer.errors
|
||||
@@ -338,16 +338,17 @@ def test_job_launch_JT_enforces_unique_credentials_kinds(machine_credential, cre
|
||||
|
||||
|
||||
@pytest.mark.django_db
|
||||
def test_job_launch_with_empty_creds(machine_credential, vault_credential, deploy_jobtemplate):
|
||||
def test_job_launch_with_empty_creds(machine_credential, vault_credential, deploy_jobtemplate, credential):
|
||||
deploy_jobtemplate.ask_credential_on_launch = True
|
||||
deploy_jobtemplate.credentials.add(machine_credential)
|
||||
deploy_jobtemplate.credentials.add(vault_credential)
|
||||
kv = dict(credentials=[])
|
||||
# `credentials` list is strictly those already present on deploy_jobtemplate
|
||||
kv = dict(credentials=[credential.pk, machine_credential.pk, vault_credential.pk])
|
||||
serializer = JobLaunchSerializer(data=kv, context={'template': deploy_jobtemplate})
|
||||
validated = serializer.is_valid()
|
||||
assert validated
|
||||
assert validated, serializer.errors
|
||||
|
||||
prompted_fields, ignored_fields, errors = deploy_jobtemplate._accept_or_ignore_job_kwargs(**kv)
|
||||
prompted_fields, ignored_fields, errors = deploy_jobtemplate._accept_or_ignore_job_kwargs(**serializer.validated_data)
|
||||
job_obj = deploy_jobtemplate.create_unified_job(**prompted_fields)
|
||||
assert job_obj.credential is deploy_jobtemplate.credential
|
||||
assert job_obj.vault_credential is deploy_jobtemplate.vault_credential
|
||||
|
||||
Reference in New Issue
Block a user