Merge pull request #44578 from gtmanfred/ssh

enable calling SaltSSH minions from the salt master
This commit is contained in:
Nicole Thomas 2017-12-28 13:02:38 -05:00 committed by GitHub
commit 4ff2d1ab18
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 63 additions and 10 deletions

View file

@ -96,6 +96,23 @@ The user to run the Salt processes
.. conf_master:: ret_port
``enable_ssh_minions``
----------------------
Default: ``False``
Tell the master to also use salt-ssh when running commands against minions.
.. code-block:: yaml
enable_ssh_minions: True
.. note::
Cross-minion communication is still not possible. The Salt mine and
publish.publish do not work between minion types.
``ret_port``
------------

View file

@ -107,6 +107,15 @@ Salt CLI.
salt myminion docker.create image=foo/bar:baz command=/path/to/command start=True
Use SaltSSH Minions like regular Master-Minions
-----------------------------------------------
The Master process can now also call SSH minions as if they were connected to
the master using ZeroMQ. By setting `enable_ssh_minions: True` in the the
master config file, the master will create a SaltSSH client process which
connects to the minion and returns the output for the `salt` commandline to use
like a regular minion. This can be used anywhere the LocalClient is used.
Comparison Operators in Package Installation
--------------------------------------------

View file

@ -214,7 +214,7 @@ class SSH(object):
def __init__(self, opts):
self.__parsed_rosters = {SSH.ROSTER_UPDATE_FLAG: True}
pull_sock = os.path.join(opts['sock_dir'], 'master_event_pull.ipc')
if os.path.isfile(pull_sock) and HAS_ZMQ:
if os.path.exists(pull_sock) and HAS_ZMQ:
self.event = salt.utils.event.get_event(
'master',
opts['sock_dir'],
@ -662,11 +662,13 @@ class SSH(object):
host = next(six.iterkeys(ret))
self.cache_job(jid, host, ret[host], fun)
if self.event:
_, data = next(six.iteritems(ret))
data['jid'] = jid # make the jid in the payload the same as the jid in the tag
self.event.fire_event(
ret,
salt.utils.event.tagify(
[jid, 'ret', host],
'job'))
data,
salt.utils.event.tagify(
[jid, 'ret', host],
'job'))
yield ret
def cache_job(self, jid, id_, ret, fun):
@ -771,11 +773,13 @@ class SSH(object):
outputter,
self.opts)
if self.event:
_, data = next(six.iteritems(ret))
data['jid'] = jid # make the jid in the payload the same as the jid in the tag
self.event.fire_event(
ret,
salt.utils.event.tagify(
[jid, 'ret', host],
'job'))
data,
salt.utils.event.tagify(
[jid, 'ret', host],
'job'))
if self.opts.get('static'):
salt.output.display_output(
sret,
@ -1262,7 +1266,7 @@ ARGS = {10}\n'''.format(self.minion_config,
self.argv = _convert_args(self.argv)
log.debug(
'Performing shimmed, blocking command as follows:\n%s',
' '.join(self.argv)
' '.join([six.text_type(arg) for arg in self.argv])
)
cmd_str = self._cmd_str()
stdout, stderr, retcode = self.shim_cmd(cmd_str)

View file

@ -1183,6 +1183,9 @@ VALID_OPTS = {
# Scheduler should be a dictionary
'schedule': dict,
# Enable calling ssh minions from the salt master
'enable_ssh_minions': bool,
}
# default configurations
@ -1799,6 +1802,8 @@ DEFAULT_MASTER_OPTS = {
'mapping': {},
},
'schedule': {},
'enable_ssh': False,
'enable_ssh_minions': False,
}

View file

@ -19,6 +19,7 @@ import logging
import collections
import multiprocessing
import salt.serializers.msgpack
import threading
# Import third party libs
try:
@ -49,6 +50,7 @@ import tornado.gen # pylint: disable=F0401
# Import salt libs
import salt.crypt
import salt.client
import salt.client.ssh.client
import salt.payload
import salt.pillar
import salt.state
@ -1957,6 +1959,7 @@ class ClearFuncs(object):
payload = self._prep_pub(minions, jid, clear_load, extra, missing)
# Send it!
minions.extend(self._send_ssh_pub(payload))
self._send_pub(payload)
return {
@ -2019,6 +2022,21 @@ class ClearFuncs(object):
chan = salt.transport.server.PubServerChannel.factory(opts)
chan.publish(load)
def _send_ssh_pub(self, load):
'''
Take a load and send it across the network to connected minions
'''
minions = []
if self.opts['enable_ssh_minions'] is True and isinstance(load['tgt'], six.string_types):
# The isinstances makes sure that syndics work
log.debug('Use SSHClient for rostered minions')
ssh = salt.client.ssh.client.SSHClient()
ssh_minions = ssh._prep_ssh(**load).targets.keys()
if ssh_minions:
minions.extend(ssh_minions)
threading.Thread(target=ssh.cmd, kwargs=load).start()
return minions
def _prep_pub(self, minions, jid, clear_load, extra, missing):
'''
Take a given load and perform the necessary steps