Merge pull request #2079 from AlanCoding/creds_no_op

Allow no-op case when modifying deprecated credentials
This commit is contained in:
Alan Rominger
2018-06-12 09:08:35 -04:00
committed by GitHub
4 changed files with 74 additions and 20 deletions

View File

@@ -2092,14 +2092,14 @@ class InventorySourceSerializer(UnifiedJobTemplateSerializer, InventorySourceOpt
def _update_deprecated_fields(self, fields, obj):
if 'credential' in fields:
new_cred = fields['credential']
existing_creds = obj.credentials.exclude(credential_type__kind='vault')
for cred in existing_creds:
# Remove all other cloud credentials
if cred != new_cred:
existing = obj.credentials.all()
if new_cred not in existing:
for cred in existing:
# Remove all other cloud credentials
obj.credentials.remove(cred)
if new_cred:
# Add new credential
obj.credentials.add(new_cred)
if new_cred:
# Add new credential
obj.credentials.add(new_cred)
def validate(self, attrs):
deprecated_fields = {}
@@ -2889,11 +2889,12 @@ class JobOptionsSerializer(LabelsListMixin, BaseSerializer):
('network_credential', obj.network_credentials),
):
if key in fields:
for cred in existing:
obj.credentials.remove(cred)
if fields[key]:
obj.credentials.add(fields[key])
obj.save()
new_cred = fields[key]
if new_cred not in existing:
for cred in existing:
obj.credentials.remove(cred)
if new_cred:
obj.credentials.add(new_cred)
def validate(self, attrs):
v1_credentials = {}
@@ -3772,10 +3773,13 @@ class WorkflowJobTemplateNodeSerializer(LaunchConfigurationBaseSerializer):
deprecated_fields['credential'] = validated_data.pop('credential')
obj = super(WorkflowJobTemplateNodeSerializer, self).update(obj, validated_data)
if 'credential' in deprecated_fields:
for cred in obj.credentials.filter(credential_type__kind='ssh'):
obj.credentials.remove(cred)
if deprecated_fields['credential']:
obj.credentials.add(deprecated_fields['credential'])
existing = obj.credentials.filter(credential_type__kind='ssh')
new_cred = deprecated_fields['credential']
if new_cred not in existing:
for cred in existing:
obj.credentials.remove(cred)
if new_cred:
obj.credentials.add(new_cred)
return obj

View File

@@ -394,3 +394,43 @@ def test_inventory_source_invalid_deprecated_credential(patch, admin, ec2_source
url = reverse('api:inventory_source_detail', kwargs={'pk': ec2_source.pk})
resp = patch(url, {'credential': 999999}, admin, expect=400)
assert 'Credential 999999 does not exist' in resp.content
@pytest.mark.django_db
def test_deprecated_credential_activity_stream(patch, admin_user, machine_credential, job_template):
job_template.credentials.add(machine_credential)
starting_entries = job_template.activitystream_set.count()
# no-op patch
patch(
job_template.get_absolute_url(),
admin_user,
data={'credential': machine_credential.pk},
expect=200
)
# no-op should not produce activity stream entries
assert starting_entries == job_template.activitystream_set.count()
@pytest.mark.django_db
def test_multi_vault_preserved_on_put(get, put, admin_user, job_template, vault_credential):
'''
A PUT request will necessarily specify deprecated fields, but if the deprecated
field is a singleton while the `credentials` relation has many, that makes
it very easy to drop those credentials not specified in the PUT data
'''
vault2 = Credential.objects.create(
name='second-vault',
credential_type=vault_credential.credential_type,
inputs={'vault_password': 'foo', 'vault_id': 'foo'}
)
job_template.credentials.add(vault_credential, vault2)
assert job_template.credentials.count() == 2 # sanity check
r = get(job_template.get_absolute_url(), admin_user, expect=200)
# should be a no-op PUT request
put(
job_template.get_absolute_url(),
admin_user,
data=r.data,
expect=200
)
assert job_template.credentials.count() == 2

View File

@@ -563,7 +563,9 @@ def _request(verb):
response.data[key] = str(value)
except Exception:
response.data = data_copy
assert response.status_code == expect
assert response.status_code == expect, 'Response data: {}'.format(
getattr(response, 'data', None)
)
if hasattr(response, 'render'):
response.render()
__SWAGGER_REQUESTS__.setdefault(request.path, {})[