1
0
Fork 0
mirror of https://github.com/ansible-collections/community.general.git synced 2024-09-14 20:13:21 +02:00

Fix become plugins (#50)

* Fix become plugins.

* Fix become unit tests to avoid play_context.make_become_cmd.

* Remove hack.

* Remove explicit defaults. Adjust tests to be more like Ansible itself.

* Forgot two lines.

* Rewrite tests (again).

* Rename play_context -> task, add possibility to pass var_options.

* Add var_options variants.

* Properly test overwriting.
This commit is contained in:
Felix Fontein 2020-03-30 19:09:45 +02:00 committed by GitHub
parent 7d8ca8bdbb
commit 0026c9f5b2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 238 additions and 84 deletions

View file

@ -111,13 +111,13 @@ class BecomeModule(BecomeBase):
self.prompt = True self.prompt = True
become_exe = self.get_option('become_exe') or self.name become_exe = self.get_option('become_exe')
flags = self.get_option('become_flags') or '' flags = self.get_option('become_flags')
if not self.get_option('become_pass') and '-n' not in flags: if not self.get_option('become_pass') and '-n' not in flags:
flags += ' -n' flags += ' -n'
user = self.get_option('become_user') or '' user = self.get_option('become_user')
if user: if user:
user = '-u %s' % (user) user = '-u %s' % (user)

View file

@ -82,14 +82,14 @@ class BecomeModule(BecomeBase):
if not cmd: if not cmd:
return cmd return cmd
becomecmd = self.get_option('become_exe') or self.name becomecmd = self.get_option('become_exe')
flags = self.get_option('become_flags') or '' flags = self.get_option('become_flags')
if self.get_option('become_pass'): if self.get_option('become_pass'):
self.prompt = '[dzdo via ansible, key=%s] password:' % self._id self.prompt = '[dzdo via ansible, key=%s] password:' % self._id
flags = '%s -p "%s"' % (flags.replace('-n', ''), self.prompt) flags = '%s -p "%s"' % (flags.replace('-n', ''), self.prompt)
user = self.get_option('become_user') or '' user = self.get_option('become_user')
if user: if user:
user = '-u %s' % (user) user = '-u %s' % (user)

View file

@ -13,6 +13,7 @@ DOCUMENTATION = '''
options: options:
become_user: become_user:
description: User you 'become' to execute the task description: User you 'become' to execute the task
default: ''
ini: ini:
- section: privilege_escalation - section: privilege_escalation
key: become_user key: become_user
@ -113,7 +114,8 @@ class BecomeModule(BecomeBase):
if not cmd: if not cmd:
return cmd return cmd
exe = self.get_option('become_exe') or self.name exe = self.get_option('become_exe')
flags = self.get_option('become_flags') or ''
user = self.get_option('become_user') or '' flags = self.get_option('become_flags')
user = self.get_option('become_user')
return '%s %s %s -e %s ' % (exe, user, flags, self._build_success_command(cmd, shell)) return '%s %s %s -e %s ' % (exe, user, flags, self._build_success_command(cmd, shell))

View file

@ -13,6 +13,7 @@ DOCUMENTATION = '''
options: options:
become_user: become_user:
description: User you 'become' to execute the task description: User you 'become' to execute the task
default: ''
ini: ini:
- section: privilege_escalation - section: privilege_escalation
key: become_user key: become_user
@ -80,7 +81,8 @@ class BecomeModule(BecomeBase):
if not cmd: if not cmd:
return cmd return cmd
become = self.get_option('become_exe') or self.name become = self.get_option('become_exe')
flags = self.get_option('become_flags') or ''
user = self.get_option('become_user') or '' flags = self.get_option('become_flags')
user = self.get_option('become_user')
return '%s -q shell %s %s@ %s' % (become, flags, user, cmd) return '%s -q shell %s %s@ %s' % (become, flags, user, cmd)

View file

@ -41,6 +41,7 @@ DOCUMENTATION = '''
- name: ANSIBLE_PBRUN_EXE - name: ANSIBLE_PBRUN_EXE
become_flags: become_flags:
description: Options to pass to pbrun description: Options to pass to pbrun
default: ''
ini: ini:
- section: privilege_escalation - section: privilege_escalation
key: become_flags key: become_flags
@ -93,9 +94,10 @@ class BecomeModule(BecomeBase):
if not cmd: if not cmd:
return cmd return cmd
become_exe = self.get_option('become_exe') or self.name become_exe = self.get_option('become_exe')
flags = self.get_option('become_flags') or ''
user = self.get_option('become_user') or '' flags = self.get_option('become_flags')
user = self.get_option('become_user')
if user: if user:
user = '-u %s' % (user) user = '-u %s' % (user)
noexe = not self.get_option('wrap_exe') noexe = not self.get_option('wrap_exe')

View file

@ -97,7 +97,8 @@ class BecomeModule(BecomeBase):
if not cmd: if not cmd:
return cmd return cmd
exe = self.get_option('become_exe') or self.name exe = self.get_option('become_exe')
flags = self.get_option('become_flags') flags = self.get_option('become_flags')
noexe = not self.get_option('wrap_exe') noexe = not self.get_option('wrap_exe')
return '%s %s "%s"' % (exe, flags, self._build_success_command(cmd, shell, noexe=noexe)) return '%s %s "%s"' % (exe, flags, self._build_success_command(cmd, shell, noexe=noexe))

View file

@ -27,6 +27,7 @@ DOCUMENTATION = '''
- name: ANSIBLE_PMRUN_EXE - name: ANSIBLE_PMRUN_EXE
become_flags: become_flags:
description: Options to pass to pmrun description: Options to pass to pmrun
default: ''
ini: ini:
- section: privilege_escalation - section: privilege_escalation
key: become_flags key: become_flags
@ -70,6 +71,7 @@ class BecomeModule(BecomeBase):
if not cmd: if not cmd:
return cmd return cmd
become = self.get_option('become_exe') or self.name become = self.get_option('become_exe')
flags = self.get_option('become_flags') or ''
flags = self.get_option('become_flags')
return '%s %s %s' % (become, flags, shlex_quote(self._build_success_command(cmd, shell))) return '%s %s %s' % (become, flags, shlex_quote(self._build_success_command(cmd, shell)))

View file

@ -13,6 +13,7 @@ DOCUMENTATION = '''
options: options:
become_user: become_user:
description: User you 'become' to execute the task description: User you 'become' to execute the task
default: ''
ini: ini:
- section: privilege_escalation - section: privilege_escalation
key: become_user key: become_user
@ -83,7 +84,8 @@ class BecomeModule(BecomeBase):
if not cmd: if not cmd:
return cmd return cmd
become = self.get_option('become_exe') or self.name become = self.get_option('become_exe')
flags = self.get_option('become_flags') or ''
user = self.get_option('become_user') or '' flags = self.get_option('become_flags')
user = self.get_option('become_user')
return '%s %s %s -c %s' % (become, flags, user, self._build_success_command(cmd, shell)) return '%s %s %s -c %s' % (become, flags, user, self._build_success_command(cmd, shell))

View file

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# (c) 2012-2014, Michael DeHaan <michael.dehaan@gmail.com>
#
# 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
from ansible.errors import AnsibleError
from ansible.plugins.loader import become_loader, get_shell_plugin
def call_become_plugin(task, var_options, cmd, executable=None):
"""Helper function to call become plugin simiarly on how Ansible itself handles this."""
plugin = become_loader.get(task['become_method'])
plugin.set_options(task_keys=task, var_options=var_options)
shell = get_shell_plugin(executable=executable)
return plugin.build_become_command(cmd, shell)

View file

@ -10,30 +10,54 @@ __metaclass__ = type
import re import re
from ansible import context from ansible import context
from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import become_loader from .helper import call_become_plugin
def test_doas(mocker, parser, reset_cli_args): def test_doas(mocker, parser, reset_cli_args):
options = parser.parse_args([]) options = parser.parse_args([])
context._init_global_context(options) context._init_global_context(options)
play_context = PlayContext()
default_cmd = "/bin/foo" default_cmd = "/bin/foo"
default_exe = "/bin/bash" default_exe = "/bin/bash"
doas_exe = 'doas' doas_exe = 'doas'
doas_flags = '-n' doas_flags = '-n'
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) success = 'BECOME-SUCCESS-.+?'
assert cmd == default_cmd
task = {
'become_user': 'foo',
'become_method': 'community.general.doas',
'become_flags': doas_flags,
}
var_options = {}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert (re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (doas_exe, doas_flags, task['become_user'], default_exe, success,
default_cmd), cmd) is not None)
def test_doas_varoptions(mocker, parser, reset_cli_args):
options = parser.parse_args([])
context._init_global_context(options)
default_cmd = "/bin/foo"
default_exe = "/bin/bash"
doas_exe = 'doas'
doas_flags = '-n'
success = 'BECOME-SUCCESS-.+?' success = 'BECOME-SUCCESS-.+?'
play_context.become = True task = {
play_context.become_user = 'foo' 'become_user': 'foo',
play_context.set_become_plugin(become_loader.get('doas')) 'become_method': 'community.general.doas',
play_context.become_method = 'doas' 'become_flags': 'xxx',
play_context.become_flags = doas_flags }
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) var_options = {
assert (re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (doas_exe, doas_flags, play_context.become_user, default_exe, success, 'ansible_become_user': 'bar',
'ansible_become_flags': doas_flags,
}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert (re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (doas_exe, doas_flags, var_options['ansible_become_user'], default_exe, success,
default_cmd), cmd) is not None) default_cmd), cmd) is not None)

View file

@ -10,35 +10,64 @@ __metaclass__ = type
import re import re
from ansible import context from ansible import context
from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import become_loader from .helper import call_become_plugin
def test_dzdo(mocker, parser, reset_cli_args): def test_dzdo(mocker, parser, reset_cli_args):
options = parser.parse_args([]) options = parser.parse_args([])
context._init_global_context(options) context._init_global_context(options)
play_context = PlayContext()
default_cmd = "/bin/foo" default_cmd = "/bin/foo"
default_exe = "/bin/bash" default_exe = "/bin/bash"
dzdo_exe = 'dzdo' dzdo_exe = 'dzdo'
dzdo_flags = '' dzdo_flags = ''
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) success = 'BECOME-SUCCESS-.+?'
assert cmd == default_cmd
task = {
'become_user': 'foo',
'become_method': 'community.general.dzdo',
'become_flags': dzdo_flags,
}
var_options = {}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, task['become_user'], default_exe,
success, default_cmd), cmd) is not None
task['become_pass'] = 'testpass'
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert re.match("""%s %s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, r'\"\[dzdo via ansible, key=.+?\] password:\"',
task['become_user'], default_exe, success, default_cmd), cmd) is not None
def test_dzdo_varoptions(mocker, parser, reset_cli_args):
options = parser.parse_args([])
context._init_global_context(options)
default_cmd = "/bin/foo"
default_exe = "/bin/bash"
dzdo_exe = 'dzdo'
dzdo_flags = ''
success = 'BECOME-SUCCESS-.+?' success = 'BECOME-SUCCESS-.+?'
play_context.become = True task = {
play_context.become_user = 'foo' 'become_user': 'foo',
play_context.set_become_plugin(become_loader.get('dzdo')) 'become_method': 'community.general.dzdo',
play_context.become_method = 'dzdo' 'become_flags': 'xxx',
play_context.become_flags = dzdo_flags }
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) var_options = {
assert re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, play_context.become_user, default_exe, 'ansible_become_user': 'bar',
'ansible_become_flags': dzdo_flags,
}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert re.match("""%s %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, var_options['ansible_become_user'], default_exe,
success, default_cmd), cmd) is not None success, default_cmd), cmd) is not None
play_context.become_pass = 'testpass' var_options['ansible_become_pass'] = 'testpass'
play_context.set_become_plugin(become_loader.get('dzdo')) cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) print(cmd)
assert re.match("""%s %s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, r'\"\[dzdo via ansible, key=.+?\] password:\"', assert re.match("""%s %s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, dzdo_flags, r'\"\[dzdo via ansible, key=.+?\] password:\"',
play_context.become_user, default_exe, success, default_cmd), cmd) is not None var_options['ansible_become_user'], default_exe, success, default_cmd), cmd) is not None

View file

@ -10,30 +10,54 @@ __metaclass__ = type
import re import re
from ansible import context from ansible import context
from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import become_loader from .helper import call_become_plugin
def test_ksu(mocker, parser, reset_cli_args): def test_ksu(mocker, parser, reset_cli_args):
options = parser.parse_args([]) options = parser.parse_args([])
context._init_global_context(options) context._init_global_context(options)
play_context = PlayContext()
default_cmd = "/bin/foo" default_cmd = "/bin/foo"
default_exe = "/bin/bash" default_exe = "/bin/bash"
ksu_exe = 'ksu' ksu_exe = 'ksu'
ksu_flags = '' ksu_flags = ''
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) success = 'BECOME-SUCCESS-.+?'
assert cmd == default_cmd
task = {
'become_user': 'foo',
'become_method': 'community.general.ksu',
'become_flags': ksu_flags,
}
var_options = {}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert (re.match("""%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, task['become_user'], ksu_flags,
default_exe, success, default_cmd), cmd) is not None)
def test_ksu_varoptions(mocker, parser, reset_cli_args):
options = parser.parse_args([])
context._init_global_context(options)
default_cmd = "/bin/foo"
default_exe = "/bin/bash"
ksu_exe = 'ksu'
ksu_flags = ''
success = 'BECOME-SUCCESS-.+?' success = 'BECOME-SUCCESS-.+?'
play_context.become = True task = {
play_context.become_user = 'foo' 'become_user': 'foo',
play_context.set_become_plugin(become_loader.get('ksu')) 'become_method': 'community.general.ksu',
play_context.become_method = 'ksu' 'become_flags': 'xxx',
play_context.become_flags = ksu_flags }
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) var_options = {
assert (re.match("""%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags, 'ansible_become_user': 'bar',
'ansible_become_flags': ksu_flags,
}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert (re.match("""%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, var_options['ansible_become_user'], ksu_flags,
default_exe, success, default_cmd), cmd) is not None) default_exe, success, default_cmd), cmd) is not None)

View file

@ -10,30 +10,54 @@ __metaclass__ = type
import re import re
from ansible import context from ansible import context
from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import become_loader from .helper import call_become_plugin
def test_pbrun(mocker, parser, reset_cli_args): def test_pbrun(mocker, parser, reset_cli_args):
options = parser.parse_args([]) options = parser.parse_args([])
context._init_global_context(options) context._init_global_context(options)
play_context = PlayContext()
default_cmd = "/bin/foo" default_cmd = "/bin/foo"
default_exe = "/bin/bash" default_exe = "/bin/bash"
pbrun_exe = 'pbrun' pbrun_exe = 'pbrun'
pbrun_flags = '' pbrun_flags = ''
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) success = 'BECOME-SUCCESS-.+?'
assert cmd == default_cmd
task = {
'become_user': 'foo',
'become_method': 'community.general.pbrun',
'become_flags': pbrun_flags,
}
var_options = {}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert re.match("""%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, task['become_user'],
success, default_cmd), cmd) is not None
def test_pbrun_var_varoptions(mocker, parser, reset_cli_args):
options = parser.parse_args([])
context._init_global_context(options)
default_cmd = "/bin/foo"
default_exe = "/bin/bash"
pbrun_exe = 'pbrun'
pbrun_flags = ''
success = 'BECOME-SUCCESS-.+?' success = 'BECOME-SUCCESS-.+?'
play_context.become = True task = {
play_context.become_user = 'foo' 'become_user': 'foo',
play_context.set_become_plugin(become_loader.get('pbrun')) 'become_method': 'community.general.pbrun',
play_context.become_method = 'pbrun' 'become_flags': 'xxx',
play_context.become_flags = pbrun_flags }
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) var_options = {
assert re.match("""%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, play_context.become_user, 'ansible_become_user': 'bar',
'ansible_become_flags': pbrun_flags,
}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert re.match("""%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, var_options['ansible_become_user'],
success, default_cmd), cmd) is not None success, default_cmd), cmd) is not None

View file

@ -10,29 +10,52 @@ __metaclass__ = type
import re import re
from ansible import context from ansible import context
from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import become_loader from .helper import call_become_plugin
def test_pfexec(mocker, parser, reset_cli_args): def test_pfexec(mocker, parser, reset_cli_args):
options = parser.parse_args([]) options = parser.parse_args([])
context._init_global_context(options) context._init_global_context(options)
play_context = PlayContext()
default_cmd = "/bin/foo" default_cmd = "/bin/foo"
default_exe = "/bin/bash" default_exe = "/bin/bash"
pfexec_exe = 'pfexec' pfexec_exe = 'pfexec'
pfexec_flags = '' pfexec_flags = ''
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) success = 'BECOME-SUCCESS-.+?'
assert cmd == default_cmd
task = {
'become_user': 'foo',
'become_method': 'community.general.pfexec',
'become_flags': pfexec_flags,
}
var_options = {}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
assert re.match('''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, success, default_cmd), cmd) is not None
def test_pfexec_varoptions(mocker, parser, reset_cli_args):
options = parser.parse_args([])
context._init_global_context(options)
default_cmd = "/bin/foo"
default_exe = "/bin/bash"
pfexec_exe = 'pfexec'
pfexec_flags = ''
success = 'BECOME-SUCCESS-.+?' success = 'BECOME-SUCCESS-.+?'
play_context.become = True task = {
play_context.become_user = 'foo' 'become_user': 'foo',
play_context.set_become_plugin(become_loader.get('pfexec')) 'become_method': 'community.general.pfexec',
play_context.become_method = 'pfexec' 'become_flags': 'xxx',
play_context.become_flags = pfexec_flags }
cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) var_options = {
'ansible_become_user': 'bar',
'ansible_become_flags': pfexec_flags,
}
cmd = call_become_plugin(task, var_options, cmd=default_cmd, executable=default_exe)
print(cmd)
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