remove the deprecated extra_credentials endpoints

This commit is contained in:
Ryan Petrello 2020-04-29 22:25:28 -04:00
parent 72de660ea1
commit 18607107a7
No known key found for this signature in database
GPG Key ID: F2AA5F2122351777
20 changed files with 22 additions and 420 deletions

View File

@ -2756,16 +2756,11 @@ class JobOptionsSerializer(LabelsListMixin, BaseSerializer):
if obj.organization_id:
res['organization'] = self.reverse('api:organization_detail', kwargs={'pk': obj.organization_id})
if isinstance(obj, UnifiedJobTemplate):
res['extra_credentials'] = self.reverse(
'api:job_template_extra_credentials_list',
kwargs={'pk': obj.pk}
)
res['credentials'] = self.reverse(
'api:job_template_credentials_list',
kwargs={'pk': obj.pk}
)
elif isinstance(obj, UnifiedJob):
res['extra_credentials'] = self.reverse('api:job_extra_credentials_list', kwargs={'pk': obj.pk})
res['credentials'] = self.reverse('api:job_credentials_list', kwargs={'pk': obj.pk})
return res
@ -2934,7 +2929,6 @@ class JobTemplateSerializer(JobTemplateMixin, UnifiedJobTemplateSerializer, JobO
summary_fields = super(JobTemplateSerializer, self).get_summary_fields(obj)
all_creds = []
# Organize credential data into multitude of deprecated fields
extra_creds = []
if obj.pk:
for cred in obj.credentials.all():
summarized_cred = {
@ -2945,10 +2939,6 @@ class JobTemplateSerializer(JobTemplateMixin, UnifiedJobTemplateSerializer, JobO
'cloud': cred.credential_type.kind == 'cloud'
}
all_creds.append(summarized_cred)
if cred.credential_type.kind in ('cloud', 'net'):
extra_creds.append(summarized_cred)
if self.is_detail_view:
summary_fields['extra_credentials'] = extra_creds
summary_fields['credentials'] = all_creds
return summary_fields
@ -3023,7 +3013,6 @@ class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer):
summary_fields = super(JobSerializer, self).get_summary_fields(obj)
all_creds = []
# Organize credential data into multitude of deprecated fields
extra_creds = []
if obj.pk:
for cred in obj.credentials.all():
summarized_cred = {
@ -3034,10 +3023,6 @@ class JobSerializer(UnifiedJobSerializer, JobOptionsSerializer):
'cloud': cred.credential_type.kind == 'cloud'
}
all_creds.append(summarized_cred)
if cred.credential_type.kind in ('cloud', 'net'):
extra_creds.append(summarized_cred)
if self.is_detail_view:
summary_fields['extra_credentials'] = extra_creds
summary_fields['credentials'] = all_creds
return summary_fields

View File

@ -23,9 +23,7 @@ from awx.api.views import (
UnifiedJobList,
HostAnsibleFactsDetail,
JobCredentialsList,
JobExtraCredentialsList,
JobTemplateCredentialsList,
JobTemplateExtraCredentialsList,
SchedulePreview,
ScheduleZoneInfo,
OAuth2ApplicationList,
@ -83,9 +81,7 @@ v2_urls = [
url(r'^credential_types/', include(credential_type_urls)),
url(r'^credential_input_sources/', include(credential_input_source_urls)),
url(r'^hosts/(?P<pk>[0-9]+)/ansible_facts/$', HostAnsibleFactsDetail.as_view(), name='host_ansible_facts_detail'),
url(r'^jobs/(?P<pk>[0-9]+)/extra_credentials/$', JobExtraCredentialsList.as_view(), name='job_extra_credentials_list'),
url(r'^jobs/(?P<pk>[0-9]+)/credentials/$', JobCredentialsList.as_view(), name='job_credentials_list'),
url(r'^job_templates/(?P<pk>[0-9]+)/extra_credentials/$', JobTemplateExtraCredentialsList.as_view(), name='job_template_extra_credentials_list'),
url(r'^job_templates/(?P<pk>[0-9]+)/credentials/$', JobTemplateCredentialsList.as_view(), name='job_template_credentials_list'),
url(r'^schedules/preview/$', SchedulePreview.as_view(), name='schedule_rrule'),
url(r'^schedules/zoneinfo/$', ScheduleZoneInfo.as_view(), name='schedule_zoneinfo'),

View File

@ -12,7 +12,7 @@ import socket
import sys
import time
from base64 import b64encode
from collections import OrderedDict, Iterable
from collections import OrderedDict
# Django
@ -2344,51 +2344,6 @@ class JobTemplateLaunch(RetrieveAPIView):
if 'inventory' not in modern_data and id_fd in modern_data:
modern_data['inventory'] = modern_data[id_fd]
# Automatically convert legacy launch credential arguments into a list of `.credentials`
if 'credentials' in modern_data and 'extra_credentials' in modern_data:
raise ParseError({"error": _(
"'credentials' cannot be used in combination with 'extra_credentials'."
)})
if 'extra_credentials' in modern_data:
# make a list of the current credentials
existing_credentials = obj.credentials.all()
template_credentials = list(existing_credentials) # save copy of existing
new_credentials = []
if 'extra_credentials' in modern_data:
existing_credentials = [
cred for cred in existing_credentials
if cred.credential_type.kind not in ('cloud', 'net')
]
prompted_value = modern_data.pop('extra_credentials')
# validate type, since these are not covered by a serializer
if not isinstance(prompted_value, Iterable):
msg = _(
"Incorrect type. Expected a list received {}."
).format(prompted_value.__class__.__name__)
raise ParseError({'extra_credentials': [msg], 'credentials': [msg]})
# add the deprecated credential specified in the request
if not isinstance(prompted_value, Iterable) or isinstance(prompted_value, str):
prompted_value = [prompted_value]
# If user gave extra_credentials, special case to use exactly
# the given list without merging with JT credentials
if prompted_value:
obj._deprecated_credential_launch = True # signal to not merge credentials
new_credentials.extend(prompted_value)
# 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
if 'credential_passwords' not in modern_data:
modern_data['credential_passwords'] = data.copy()
@ -2711,22 +2666,6 @@ class JobTemplateCredentialsList(SubListCreateAttachDetachAPIView):
return super(JobTemplateCredentialsList, self).is_valid_relation(parent, sub, created)
class JobTemplateExtraCredentialsList(JobTemplateCredentialsList):
deprecated = True
def get_queryset(self):
sublist_qs = super(JobTemplateExtraCredentialsList, self).get_queryset()
sublist_qs = sublist_qs.filter(credential_type__kind__in=['cloud', 'net'])
return sublist_qs
def is_valid_relation(self, parent, sub, created=False):
valid = super(JobTemplateExtraCredentialsList, self).is_valid_relation(parent, sub, created)
if sub.credential_type.kind not in ('cloud', 'net'):
return {'error': _('Extra credentials must be network or cloud.')}
return valid
class JobTemplateLabelList(DeleteLastUnattachLabelMixin, SubListCreateAttachDetachAPIView):
model = models.Label
@ -3543,16 +3482,6 @@ class JobCredentialsList(SubListAPIView):
relationship = 'credentials'
class JobExtraCredentialsList(JobCredentialsList):
deprecated = True
def get_queryset(self):
sublist_qs = super(JobExtraCredentialsList, self).get_queryset()
sublist_qs = sublist_qs.filter(credential_type__kind__in=['cloud', 'net'])
return sublist_qs
class JobLabelList(SubListAPIView):
model = models.Label

View File

@ -439,13 +439,9 @@ class JobTemplate(UnifiedJobTemplate, JobOptions, SurveyJobTemplateMixin, Resour
field = self._meta.get_field(field_name)
if isinstance(field, models.ManyToManyField):
old_value = set(old_value.all())
if getattr(self, '_deprecated_credential_launch', False):
# TODO: remove this code branch when support for `extra_credentials` goes away
new_value = set(kwargs[field_name])
else:
new_value = set(kwargs[field_name]) - old_value
if not new_value:
continue
new_value = set(kwargs[field_name]) - old_value
if not new_value:
continue
if new_value == old_value:
# no-op case: Fields the same as template's value

View File

@ -413,9 +413,8 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, Notificatio
if 'extra_vars' in validated_kwargs:
unified_job.handle_extra_data(validated_kwargs['extra_vars'])
if not getattr(self, '_deprecated_credential_launch', False):
# Create record of provided prompts for relaunch and rescheduling
unified_job.create_config_from_prompts(kwargs, parent=self)
# Create record of provided prompts for relaunch and rescheduling
unified_job.create_config_from_prompts(kwargs, parent=self)
# manually issue the create activity stream entry _after_ M2M relations
# have been associated to the UJ

View File

@ -105,9 +105,6 @@ class TestSwaggerGeneration():
'get', 'put', 'patch', 'delete'
]
# Test deprecated paths
assert paths['/api/v2/jobs/{id}/extra_credentials/']['get']['deprecated'] is True
@pytest.mark.parametrize('path', [
'/api/',
'/api/v2/',

View File

@ -24,41 +24,6 @@ def job_template(job_template, project, inventory):
return job_template
@pytest.mark.django_db
def test_extra_credentials_filtering(get, job_template, admin,
machine_credential, vault_credential, credential):
job_template.credentials.add(machine_credential)
job_template.credentials.add(vault_credential)
job_template.credentials.add(credential)
url = reverse(
'api:job_template_extra_credentials_list',
kwargs={'pk': job_template.pk}
)
resp = get(url, admin, expect=200)
assert resp.data['count'] == 1
assert resp.data['results'][0]['id'] == credential.pk
@pytest.mark.django_db
def test_extra_credentials_requires_cloud_or_net(get, post, job_template, admin,
machine_credential, vault_credential, credential,
net_credential):
url = reverse(
'api:job_template_extra_credentials_list',
kwargs={'pk': job_template.pk}
)
for cred in (machine_credential, vault_credential):
resp = post(url, {'associate': True, 'id': cred.pk}, admin, expect=400)
assert 'Extra credentials must be network or cloud.' in smart_str(resp.content)
post(url, {'associate': True, 'id': credential.pk}, admin, expect=204)
assert get(url, admin).data['count'] == 1
post(url, {'associate': True, 'id': net_credential.pk}, admin, expect=204)
assert get(url, admin).data['count'] == 2
@pytest.mark.django_db
def test_prevent_multiple_machine_creds(get, post, job_template, admin, machine_credential):
url = reverse(
@ -115,52 +80,6 @@ def test_prevent_multiple_machine_creds_at_launch(get, post, job_template, admin
assert 'Cannot assign multiple Machine credentials.' in smart_str(resp.content)
@pytest.mark.django_db
def test_extra_credentials_unique_by_kind(get, post, job_template, admin,
credentialtype_aws):
url = reverse(
'api:job_template_extra_credentials_list',
kwargs={'pk': job_template.pk}
)
def _new_cred(name):
return {
'name': name,
'credential_type': credentialtype_aws.pk,
'inputs': {
'username': 'bob',
'password': 'secret',
}
}
post(url, _new_cred('First Cred'), admin, expect=201)
assert get(url, admin).data['count'] == 1
resp = post(url, _new_cred('Second Cred'), admin, expect=400)
assert 'Cannot assign multiple Amazon Web Services credentials.' in smart_str(resp.content)
@pytest.mark.django_db
def test_extra_credentials_at_launch(get, post, job_template, admin, credential):
url = reverse('api:job_template_launch', kwargs={'pk': job_template.pk})
pk = post(url, {'extra_credentials': [credential.pk]}, admin, expect=201).data['job']
summary_fields = get(reverse('api:job_detail', kwargs={'pk': pk}), admin).data['summary_fields']
assert len(summary_fields['credentials']) == 1
@pytest.mark.django_db
def test_modify_extra_credentials_at_launch(get, post, job_template, admin,
machine_credential, vault_credential, credential):
job_template.credentials.add(machine_credential)
job_template.credentials.add(vault_credential)
url = reverse('api:job_template_launch', kwargs={'pk': job_template.pk})
pk = post(url, {'extra_credentials': [credential.pk]}, admin, expect=201).data['job']
summary_fields = get(reverse('api:job_detail', kwargs={'pk': pk}), admin).data['summary_fields']
assert len(summary_fields['credentials']) == 3
@pytest.mark.django_db
def test_ssh_password_prompted_at_launch(get, post, job_template, admin, machine_credential):
job_template.credentials.add(machine_credential)
@ -229,25 +148,6 @@ def test_vault_credential_with_password_at_launch(get, post, job_template, admin
signal_start.assert_called_with(vault_password='testing123')
@pytest.mark.django_db
def test_extra_creds_prompted_at_launch(get, post, job_template, admin, net_credential):
url = reverse('api:job_template_launch', kwargs={'pk': job_template.pk})
resp = post(url, {'extra_credentials': [net_credential.pk]}, admin, expect=201)
summary_fields = get(
reverse('api:job_detail', kwargs={'pk': resp.data['job']}),
admin
).data['summary_fields']
assert len(summary_fields['credentials']) == 1
@pytest.mark.django_db
def test_invalid_mixed_credentials_specification(get, post, job_template, admin, net_credential):
url = reverse('api:job_template_launch', kwargs={'pk': job_template.pk})
post(url=url, data={'credentials': [net_credential.pk], 'extra_credentials': [net_credential.pk]},
user=admin, expect=400)
@pytest.mark.django_db
def test_deprecated_credential_activity_stream(patch, admin_user, machine_credential, job_template):
job_template.credentials.add(machine_credential)

View File

@ -22,20 +22,6 @@ from awx.main.models import (
)
@pytest.mark.django_db
def test_extra_credentials(get, organization_factory, job_template_factory, credential):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
jt.credentials.add(credential)
jt.save()
job = jt.create_unified_job()
url = reverse('api:job_extra_credentials_list', kwargs={'pk': job.pk})
response = get(url, user=objs.superusers.admin)
assert response.data.get('count') == 1
@pytest.mark.django_db
def test_job_relaunch_permission_denied_response(
post, get, inventory, project, credential, net_credential, machine_credential):
@ -50,7 +36,7 @@ def test_job_relaunch_permission_denied_response(
r = get(job.get_absolute_url(), jt_user, expect=200)
assert r.data['summary_fields']['user_capabilities']['start']
# Job has prompted extra_credential, launch denied w/ message
# Job has prompted credential, launch denied w/ message
job.launch_config.credentials.add(net_credential)
r = post(reverse('api:job_relaunch', kwargs={'pk':job.pk}), {}, jt_user, expect=403)
assert 'launched with prompted fields you do not have access to' in r.data['detail']
@ -70,7 +56,7 @@ def test_job_relaunch_prompts_not_accepted_response(
r = get(job.get_absolute_url(), jt_user, expect=200)
assert r.data['summary_fields']['user_capabilities']['start']
# Job has prompted extra_credential, launch denied w/ message
# Job has prompted credential, launch denied w/ message
job.launch_config.credentials.add(net_credential)
r = post(reverse('api:job_relaunch', kwargs={'pk':job.pk}), {}, jt_user, expect=403)

View File

@ -304,7 +304,7 @@ def test_job_launch_with_default_creds(machine_credential, vault_credential, dep
@pytest.mark.django_db
def test_job_launch_JT_enforces_unique_credentials_kinds(machine_credential, credentialtype_aws, deploy_jobtemplate):
"""
JT launching should require that extra_credentials have distinct CredentialTypes
JT launching should require that credentials have distinct CredentialTypes
"""
creds = []
for i in range(2):

View File

@ -45,27 +45,6 @@ def test_create(post, project, machine_credential, inventory, alice, grant_proje
)
@pytest.mark.django_db
def test_extra_credential_creation(get, post, organization_factory, job_template_factory, credentialtype_aws):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
url = reverse('api:job_template_extra_credentials_list', kwargs={'pk': jt.pk})
response = post(url, {
'name': 'My Cred',
'credential_type': credentialtype_aws.pk,
'inputs': {
'username': 'bob',
'password': 'secret',
}
}, objs.superusers.admin)
assert response.status_code == 201
response = get(url, user=objs.superusers.admin)
assert response.data.get('count') == 1
@pytest.mark.django_db
@pytest.mark.parametrize('kind', ['scm', 'insights'])
def test_invalid_credential_kind_xfail(get, post, organization_factory, job_template_factory, kind):
@ -87,42 +66,6 @@ def test_invalid_credential_kind_xfail(get, post, organization_factory, job_temp
assert 'Cannot assign a Credential of kind `{}`.'.format(kind) in response.data.values()
@pytest.mark.django_db
def test_extra_credential_unique_type_xfail(get, post, organization_factory, job_template_factory, credentialtype_aws):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
url = reverse('api:job_template_extra_credentials_list', kwargs={'pk': jt.pk})
response = post(url, {
'name': 'My Cred',
'credential_type': credentialtype_aws.pk,
'inputs': {
'username': 'bob',
'password': 'secret',
}
}, objs.superusers.admin)
assert response.status_code == 201
response = get(url, user=objs.superusers.admin)
assert response.data.get('count') == 1
# this request should fail because you can't assign the same type (aws)
# twice
response = post(url, {
'name': 'My Cred',
'credential_type': credentialtype_aws.pk,
'inputs': {
'username': 'joe',
'password': 'another-secret',
}
}, objs.superusers.admin)
assert response.status_code == 400
response = get(url, user=objs.superusers.admin)
assert response.data.get('count') == 1
@pytest.mark.django_db
def test_create_with_forks_exceeding_maximum_xfail(alice, post, project, inventory, settings):
project.use_role.members.add(alice)
@ -143,60 +86,6 @@ def test_create_with_forks_exceeding_maximum_xfail(alice, post, project, invento
assert 'Maximum number of forks (10) exceeded' in str(response.data)
@pytest.mark.django_db
def test_attach_extra_credential(get, post, organization_factory, job_template_factory, credential):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
url = reverse('api:job_template_extra_credentials_list', kwargs={'pk': jt.pk})
response = post(url, {
'associate': True,
'id': credential.id,
}, objs.superusers.admin)
assert response.status_code == 204
response = get(url, user=objs.superusers.admin)
assert response.data.get('count') == 1
@pytest.mark.django_db
def test_detach_extra_credential(get, post, organization_factory, job_template_factory, credential):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
jt.credentials.add(credential)
jt.save()
url = reverse('api:job_template_extra_credentials_list', kwargs={'pk': jt.pk})
response = post(url, {
'disassociate': True,
'id': credential.id,
}, objs.superusers.admin)
assert response.status_code == 204
response = get(url, user=objs.superusers.admin)
assert response.data.get('count') == 0
@pytest.mark.django_db
def test_attach_extra_credential_wrong_kind_xfail(get, post, organization_factory, job_template_factory, machine_credential):
"""Extra credentials only allow net + cloud credentials"""
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
url = reverse('api:job_template_extra_credentials_list', kwargs={'pk': jt.pk})
response = post(url, {
'associate': True,
'id': machine_credential.id,
}, objs.superusers.admin)
assert response.status_code == 400
response = get(url, user=objs.superusers.admin)
assert response.data.get('count') == 0
@pytest.mark.django_db
@pytest.mark.parametrize(
"grant_project, grant_inventory, expect", [
@ -368,57 +257,6 @@ def test_launch_with_pending_deletion_inventory_workflow(get, post, organization
assert resp.data['inventory'] == ['The inventory associated with this Workflow is being deleted.']
@pytest.mark.django_db
def test_launch_with_extra_credentials(get, post, organization_factory,
job_template_factory, machine_credential,
credential, net_credential):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
jt.ask_credential_on_launch = True
jt.save()
resp = post(
reverse('api:job_template_launch', kwargs={'pk': jt.pk}),
dict(
credentials=[machine_credential.pk, credential.pk, net_credential.pk]
),
objs.superusers.admin, expect=201
)
job_pk = resp.data.get('id')
resp = get(reverse('api:job_extra_credentials_list', kwargs={'pk': job_pk}), objs.superusers.admin)
assert resp.data.get('count') == 2
resp = get(reverse('api:job_template_extra_credentials_list', kwargs={'pk': jt.pk}), objs.superusers.admin)
assert resp.data.get('count') == 0
@pytest.mark.django_db
def test_launch_with_extra_credentials_not_allowed(get, post, organization_factory,
job_template_factory, machine_credential,
credential, net_credential):
objs = organization_factory("org", superusers=['admin'])
jt = job_template_factory("jt", organization=objs.organization,
inventory='test_inv', project='test_proj').job_template
jt.credentials.add(machine_credential)
jt.ask_credential_on_launch = False
jt.save()
resp = post(
reverse('api:job_template_launch', kwargs={'pk': jt.pk}),
dict(
credentials=[machine_credential.pk, credential.pk, net_credential.pk]
),
objs.superusers.admin
)
assert 'credentials' in resp.data['ignored_fields'].keys()
job_pk = resp.data.get('id')
resp = get(reverse('api:job_extra_credentials_list', kwargs={'pk': job_pk}), objs.superusers.admin)
assert resp.data.get('count') == 0
@pytest.mark.django_db
def test_jt_without_project(inventory):
data = dict(name="Test", job_type="run",

View File

@ -128,7 +128,7 @@ def test_job_template_access_admin(role_names, jt_linked, rando):
@pytest.mark.django_db
def test_job_template_extra_credentials_prompts_access(
def test_job_template_credentials_prompts_access(
rando, post, inventory, project, machine_credential, vault_credential):
jt = JobTemplate.objects.create(
name = 'test-jt',
@ -149,14 +149,14 @@ def test_job_template_extra_credentials_prompts_access(
@pytest.mark.django_db
class TestJobTemplateCredentials:
def test_job_template_cannot_add_extra_credentials(self, job_template, credential, rando):
def test_job_template_cannot_add_credentials(self, job_template, credential, rando):
job_template.admin_role.members.add(rando)
credential.read_role.members.add(rando)
# without permission to credential, user can not attach it
assert not JobTemplateAccess(rando).can_attach(
job_template, credential, 'credentials', {})
def test_job_template_can_add_extra_credentials(self, job_template, credential, rando):
def test_job_template_can_add_credentials(self, job_template, credential, rando):
job_template.admin_role.members.add(rando)
credential.use_role.members.add(rando)
# user has permission to apply credential

View File

@ -123,9 +123,9 @@ export default
if(!Empty(scope.selected_credentials.machine)) {
job_launch_data.credential_id = scope.selected_credentials.machine.id;
}
job_launch_data.extra_credentials = [];
job_launch_data.credentials = [];
scope.selected_credentials.extra.forEach((extraCredential) => {
job_launch_data.extra_credentials.push(extraCredential.id);
job_launch_data.credentials.push(extraCredential.id);
});
}

View File

@ -9,7 +9,6 @@
"labels": "/api/v2/job_templates/7/labels/",
"inventory": "/api/v2/inventories/1/",
"project": "/api/v2/projects/6/",
"extra_credentials": "/api/v2/job_templates/7/extra_credentials/",
"credentials": "/api/v2/job_templates/7/credentials/",
"last_job": "/api/v2/jobs/12/",
"jobs": "/api/v2/job_templates/7/jobs/",
@ -143,7 +142,6 @@
"type": "job"
}
],
"extra_credentials": [],
"credentials": [
{
"id": 1, "kind": "ssh" , "name": "Credential 1"
@ -195,4 +193,4 @@
"job_slice_count": 1,
"webhook_service": "github",
"webhook_credential": 8
}
}

View File

@ -7,7 +7,6 @@
"labels": "/api/v2/jobs/2/labels/",
"inventory": "/api/v2/inventories/1/",
"project": "/api/v2/projects/6/",
"extra_credentials": "/api/v2/jobs/2/extra_credentials/",
"credentials": "/api/v2/jobs/2/credentials/",
"unified_job_template": "/api/v2/job_templates/7/",
"stdout": "/api/v2/jobs/2/stdout/",
@ -80,7 +79,6 @@
"count": 0,
"results": []
},
"extra_credentials": [],
"credentials": [
{
"id": 1,

View File

@ -9,7 +9,6 @@
"labels": "/api/v2/job_templates/7/labels/",
"inventory": "/api/v2/inventories/1/",
"project": "/api/v2/projects/6/",
"extra_credentials": "/api/v2/job_templates/7/extra_credentials/",
"credentials": "/api/v2/job_templates/7/credentials/",
"last_job": "/api/v2/jobs/12/",
"jobs": "/api/v2/job_templates/7/jobs/",
@ -118,7 +117,6 @@
"finished": "2019-10-01T14:34:35.142483Z",
"type": "job"
}],
"extra_credentials": [],
"credentials": [{
"id": 1,
"kind": "ssh",

View File

@ -362,9 +362,7 @@ class Credentials(page.PageList, Credential):
page.register_page([resources.credentials,
resources.related_credentials,
resources.job_extra_credentials,
resources.job_template_extra_credentials],
resources.related_credentials],
Credentials)

View File

@ -189,16 +189,6 @@ class JobTemplate(
dict(id=kwargs['vault_credential']))
return ret
def add_extra_credential(self, credential):
with suppress(exc.NoContent):
self.related.extra_credentials.post(
dict(id=credential.id, associate=True))
def remove_extra_credential(self, credential):
with suppress(exc.NoContent):
self.related.extra_credentials.post(
dict(id=credential.id, disassociate=True))
def add_credential(self, credential):
with suppress(exc.NoContent):
self.related.credentials.post(

View File

@ -88,7 +88,6 @@ class Resources(object):
_job_event = r'job_events/\d+/'
_job_event_children = r'job_events/\d+/children/'
_job_events = 'job_events/'
_job_extra_credentials = _job + 'extra_credentials/'
_job_host_summaries = r'jobs/\d+/job_host_summaries/'
_job_host_summary = r'job_host_summaries/\d+/'
_job_job_event = r'jobs/\d+/job_events/\d+/'
@ -105,7 +104,6 @@ class Resources(object):
_job_template_access_list = r'job_templates/\d+/access_list/'
_job_template_callback = r'job_templates/\d+/callback/'
_job_template_copy = r'job_templates/\d+/copy/'
_job_template_extra_credentials = _job_template + 'extra_credentials/'
_job_template_jobs = r'job_templates/\d+/jobs/'
_job_template_labels = r'job_templates/\d+/labels/'
_job_template_launch = r'job_templates/\d+/launch/'

View File

@ -37,7 +37,7 @@ Important Changes
two OpenStack credentials.
* In the same manner as "promptable SSH credentials", when
``ask_credential_on_launch = true``, ``JobTemplate.extra_credentials`` can be
``ask_credential_on_launch = true``, ``JobTemplate.credentials`` can be
specified in the launch payload.
* Custom inventory sources can now utilize a ``Credential``; you
@ -221,9 +221,9 @@ API resources in `/api/v2/` now have two credential related fields:
...
}
...and a new endpoint for fetching all "extra" credentials:
...and a new endpoint for fetching all credentials:
HTTP GET /api/v2/job_templates/N/extra_credentials/
HTTP GET /api/v2/job_templates/N/credentials/
{
'count': N,
@ -239,21 +239,21 @@ Similar to other list attachment/detachment API views, cloud and network
credentials can be created and attached via an `HTTP POST` at this new
endpoint:
HTTP POST /api/v2/job_templates/N/extra_credentials/
HTTP POST /api/v2/job_templates/N/credentials/
{
'id': <cloud_credential_primary_key>,
'associate': True,
}
HTTP POST /api/v2/job_templates/N/extra_credentials/
HTTP POST /api/v2/job_templates/N/credentials/
{
'id': <network_credential_primary_key>,
'disassociate': True,
}
HTTP POST /api/v2/job_templates/N/extra_credentials/
HTTP POST /api/v2/job_templates/N/credentials/
{
'name': 'My Credential',

View File

@ -283,7 +283,3 @@ of what happened.
- Job template has machine & cloud credentials, set to prompt for credential on launch
- Schedule for job template provides no credentials
- Spawned job still uses all job template credentials
**Credentials Deprecated Behavior**
- Manual launch providing `"extra_credentials": []` should launch with no job credentials
- Such jobs cannot have schedules created from them