Merge pull request #25089 from jfindlay/fix_sudo

fix minion sudo
This commit is contained in:
Mike Place 2015-07-01 09:53:16 -06:00
commit 7c8d2a8656
4 changed files with 88 additions and 11 deletions

View file

@ -48,6 +48,12 @@
# The user to run salt.
#user: root
# Setting sudo_user will cause salt to run all execution modules under an sudo
# to the user given in sudo_user. The user under which the salt minion process
# itself runs will still be that provided in the user config above, but all
# execution modules run by the minion will be rerouted through sudo.
#sudo_user: saltdev
# Specify the location of the daemon process ID file.
#pidfile: /var/run/salt-minion.pid
@ -615,7 +621,7 @@
#tcp_keepalive_intvl: -1
###### Windows Software settings ######
###### Windows Software settings ######
############################################
# Location of the repository cache file on the master:
#win_repo_cachefile: 'salt://win/repo/winrepo.p'

View file

@ -175,6 +175,22 @@ The user to run the Salt processes
user: root
.. conf_minion:: sudo_user
``sudo_user``
--------
Default: ``''``
Setting ``sudo_user`` will cause salt to run all execution modules under an
sudo to the user given in ``sudo_user``. The user under which the salt minion
process itself runs will still be that provided in :conf_minion:`user` above,
but all execution modules run by the minion will be rerouted through sudo.
.. code-block:: yaml
sudo_user: saltadm
.. conf_minion:: pidfile
``pidfile``

View file

@ -290,6 +290,7 @@ VALID_OPTS = {
'rotate_aes_key': bool,
'cache_sreqs': bool,
'cmd_safe': bool,
'sudo_user': str,
}
# default configurations
@ -444,6 +445,7 @@ DEFAULT_MINION_OPTS = {
'zmq_monitor': False,
'cache_sreqs': True,
'cmd_safe': True,
'sudo_user': '',
}
DEFAULT_MASTER_OPTS = {

View file

@ -1,10 +1,41 @@
# -*- coding: utf-8 -*-
'''
Allow for the calling of execution modules via sudo
Allow for the calling of execution modules via sudo.
This module is invoked by the minion if the ``sudo_user`` minion config is
present.
Example minion config:
.. code-block:: yaml
sudo_user: saltdev
Once this setting is made, any execution module call done by the minion will be
run under ``sudo -u <sudo_user> salt-call``. For example, with the above
minion config,
.. code-block:: bash
salt sudo_minion cmd.run 'cat /etc/sudoers'
is equivalent to
.. code-block:: bash
sudo -u saltdev salt-call cmd.run 'cat /etc/sudoers'
being run on ``sudo_minion``.
'''
# Import python libs
import json
try:
from shlex import quote as _cmd_quote # pylint: disable=E0611
except ImportError:
from pipes import quote as _cmd_quote
# Import salt libs
from salt.exceptions import SaltInvocationError
import salt.utils
import salt.syspaths
@ -12,7 +43,7 @@ __virtualname__ = 'sudo'
def __virtual__():
if salt.utils.which('sudo'):
if salt.utils.which('sudo') and __opts__.get('sudo_user'):
return __virtualname__
return False
@ -21,23 +52,45 @@ def salt_call(runas, fun, *args, **kwargs):
'''
Wrap a shell execution out to salt call with sudo
CLI Example::
Example:
salt '*' sudo.salt_call root test.ping
/etc/salt/minion
.. code-block:: yaml
sudo_user: saltdev
.. code-block:: bash
salt '*' test.ping # is run as saltdev user
'''
if fun == 'sudo.salt_call':
__context__['retcode'] = 1
raise SaltInvocationError('sudo.salt_call is not designed to be run '
'directly, but is used by the minion when '
'the sudo_user config is set.')
cmd = ['sudo',
'-u', runas,
'salt-call',
'--out', 'json',
'--metadata',
'-c', salt.syspaths.CONFIG_DIR,
'--',
fun]
for arg in args:
cmd.append(arg)
cmd.append(_cmd_quote(arg))
for key in kwargs:
cmd.append('{0}={1}'.format(key, kwargs[key]))
cmd_ret = __salt__['cmd.run_all'](cmd, python_shell=False)
cmd_meta = json.loads(cmd_ret['stdout'])['local']
ret = cmd_meta['return']
__context__['retcode'] = cmd_meta.get('retcode', 0)
cmd.append(_cmd_quote('{0}={1}'.format(key, kwargs[key])))
cmd_ret = __salt__['cmd.run_all'](cmd, use_vt=True, python_shell=False)
if cmd_ret['retcode'] == 0:
cmd_meta = json.loads(cmd_ret['stdout'])['local']
ret = cmd_meta['return']
__context__['retcode'] = cmd_meta.get('retcode', 0)
else:
ret = cmd_ret['stderr']
__context__['retcode'] = cmd_ret['retcode']
return ret