%PDF- %PDF-
Direktori : /proc/self/root/lib/python2.7/site-packages/salt/client/ssh/ |
Current File : //proc/self/root/lib/python2.7/site-packages/salt/client/ssh/client.py |
# -*- coding: utf-8 -*- # Import Python libs from __future__ import absolute_import, print_function, unicode_literals import os import copy import logging import random # Import Salt libs import salt.config import salt.utils.args import salt.syspaths as syspaths from salt.exceptions import SaltClientError # Temporary log = logging.getLogger(__name__) class SSHClient(object): ''' Create a client object for executing routines via the salt-ssh backend .. versionadded:: 2015.5.0 ''' def __init__(self, c_path=os.path.join(syspaths.CONFIG_DIR, 'master'), mopts=None, disable_custom_roster=False): if mopts: self.opts = mopts else: if os.path.isdir(c_path): log.warning( '%s expects a file path not a directory path(%s) to ' 'its \'c_path\' keyword argument', self.__class__.__name__, c_path ) self.opts = salt.config.client_config(c_path) # Salt API should never offer a custom roster! self.opts['__disable_custom_roster'] = disable_custom_roster def _prep_ssh( self, tgt, fun, arg=(), timeout=None, tgt_type='glob', kwarg=None, **kwargs): ''' Prepare the arguments ''' opts = copy.deepcopy(self.opts) opts.update(kwargs) if timeout: opts['timeout'] = timeout arg = salt.utils.args.condition_input(arg, kwarg) opts['argv'] = [fun] + arg opts['selected_target_option'] = tgt_type opts['tgt'] = tgt opts['arg'] = arg return salt.client.ssh.SSH(opts) def cmd_iter( self, tgt, fun, arg=(), timeout=None, tgt_type='glob', ret='', kwarg=None, **kwargs): ''' Execute a single command via the salt-ssh subsystem and return a generator .. versionadded:: 2015.5.0 ''' ssh = self._prep_ssh( tgt, fun, arg, timeout, tgt_type, kwarg, **kwargs) for ret in ssh.run_iter(jid=kwargs.get('jid', None)): yield ret def cmd(self, tgt, fun, arg=(), timeout=None, tgt_type='glob', kwarg=None, **kwargs): ''' Execute a single command via the salt-ssh subsystem and return all routines at once .. versionadded:: 2015.5.0 ''' ssh = self._prep_ssh( tgt, fun, arg, timeout, tgt_type, kwarg, **kwargs) final = {} for ret in ssh.run_iter(jid=kwargs.get('jid', None)): final.update(ret) return final def cmd_sync(self, low): ''' Execute a salt-ssh call synchronously. .. versionadded:: 2015.5.0 WARNING: Eauth is **NOT** respected .. code-block:: python client.cmd_sync({ 'tgt': 'silver', 'fun': 'test.ping', 'arg': (), 'tgt_type'='glob', 'kwarg'={} }) {'silver': {'fun_args': [], 'jid': '20141202152721523072', 'return': True, 'retcode': 0, 'success': True, 'fun': 'test.ping', 'id': 'silver'}} ''' kwargs = copy.deepcopy(low) for ignore in ['tgt', 'fun', 'arg', 'timeout', 'tgt_type', 'kwarg']: if ignore in kwargs: del kwargs[ignore] return self.cmd(low['tgt'], low['fun'], low.get('arg', []), low.get('timeout'), low.get('tgt_type'), low.get('kwarg'), **kwargs) def cmd_async(self, low, timeout=None): ''' Execute aa salt-ssh asynchronously WARNING: Eauth is **NOT** respected .. code-block:: python client.cmd_sync({ 'tgt': 'silver', 'fun': 'test.ping', 'arg': (), 'tgt_type'='glob', 'kwarg'={} }) {'silver': {'fun_args': [], 'jid': '20141202152721523072', 'return': True, 'retcode': 0, 'success': True, 'fun': 'test.ping', 'id': 'silver'}} ''' # TODO Not implemented raise SaltClientError def cmd_subset( self, tgt, fun, arg=(), timeout=None, tgt_type='glob', ret='', kwarg=None, sub=3, **kwargs): ''' Execute a command on a random subset of the targeted systems The function signature is the same as :py:meth:`cmd` with the following exceptions. :param sub: The number of systems to execute on .. code-block:: python >>> import salt.client.ssh.client >>> sshclient= salt.client.ssh.client.SSHClient() >>> sshclient.cmd_subset('*', 'test.ping', sub=1) {'jerry': True} .. versionadded:: 2017.7.0 ''' minion_ret = self.cmd(tgt, 'sys.list_functions', tgt_type=tgt_type, **kwargs) minions = list(minion_ret) random.shuffle(minions) f_tgt = [] for minion in minions: if fun in minion_ret[minion]['return']: f_tgt.append(minion) if len(f_tgt) >= sub: break return self.cmd_iter(f_tgt, fun, arg, timeout, tgt_type='list', ret=ret, kwarg=kwarg, **kwargs)