mirror of
https://github.com/ansible/awx.git
synced 2026-03-04 18:21:03 -03:30
Merge pull request #1459 from wwitzel3/become-enable
Add new credential become methods, inject instead of set in database
This commit is contained in:
@@ -5,6 +5,7 @@
|
|||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
import operator
|
||||||
import re
|
import re
|
||||||
import six
|
import six
|
||||||
import urllib
|
import urllib
|
||||||
@@ -38,7 +39,13 @@ from rest_framework.utils.serializer_helpers import ReturnList
|
|||||||
from polymorphic.models import PolymorphicModel
|
from polymorphic.models import PolymorphicModel
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.constants import SCHEDULEABLE_PROVIDERS, ANSI_SGR_PATTERN, ACTIVE_STATES, TOKEN_CENSOR
|
from awx.main.constants import (
|
||||||
|
SCHEDULEABLE_PROVIDERS,
|
||||||
|
ANSI_SGR_PATTERN,
|
||||||
|
ACTIVE_STATES,
|
||||||
|
TOKEN_CENSOR,
|
||||||
|
CHOICES_PRIVILEGE_ESCALATION_METHODS,
|
||||||
|
)
|
||||||
from awx.main.models import * # noqa
|
from awx.main.models import * # noqa
|
||||||
from awx.main.models.base import NEW_JOB_TYPE_CHOICES
|
from awx.main.models.base import NEW_JOB_TYPE_CHOICES
|
||||||
from awx.main.access import get_user_capabilities
|
from awx.main.access import get_user_capabilities
|
||||||
@@ -2494,6 +2501,9 @@ class CredentialTypeSerializer(BaseSerializer):
|
|||||||
field['label'] = _(field['label'])
|
field['label'] = _(field['label'])
|
||||||
if 'help_text' in field:
|
if 'help_text' in field:
|
||||||
field['help_text'] = _(field['help_text'])
|
field['help_text'] = _(field['help_text'])
|
||||||
|
if field['type'] == 'become_method':
|
||||||
|
field.pop('type')
|
||||||
|
field['choices'] = map(operator.itemgetter(0), CHOICES_PRIVILEGE_ESCALATION_METHODS)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def filter_field_metadata(self, fields, method):
|
def filter_field_metadata(self, fields, method):
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ CLOUD_PROVIDERS = ('azure_rm', 'ec2', 'gce', 'vmware', 'openstack', 'rhv', 'sate
|
|||||||
SCHEDULEABLE_PROVIDERS = CLOUD_PROVIDERS + ('custom', 'scm',)
|
SCHEDULEABLE_PROVIDERS = CLOUD_PROVIDERS + ('custom', 'scm',)
|
||||||
PRIVILEGE_ESCALATION_METHODS = [
|
PRIVILEGE_ESCALATION_METHODS = [
|
||||||
('sudo', _('Sudo')), ('su', _('Su')), ('pbrun', _('Pbrun')), ('pfexec', _('Pfexec')),
|
('sudo', _('Sudo')), ('su', _('Su')), ('pbrun', _('Pbrun')), ('pfexec', _('Pfexec')),
|
||||||
('dzdo', _('DZDO')), ('pmrun', _('Pmrun')), ('runas', _('Runas'))]
|
('dzdo', _('DZDO')), ('pmrun', _('Pmrun')), ('runas', _('Runas')),
|
||||||
|
('enable', _('Enable')), ('doas', _('Doas')),
|
||||||
|
]
|
||||||
|
CHOICES_PRIVILEGE_ESCALATION_METHODS = [('', _('None'))] + PRIVILEGE_ESCALATION_METHODS
|
||||||
ANSI_SGR_PATTERN = re.compile(r'\x1b\[[0-9;]*m')
|
ANSI_SGR_PATTERN = re.compile(r'\x1b\[[0-9;]*m')
|
||||||
CAN_CANCEL = ('new', 'pending', 'waiting', 'running')
|
CAN_CANCEL = ('new', 'pending', 'waiting', 'running')
|
||||||
ACTIVE_STATES = CAN_CANCEL
|
ACTIVE_STATES = CAN_CANCEL
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
# Python
|
# Python
|
||||||
import copy
|
import copy
|
||||||
import json
|
import json
|
||||||
|
import operator
|
||||||
import re
|
import re
|
||||||
import six
|
import six
|
||||||
import urllib
|
import urllib
|
||||||
@@ -45,6 +46,7 @@ from awx.main.utils.filters import SmartFilter
|
|||||||
from awx.main.utils.encryption import encrypt_value, decrypt_value, get_encryption_key
|
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.validators import validate_ssh_private_key
|
||||||
from awx.main.models.rbac import batch_role_ancestor_rebuilding, Role
|
from awx.main.models.rbac import batch_role_ancestor_rebuilding, Role
|
||||||
|
from awx.main.constants import CHOICES_PRIVILEGE_ESCALATION_METHODS
|
||||||
from awx.main import utils
|
from awx.main import utils
|
||||||
|
|
||||||
|
|
||||||
@@ -506,6 +508,9 @@ class CredentialInputField(JSONSchemaField):
|
|||||||
properties = {}
|
properties = {}
|
||||||
for field in model_instance.credential_type.inputs.get('fields', []):
|
for field in model_instance.credential_type.inputs.get('fields', []):
|
||||||
field = field.copy()
|
field = field.copy()
|
||||||
|
if field['type'] == 'become_method':
|
||||||
|
field.pop('type')
|
||||||
|
field['choices'] = map(operator.itemgetter(0), CHOICES_PRIVILEGE_ESCALATION_METHODS)
|
||||||
properties[field['id']] = field
|
properties[field['id']] = field
|
||||||
if field.get('choices', []):
|
if field.get('choices', []):
|
||||||
field['enum'] = field['choices'][:]
|
field['enum'] = field['choices'][:]
|
||||||
@@ -649,7 +654,7 @@ class CredentialTypeInputField(JSONSchemaField):
|
|||||||
'items': {
|
'items': {
|
||||||
'type': 'object',
|
'type': 'object',
|
||||||
'properties': {
|
'properties': {
|
||||||
'type': {'enum': ['string', 'boolean']},
|
'type': {'enum': ['string', 'boolean', 'become_method']},
|
||||||
'format': {'enum': ['ssh_private_key']},
|
'format': {'enum': ['ssh_private_key']},
|
||||||
'choices': {
|
'choices': {
|
||||||
'type': 'array',
|
'type': 'array',
|
||||||
@@ -710,6 +715,17 @@ class CredentialTypeInputField(JSONSchemaField):
|
|||||||
# If no type is specified, default to string
|
# If no type is specified, default to string
|
||||||
field['type'] = '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',):
|
for key in ('choices', 'multiline', 'format', 'secret',):
|
||||||
if key in field and field['type'] != 'string':
|
if key in field and field['type'] != 'string':
|
||||||
raise django_exceptions.ValidationError(
|
raise django_exceptions.ValidationError(
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
# -*- 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', '0035_v330_more_oauth2_help_text'),
|
||||||
|
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(credentialtypes.remove_become_methods),
|
||||||
|
]
|
||||||
@@ -197,3 +197,9 @@ def add_azure_cloud_environment_field(apps, schema_editor):
|
|||||||
name='Microsoft Azure Resource Manager')
|
name='Microsoft Azure Resource Manager')
|
||||||
azure_rm_credtype.inputs = CredentialType.defaults.get('azure_rm')().inputs
|
azure_rm_credtype.inputs = CredentialType.defaults.get('azure_rm')().inputs
|
||||||
azure_rm_credtype.save()
|
azure_rm_credtype.save()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_become_methods(apps, schema_editor):
|
||||||
|
become_credtype = CredentialType.objects.filter(kind='ssh', managed_by_tower=True).first()
|
||||||
|
become_credtype.inputs = CredentialType.defaults.get('ssh')().inputs
|
||||||
|
become_credtype.save()
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from collections import OrderedDict
|
|||||||
import functools
|
import functools
|
||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
import operator
|
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import stat
|
import stat
|
||||||
@@ -22,7 +21,6 @@ from django.utils.encoding import force_text
|
|||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.api.versioning import reverse
|
from awx.api.versioning import reverse
|
||||||
from awx.main.constants import PRIVILEGE_ESCALATION_METHODS
|
|
||||||
from awx.main.fields import (ImplicitRoleField, CredentialInputField,
|
from awx.main.fields import (ImplicitRoleField, CredentialInputField,
|
||||||
CredentialTypeInputField,
|
CredentialTypeInputField,
|
||||||
CredentialTypeInjectorField)
|
CredentialTypeInjectorField)
|
||||||
@@ -35,6 +33,7 @@ from awx.main.models.rbac import (
|
|||||||
ROLE_SINGLETON_SYSTEM_AUDITOR,
|
ROLE_SINGLETON_SYSTEM_AUDITOR,
|
||||||
)
|
)
|
||||||
from awx.main.utils import encrypt_field
|
from awx.main.utils import encrypt_field
|
||||||
|
from awx.main.constants import CHOICES_PRIVILEGE_ESCALATION_METHODS
|
||||||
from . import injectors as builtin_injectors
|
from . import injectors as builtin_injectors
|
||||||
|
|
||||||
__all__ = ['Credential', 'CredentialType', 'V1Credential', 'build_safe_env']
|
__all__ = ['Credential', 'CredentialType', 'V1Credential', 'build_safe_env']
|
||||||
@@ -165,7 +164,7 @@ class V1Credential(object):
|
|||||||
max_length=32,
|
max_length=32,
|
||||||
blank=True,
|
blank=True,
|
||||||
default='',
|
default='',
|
||||||
choices=[('', _('None'))] + PRIVILEGE_ESCALATION_METHODS,
|
choices=CHOICES_PRIVILEGE_ESCALATION_METHODS,
|
||||||
help_text=_('Privilege escalation method.')
|
help_text=_('Privilege escalation method.')
|
||||||
),
|
),
|
||||||
'become_username': models.CharField(
|
'become_username': models.CharField(
|
||||||
@@ -516,7 +515,7 @@ class CredentialType(CommonModelNameNotUnique):
|
|||||||
if field['id'] == field_id:
|
if field['id'] == field_id:
|
||||||
if 'choices' in field:
|
if 'choices' in field:
|
||||||
return field['choices'][0]
|
return field['choices'][0]
|
||||||
return {'string': '', 'boolean': False}[field['type']]
|
return {'string': '', 'boolean': False, 'become_method': ''}[field['type']]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def default(cls, f):
|
def default(cls, f):
|
||||||
@@ -708,8 +707,7 @@ def ssh(cls):
|
|||||||
}, {
|
}, {
|
||||||
'id': 'become_method',
|
'id': 'become_method',
|
||||||
'label': 'Privilege Escalation Method',
|
'label': 'Privilege Escalation Method',
|
||||||
'choices': map(operator.itemgetter(0),
|
'type': 'become_method',
|
||||||
V1Credential.FIELDS['become_method'].choices),
|
|
||||||
'help_text': ('Specify a method for "become" operations. This is '
|
'help_text': ('Specify a method for "become" operations. This is '
|
||||||
'equivalent to specifying the --become-method '
|
'equivalent to specifying the --become-method '
|
||||||
'Ansible parameter.')
|
'Ansible parameter.')
|
||||||
|
|||||||
Reference in New Issue
Block a user