diff --git a/awx/main/constants.py b/awx/main/constants.py index edd00569ea..7305a94a34 100644 --- a/awx/main/constants.py +++ b/awx/main/constants.py @@ -14,6 +14,7 @@ __all__ = [ CLOUD_PROVIDERS = ('azure_rm', 'ec2', 'gce', 'vmware', 'openstack', 'rhv', 'satellite6', 'cloudforms', 'tower') SCHEDULEABLE_PROVIDERS = CLOUD_PROVIDERS + ('custom', 'scm',) PRIVILEGE_ESCALATION_METHODS = [ + ('', _('None')), ('enable', _('Enable')), ('doas', _('Doas')), ('sudo', _('Sudo')), ('su', _('Su')), ('pbrun', _('Pbrun')), ('pfexec', _('Pfexec')), ('dzdo', _('DZDO')), ('pmrun', _('Pmrun')), ('runas', _('Runas'))] ANSI_SGR_PATTERN = re.compile(r'\x1b\[[0-9;]*m') diff --git a/awx/main/fields.py b/awx/main/fields.py index 1a41d711a3..ec9ada6cf8 100644 --- a/awx/main/fields.py +++ b/awx/main/fields.py @@ -45,6 +45,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 PRIVILEGE_ESCALATION_METHODS from awx.main import utils @@ -649,7 +650,7 @@ class CredentialTypeInputField(JSONSchemaField): 'items': { 'type': 'object', 'properties': { - 'type': {'enum': ['string', 'boolean']}, + 'type': {'enum': ['string', 'boolean', 'become_method']}, 'format': {'enum': ['ssh_private_key']}, 'choices': { 'type': 'array', @@ -710,6 +711,17 @@ 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( + _('{0} is a reserved type name'.format(field['type'])), + code='invalid', + params={'value': value}, + ) + else: + field['type'] = 'string' + field['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/0035_v330_credtype_remove_become_methods.py b/awx/main/migrations/0035_v330_credtype_remove_become_methods.py new file mode 100644 index 0000000000..130a949ec7 --- /dev/null +++ b/awx/main/migrations/0035_v330_credtype_remove_become_methods.py @@ -0,0 +1,18 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +# AWX +from awx.main.migrations import _credentialtypes as credentialtypes + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('main', '0034_v330_more_oauth2_help_text'), + ] + + operations = [ + migrations.RunPython(credentialtypes.remove_become_methods), + ] diff --git a/awx/main/migrations/_credentialtypes.py b/awx/main/migrations/_credentialtypes.py index bf4128c92e..247ca42a36 100644 --- a/awx/main/migrations/_credentialtypes.py +++ b/awx/main/migrations/_credentialtypes.py @@ -197,3 +197,9 @@ def add_azure_cloud_environment_field(apps, schema_editor): name='Microsoft Azure Resource Manager') azure_rm_credtype.inputs = CredentialType.defaults.get('azure_rm')().inputs azure_rm_credtype.save() + + +def remove_become_methods(apps, schema_editor): + become_credtype = CredentialType.objects.get(kind='ssh') + become_credtype.inputs = CredentialType.defaults.get('ssh')().inputs + become_credtype.save() diff --git a/awx/main/models/credential/__init__.py b/awx/main/models/credential/__init__.py index b390043765..b372144512 100644 --- a/awx/main/models/credential/__init__.py +++ b/awx/main/models/credential/__init__.py @@ -165,7 +165,7 @@ class V1Credential(object): max_length=32, blank=True, default='', - choices=[('', _('None'))] + PRIVILEGE_ESCALATION_METHODS, + choices=PRIVILEGE_ESCALATION_METHODS, help_text=_('Privilege escalation method.') ), 'become_username': models.CharField( @@ -516,7 +516,7 @@ class CredentialType(CommonModelNameNotUnique): if field['id'] == field_id: if 'choices' in field: return field['choices'][0] - return {'string': '', 'boolean': False}[field['type']] + return {'string': '', 'boolean': False, 'become_method': ''}[field['type']] @classmethod def default(cls, f):