become mixin is no more (#54002)

* become mixin is no more
  since sudo/su keywords are removed in 2.9 .. no need to keep this code around
 * also don't need test for code that is removed
 * made preprocess_data on base noop
   its not used by anything anymore, but kept for backwards compat since other methods of same name are used
pull/55218/head
Brian Coca 6 years ago committed by GitHub
parent 9ddde6b27f
commit e40832df84
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,2 @@
bugfixes:
- remove obsolete become mixin

@ -195,11 +195,6 @@ class FieldAttributeBase(with_metaclass(BaseMeta, object)):
def preprocess_data(self, ds): def preprocess_data(self, ds):
''' infrequently used method to do some pre-processing of legacy terms ''' ''' infrequently used method to do some pre-processing of legacy terms '''
for base_class in self.__class__.mro():
method = getattr(self, "_preprocess_data_%s" % base_class.__name__.lower(), None)
if method:
return method(ds)
return ds return ds
def load_data(self, ds, variable_manager=None, loader=None): def load_data(self, ds, variable_manager=None, loader=None):
@ -615,8 +610,12 @@ class Base(FieldAttributeBase):
# explicitly invoke a debugger on tasks # explicitly invoke a debugger on tasks
_debugger = FieldAttribute(isa='string') _debugger = FieldAttribute(isa='string')
# param names which have been deprecated/removed # Privilege escalation
DEPRECATED_ATTRIBUTES = [ _become = FieldAttribute(isa='bool', default=context.cliargs_deferred_get('become'))
'sudo', 'sudo_user', 'sudo_pass', 'sudo_exe', 'sudo_flags', _become_method = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_method'))
'su', 'su_user', 'su_pass', 'su_exe', 'su_flags', _become_user = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_user'))
] _become_flags = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_flags'))
_become_exe = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_exe'))
# used to hold sudo/su stuff
DEPRECATED_ATTRIBUTES = []

@ -1,93 +0,0 @@
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
#
# This file is part of Ansible
#
# Ansible is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Ansible is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Ansible. If not, see <http://www.gnu.org/licenses/>.
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
from ansible import constants as C
from ansible import context
from ansible.errors import AnsibleParserError
from ansible.playbook.attribute import FieldAttribute
from ansible.utils.display import Display
display = Display()
class Become:
# Privilege escalation
_become = FieldAttribute(isa='bool', default=context.cliargs_deferred_get('become'))
_become_method = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_method'))
_become_user = FieldAttribute(isa='string', default=context.cliargs_deferred_get('become_user'))
_become_flags = FieldAttribute(isa='string')
def __init__(self):
super(Become, self).__init__()
def _detect_privilege_escalation_conflict(self, ds):
# Fail out if user specifies conflicting privilege escalations
has_become = 'become' in ds or 'become_user'in ds
has_sudo = 'sudo' in ds or 'sudo_user' in ds
has_su = 'su' in ds or 'su_user' in ds
if has_become:
msg = 'The become params ("become", "become_user") and'
if has_sudo:
raise AnsibleParserError('%s sudo params ("sudo", "sudo_user") cannot be used together' % msg)
elif has_su:
raise AnsibleParserError('%s su params ("su", "su_user") cannot be used together' % msg)
elif has_sudo and has_su:
raise AnsibleParserError('sudo params ("sudo", "sudo_user") and su params ("su", "su_user") cannot be used together')
def _preprocess_data_become(self, ds):
"""Preprocess the playbook data for become attributes
This is called from the Base object's preprocess_data() method which
in turn is called pretty much anytime any sort of playbook object
(plays, tasks, blocks, etc) is created.
"""
self._detect_privilege_escalation_conflict(ds)
# Privilege escalation, backwards compatibility for sudo/su
if 'sudo' in ds or 'sudo_user' in ds:
ds['become_method'] = 'sudo'
if 'sudo' in ds:
ds['become'] = ds['sudo']
del ds['sudo']
if 'sudo_user' in ds:
ds['become_user'] = ds['sudo_user']
del ds['sudo_user']
display.deprecated("Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default)", '2.9')
elif 'su' in ds or 'su_user' in ds:
ds['become_method'] = 'su'
if 'su' in ds:
ds['become'] = ds['su']
del ds['su']
if 'su_user' in ds:
ds['become_user'] = ds['su_user']
del ds['su_user']
display.deprecated("Instead of su/su_user, use become/become_user and set become_method to 'su' (default is sudo)", '2.9')
return ds

@ -22,7 +22,6 @@ __metaclass__ = type
from ansible.errors import AnsibleParserError from ansible.errors import AnsibleParserError
from ansible.playbook.attribute import FieldAttribute from ansible.playbook.attribute import FieldAttribute
from ansible.playbook.base import Base from ansible.playbook.base import Base
from ansible.playbook.become import Become
from ansible.playbook.conditional import Conditional from ansible.playbook.conditional import Conditional
from ansible.playbook.collectionsearch import CollectionSearch from ansible.playbook.collectionsearch import CollectionSearch
from ansible.playbook.helpers import load_list_of_tasks from ansible.playbook.helpers import load_list_of_tasks
@ -31,7 +30,7 @@ from ansible.playbook.taggable import Taggable
from ansible.utils.sentinel import Sentinel from ansible.utils.sentinel import Sentinel
class Block(Base, Become, Conditional, CollectionSearch, Taggable): class Block(Base, Conditional, CollectionSearch, Taggable):
# main block fields containing the task lists # main block fields containing the task lists
_block = FieldAttribute(isa='list', default=list, inherit=False) _block = FieldAttribute(isa='list', default=list, inherit=False)

@ -25,7 +25,6 @@ from ansible.errors import AnsibleParserError, AnsibleAssertionError
from ansible.module_utils.six import string_types from ansible.module_utils.six import string_types
from ansible.playbook.attribute import FieldAttribute from ansible.playbook.attribute import FieldAttribute
from ansible.playbook.base import Base from ansible.playbook.base import Base
from ansible.playbook.become import Become
from ansible.playbook.block import Block from ansible.playbook.block import Block
from ansible.playbook.collectionsearch import CollectionSearch from ansible.playbook.collectionsearch import CollectionSearch
from ansible.playbook.helpers import load_list_of_blocks, load_list_of_roles from ansible.playbook.helpers import load_list_of_blocks, load_list_of_roles
@ -40,7 +39,7 @@ display = Display()
__all__ = ['Play'] __all__ = ['Play']
class Play(Base, Taggable, Become, CollectionSearch): class Play(Base, Taggable, CollectionSearch):
""" """
A play is a language feature that represents a list of roles and/or A play is a language feature that represents a list of roles and/or

@ -26,7 +26,6 @@ from ansible.module_utils.six import iteritems, binary_type, text_type
from ansible.module_utils.common._collections_compat import Container, Mapping, Set, Sequence from ansible.module_utils.common._collections_compat import Container, Mapping, Set, Sequence
from ansible.playbook.attribute import FieldAttribute from ansible.playbook.attribute import FieldAttribute
from ansible.playbook.base import Base from ansible.playbook.base import Base
from ansible.playbook.become import Become
from ansible.playbook.collectionsearch import CollectionSearch from ansible.playbook.collectionsearch import CollectionSearch
from ansible.playbook.conditional import Conditional from ansible.playbook.conditional import Conditional
from ansible.playbook.helpers import load_list_of_blocks from ansible.playbook.helpers import load_list_of_blocks
@ -92,7 +91,7 @@ def hash_params(params):
return frozenset((params,)) return frozenset((params,))
class Role(Base, Become, Conditional, Taggable, CollectionSearch): class Role(Base, Conditional, Taggable, CollectionSearch):
_delegate_to = FieldAttribute(isa='string') _delegate_to = FieldAttribute(isa='string')
_delegate_facts = FieldAttribute(isa='bool') _delegate_facts = FieldAttribute(isa='bool')

@ -27,7 +27,6 @@ from ansible.module_utils.six import iteritems, string_types
from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleMapping from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleMapping
from ansible.playbook.attribute import Attribute, FieldAttribute from ansible.playbook.attribute import Attribute, FieldAttribute
from ansible.playbook.base import Base from ansible.playbook.base import Base
from ansible.playbook.become import Become
from ansible.playbook.collectionsearch import CollectionSearch from ansible.playbook.collectionsearch import CollectionSearch
from ansible.playbook.conditional import Conditional from ansible.playbook.conditional import Conditional
from ansible.playbook.taggable import Taggable from ansible.playbook.taggable import Taggable
@ -41,7 +40,7 @@ __all__ = ['RoleDefinition']
display = Display() display = Display()
class RoleDefinition(Base, Become, Conditional, Taggable, CollectionSearch): class RoleDefinition(Base, Conditional, Taggable, CollectionSearch):
_role = FieldAttribute(isa='string') _role = FieldAttribute(isa='string')

@ -30,7 +30,6 @@ from ansible.parsing.yaml.objects import AnsibleBaseYAMLObject, AnsibleMapping
from ansible.plugins.loader import lookup_loader from ansible.plugins.loader import lookup_loader
from ansible.playbook.attribute import FieldAttribute from ansible.playbook.attribute import FieldAttribute
from ansible.playbook.base import Base from ansible.playbook.base import Base
from ansible.playbook.become import Become
from ansible.playbook.block import Block from ansible.playbook.block import Block
from ansible.playbook.collectionsearch import CollectionSearch from ansible.playbook.collectionsearch import CollectionSearch
from ansible.playbook.conditional import Conditional from ansible.playbook.conditional import Conditional
@ -45,7 +44,7 @@ __all__ = ['Task']
display = Display() display = Display()
class Task(Base, Conditional, Taggable, Become, CollectionSearch): class Task(Base, Conditional, Taggable, CollectionSearch):
""" """
A task is a language feature that represents a call to a module, with given arguments and other parameters. A task is a language feature that represents a call to a module, with given arguments and other parameters.

@ -367,12 +367,6 @@ class BaseSubClass(base.Base):
_test_attr_method_missing = FieldAttribute(isa='string', default='some attr with a missing getter', _test_attr_method_missing = FieldAttribute(isa='string', default='some attr with a missing getter',
always_post_validate=True) always_post_validate=True)
def _preprocess_data_basesubclass(self, ds):
return ds
def preprocess_data(self, ds):
return super(BaseSubClass, self).preprocess_data(ds)
def _get_attr_test_attr_method(self): def _get_attr_test_attr_method(self):
return 'foo bar' return 'foo bar'

@ -1,100 +0,0 @@
# -*- coding: utf-8 -*-
# (c) 2018 Matt Martz <matt@sivel.net>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
from __future__ import absolute_import, division, print_function
__metaclass__ = type
import re
from ansible.errors import AnsibleParserError
from ansible.playbook.become import Become
from ansible.module_utils._text import to_native
import pytest
class InString(str):
def __eq__(self, other):
return self in other
@pytest.mark.parametrize("ds", [
{},
{'become': True},
{'become_user': 'root'},
{'sudo': True},
{'sudo_user': 'root'},
{'su': True},
{'su_user': 'root'}
])
def test_detect_privilege_escalation_conflict_valid(ds):
become = Become()
become._detect_privilege_escalation_conflict(ds)
@pytest.mark.parametrize("ds,message", [
({'become': True, 'sudo': True}, re.compile('"become".*"sudo"')),
({'become': True, 'su': True}, re.compile('"become".*"su"')),
({'sudo': True, 'su': True}, re.compile('"sudo".*"su"')),
({'become_user': 'root', 'sudo': True}, re.compile('"become".*"sudo"')),
({'sudo_user': 'root', 'su': True}, re.compile('"sudo".*"su"')),
])
def test_detect_privilege_escalation_conflict_invalid(ds, message):
become = Become()
with pytest.raises(AnsibleParserError) as excinfo:
become._detect_privilege_escalation_conflict(ds)
assert message.search(excinfo.value.message) is not None
def test_preprocess_data_become(mocker):
display_mock = mocker.patch('ansible.playbook.become.display')
become = Become()
ds = {}
assert become._preprocess_data_become(ds) == {}
display_mock.reset_mock()
ds = {'sudo': True}
out = become._preprocess_data_become(ds)
assert 'sudo' not in out
assert out.get('become_method') == 'sudo'
display_mock.deprecated.assert_called_once_with(
"Instead of sudo/sudo_user, use become/become_user and make sure become_method is 'sudo' (default)",
'2.9'
)
ds = {'sudo_user': 'root'}
out = become._preprocess_data_become(ds)
assert 'sudo_user' not in out
assert out.get('become_user') == 'root'
ds = {'sudo': True, 'sudo_user': 'root'}
out = become._preprocess_data_become(ds)
assert 'sudo' not in out
assert 'sudo_user' not in out
assert out.get('become_method') == 'sudo'
assert out.get('become_user') == 'root'
display_mock.reset_mock()
ds = {'su': True}
out = become._preprocess_data_become(ds)
assert 'su' not in out
assert out.get('become_method') == 'su'
display_mock.deprecated.assert_called_once_with(
"Instead of su/su_user, use become/become_user and set become_method to 'su' (default is sudo)",
'2.9'
)
display_mock.reset_mock()
ds = {'su_user': 'root'}
out = become._preprocess_data_become(ds)
assert 'su_user' not in out
assert out.get('become_user') == 'root'
ds = {'su': True, 'su_user': 'root'}
out = become._preprocess_data_become(ds)
assert 'su' not in out
assert 'su_user' not in out
assert out.get('become_method') == 'su'
assert out.get('become_user') == 'root'

@ -140,6 +140,7 @@ def test_play_context_make_become_cmd(mocker, parser, reset_cli_args):
default_exe, success, default_cmd), cmd) is not None) default_exe, success, default_cmd), cmd) is not None)
play_context.become_pass = None play_context.become_pass = None
play_context.become_method = 'su'
play_context.set_become_plugin(become_loader.get('su')) play_context.set_become_plugin(become_loader.get('su'))
play_context.become_flags = su_flags play_context.become_flags = su_flags
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
@ -147,33 +148,39 @@ def test_play_context_make_become_cmd(mocker, parser, reset_cli_args):
success, default_cmd), cmd) is not None) success, default_cmd), cmd) is not None)
play_context.set_become_plugin(become_loader.get('pbrun')) play_context.set_become_plugin(become_loader.get('pbrun'))
play_context.become_method = 'pbrun'
play_context.become_flags = pbrun_flags play_context.become_flags = pbrun_flags
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
assert re.match("""%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, play_context.become_user, assert re.match("""%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, play_context.become_user,
success, default_cmd), cmd) is not None success, default_cmd), cmd) is not None
play_context.set_become_plugin(become_loader.get('pfexec')) play_context.set_become_plugin(become_loader.get('pfexec'))
play_context.become_method = 'pfexec'
play_context.become_flags = pfexec_flags play_context.become_flags = pfexec_flags
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
assert re.match('''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None assert re.match('''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None
play_context.set_become_plugin(become_loader.get('doas')) play_context.set_become_plugin(become_loader.get('doas'))
play_context.become_method = 'doas'
play_context.become_flags = doas_flags play_context.become_flags = doas_flags
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
assert (re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (doas_exe, doas_flags, play_context.become_user, default_exe, success, assert (re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (doas_exe, doas_flags, play_context.become_user, default_exe, success,
default_cmd), cmd) is not None) default_cmd), cmd) is not None)
play_context.set_become_plugin(become_loader.get('ksu')) play_context.set_become_plugin(become_loader.get('ksu'))
play_context.become_method = 'ksu'
play_context.become_flags = ksu_flags play_context.become_flags = ksu_flags
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
assert (re.match("""%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags, assert (re.match("""%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags,
default_exe, success, default_cmd), cmd) is not None) default_exe, success, default_cmd), cmd) is not None)
play_context.set_become_plugin(become_loader.get('bad')) play_context.set_become_plugin(become_loader.get('bad'))
play_context.become_method = 'bad'
with pytest.raises(AnsibleError): with pytest.raises(AnsibleError):
play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
play_context.set_become_plugin(become_loader.get('dzdo')) play_context.set_become_plugin(become_loader.get('dzdo'))
play_context.become_method = 'dzdo'
play_context.become_flags = dzdo_flags play_context.become_flags = dzdo_flags
cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash")
assert re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, play_context.become_user, default_exe, assert re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, play_context.become_user, default_exe,

Loading…
Cancel
Save