diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 7f249e3e14..bb74b4c764 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -5,7 +5,6 @@ import copy import json import logging -import operator import re import urllib.parse from collections import OrderedDict @@ -45,7 +44,6 @@ from awx.main.constants import ( ANSI_SGR_PATTERN, ACTIVE_STATES, CENSOR_VALUE, - CHOICES_PRIVILEGE_ESCALATION_METHODS, ) from awx.main.models import * # noqa from awx.main.models.base import NEW_JOB_TYPE_CHOICES @@ -2498,9 +2496,6 @@ class CredentialTypeSerializer(BaseSerializer): field['label'] = _(field['label']) if 'help_text' in field: field['help_text'] = _(field['help_text']) - if field['type'] == 'become_method': - field.pop('type') - field['choices'] = list(map(operator.itemgetter(0), CHOICES_PRIVILEGE_ESCALATION_METHODS)) return value def filter_field_metadata(self, fields, method): diff --git a/awx/main/fields.py b/awx/main/fields.py index 2a21e063aa..832fa02f1a 100644 --- a/awx/main/fields.py +++ b/awx/main/fields.py @@ -4,7 +4,6 @@ # Python import copy import json -import operator import re import urllib.parse @@ -45,7 +44,7 @@ from awx.main.utils.filters import SmartFilter from awx.main.utils.encryption import encrypt_value, decrypt_value, get_encryption_key from awx.main.validators import validate_ssh_private_key from awx.main.models.rbac import batch_role_ancestor_rebuilding, Role -from awx.main.constants import CHOICES_PRIVILEGE_ESCALATION_METHODS, ENV_BLACKLIST +from awx.main.constants import ENV_BLACKLIST from awx.main import utils @@ -511,9 +510,6 @@ class CredentialInputField(JSONSchemaField): properties = {} for field in model_instance.credential_type.inputs.get('fields', []): field = field.copy() - if field['type'] == 'become_method': - field.pop('type') - field['choices'] = list(map(operator.itemgetter(0), CHOICES_PRIVILEGE_ESCALATION_METHODS)) properties[field['id']] = field if field.get('choices', []): field['enum'] = list(field['choices'])[:] @@ -657,7 +653,7 @@ class CredentialTypeInputField(JSONSchemaField): 'items': { 'type': 'object', 'properties': { - 'type': {'enum': ['string', 'boolean', 'become_method']}, + 'type': {'enum': ['string', 'boolean']}, 'format': {'enum': ['ssh_private_key']}, 'choices': { 'type': 'array', @@ -718,17 +714,6 @@ class CredentialTypeInputField(JSONSchemaField): # If no type is specified, default to string field['type'] = 'string' - if field['type'] == 'become_method': - if not model_instance.managed_by_tower: - raise django_exceptions.ValidationError( - _('become_method is a reserved type name'), - code='invalid', - params={'value': value}, - ) - else: - field.pop('type') - field['choices'] = CHOICES_PRIVILEGE_ESCALATION_METHODS - for key in ('choices', 'multiline', 'format', 'secret',): if key in field and field['type'] != 'string': raise django_exceptions.ValidationError( diff --git a/awx/main/migrations/0057_v350_remove_become_method_type.py b/awx/main/migrations/0057_v350_remove_become_method_type.py new file mode 100644 index 0000000000..cd5f76cdec --- /dev/null +++ b/awx/main/migrations/0057_v350_remove_become_method_type.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.11.16 on 2019-01-29 19:56 +from __future__ import unicode_literals + +from django.db import migrations + +# AWX +from awx.main.migrations import _credentialtypes as credentialtypes + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0056_v350_custom_venv_history'), + ] + + operations = [ + migrations.RunPython(credentialtypes.remove_become_methods), + ] diff --git a/awx/main/models/credential/__init__.py b/awx/main/models/credential/__init__.py index b5ad4e1636..ffcc087530 100644 --- a/awx/main/models/credential/__init__.py +++ b/awx/main/models/credential/__init__.py @@ -32,7 +32,6 @@ from awx.main.models.rbac import ( ROLE_SINGLETON_SYSTEM_AUDITOR, ) from awx.main.utils import encrypt_field -from awx.main.constants import CHOICES_PRIVILEGE_ESCALATION_METHODS from . import injectors as builtin_injectors __all__ = ['Credential', 'CredentialType', 'V1Credential', 'build_safe_env'] @@ -163,7 +162,6 @@ class V1Credential(object): max_length=32, blank=True, default='', - choices=CHOICES_PRIVILEGE_ESCALATION_METHODS, help_text=_('Privilege escalation method.') ), 'become_username': models.CharField( @@ -539,7 +537,7 @@ class CredentialType(CommonModelNameNotUnique): if field['id'] == field_id: if 'choices' in field: return field['choices'][0] - return {'string': '', 'boolean': False, 'become_method': ''}[field['type']] + return {'string': '', 'boolean': False}[field['type']] @classmethod def default(cls, f): @@ -736,7 +734,7 @@ def ssh(cls): }, { 'id': 'become_method', 'label': ugettext_noop('Privilege Escalation Method'), - 'type': 'become_method', + 'type': 'string', 'help_text': ugettext_noop('Specify a method for "become" operations. This is ' 'equivalent to specifying the --become-method ' 'Ansible parameter.') diff --git a/awx/main/tests/functional/test_credential.py b/awx/main/tests/functional/test_credential.py index d9b19535e9..4b3ff2d75e 100644 --- a/awx/main/tests/functional/test_credential.py +++ b/awx/main/tests/functional/test_credential.py @@ -1,13 +1,11 @@ # Copyright (c) 2017 Ansible by Red Hat # All Rights Reserved. -import itertools - import pytest from django.core.exceptions import ValidationError from awx.main.utils import decrypt_field -from awx.main.models import Credential, CredentialType, V1Credential +from awx.main.models import Credential, CredentialType from rest_framework import serializers @@ -206,10 +204,11 @@ def test_vault_validation(organization, inputs, valid): @pytest.mark.django_db -@pytest.mark.parametrize('become_method, valid', list(zip( - dict(V1Credential.FIELDS['become_method'].choices).keys(), - itertools.repeat(True) -)) + [('invalid-choice', False)]) +@pytest.mark.parametrize('become_method, valid', [ + ('', True), + ('sudo', True), + ('custom-plugin', True), +]) def test_choices_validity(become_method, valid, organization): inputs = {'become_method': become_method} cred_type = CredentialType.defaults['ssh']() diff --git a/awx/ui/client/src/credentials/credentials.form.js b/awx/ui/client/src/credentials/credentials.form.js index 063e9a3a6b..b42b60738f 100644 --- a/awx/ui/client/src/credentials/credentials.form.js +++ b/awx/ui/client/src/credentials/credentials.form.js @@ -278,10 +278,9 @@ export default ['i18n', function(i18n) { "become_method": { label: i18n._("Privilege Escalation"), // hintText: "If your playbooks use privilege escalation (\"sudo: true\", \"su: true\", etc), you can specify the username to become, and the password to use here.", - type: 'select', + type: 'text', ngShow: "kind.value == 'ssh'", dataTitle: i18n._('Privilege Escalation'), - ngOptions: 'become.label for become in become_options track by become.value', awPopOver: "

" + i18n.sprintf(i18n._("Specify a method for %s operations. " + "This is equivalent to specifying the %s parameter, where %s could be "+ "%s"), "'become'", "--become-method=BECOME_METHOD", "BECOME_METHOD", "sudo | su | pbrun | pfexec | runas") + "
" + i18n.sprintf(i18n._("(defaults to %s)"), "sudo") + "

",