mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #44578 from gtmanfred/ssh
enable calling SaltSSH minions from the salt master
This commit is contained in:
commit
4ff2d1ab18
5 changed files with 63 additions and 10 deletions
|
@ -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``
|
||||
------------
|
||||
|
||||
|
|
|
@ -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
|
||||
--------------------------------------------
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue