From 09055f9c2fd0599f2559be37d5f57462f8075cc1 Mon Sep 17 00:00:00 2001 From: Ryan Petrello Date: Mon, 10 Jul 2017 17:52:16 -0400 Subject: [PATCH] fix a few issues in credential type kind validation - fix a typo from `network` to `net` - properly update OPTIONS for CredentialTypes to reflect allowed `kind` values for POST/PUT/ see: #6959 --- awx/api/metadata.py | 12 +++++++++- awx/api/serializers.py | 4 ++-- .../functional/api/test_credential_type.py | 22 +++++++++++++++++++ 3 files changed, 35 insertions(+), 3 deletions(-) diff --git a/awx/api/metadata.py b/awx/api/metadata.py index 0d05eedb98..02e1312c0f 100644 --- a/awx/api/metadata.py +++ b/awx/api/metadata.py @@ -17,7 +17,7 @@ from rest_framework.relations import RelatedField, ManyRelatedField from rest_framework.request import clone_request # Ansible Tower -from awx.main.models import InventorySource, NotificationTemplate +from awx.main.models import InventorySource, NotificationTemplate, CredentialType class Metadata(metadata.SimpleMetadata): @@ -149,6 +149,16 @@ class Metadata(metadata.SimpleMetadata): if field == 'type' and hasattr(serializer, 'get_type_choices'): meta['choices'] = serializer.get_type_choices() + # API-created/modified CredentialType kinds are limited to + # `cloud` and `network` + if method != 'GET' and \ + hasattr(serializer, 'Meta') and \ + getattr(serializer.Meta, 'model', None) is CredentialType: + actions[method]['kind']['choices'] = filter( + lambda choice: choice[0] in ('cloud', 'net'), + actions[method]['kind']['choices'] + ) + # For GET method, remove meta attributes that aren't relevant # when reading a field and remove write-only fields. if method == 'GET': diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 06755f06d2..398e686634 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -1904,9 +1904,9 @@ class CredentialTypeSerializer(BaseSerializer): ) ret = super(CredentialTypeSerializer, self).validate(attrs) - if 'kind' in attrs and attrs['kind'] not in ('cloud', 'network'): + if 'kind' in attrs and attrs['kind'] not in ('cloud', 'net'): raise serializers.ValidationError({ - "kind": _("Must be 'cloud' or 'network', not %s") % attrs['kind'] + "kind": _("Must be 'cloud' or 'net', not %s") % attrs['kind'] }) fields = attrs.get('inputs', {}).get('fields', []) diff --git a/awx/main/tests/functional/api/test_credential_type.py b/awx/main/tests/functional/api/test_credential_type.py index 452362c505..539d8f827b 100644 --- a/awx/main/tests/functional/api/test_credential_type.py +++ b/awx/main/tests/functional/api/test_credential_type.py @@ -143,6 +143,28 @@ def test_create_managed_by_tower_readonly(get, post, admin): assert response.data['results'][0]['managed_by_tower'] is False +@pytest.mark.django_db +@pytest.mark.parametrize('kind', ['cloud', 'net']) +def test_create_valid_kind(kind, get, post, admin): + response = post(reverse('api:credential_type_list'), { + 'kind': kind, + 'name': 'My Custom Type', + 'inputs': { + 'fields': [{ + 'id': 'api_token', + 'label': 'API Token', + 'type': 'string', + 'secret': True + }] + }, + 'injectors': {} + }, admin) + assert response.status_code == 201 + + response = get(reverse('api:credential_type_list'), admin) + assert response.data['count'] == 1 + + @pytest.mark.django_db @pytest.mark.parametrize('kind', ['ssh', 'vault', 'scm', 'insights']) def test_create_invalid_kind(kind, get, post, admin):