Updating salt-call, salt-run and salt to show documentation when a valid module but no function is passed.

This commit is contained in:
Gareth J. Greenaway 2017-07-19 11:56:36 -07:00
parent ddc0286d57
commit 343b970a00
4 changed files with 36 additions and 11 deletions

View File

@ -165,6 +165,11 @@ class BaseCaller(object):
ret['jid'] ret['jid']
) )
if fun not in self.minion.functions: if fun not in self.minion.functions:
docs = self.minion.functions['sys.doc']('{0}*'.format(fun))
if docs:
ret['out'] = 'nested'
ret['return'] = docs
return ret
sys.stderr.write(self.minion.functions.missing_fun_string(fun)) sys.stderr.write(self.minion.functions.missing_fun_string(fun))
mod_name = fun.split('.')[0] mod_name = fun.split('.')[0]
if mod_name in self.minion.function_errors: if mod_name in self.minion.function_errors:

View File

@ -5,6 +5,7 @@ A collection of mixins useful for the various *Client interfaces
# Import Python libs # Import Python libs
from __future__ import absolute_import, print_function, with_statement from __future__ import absolute_import, print_function, with_statement
import fnmatch
import signal import signal
import logging import logging
import weakref import weakref
@ -436,10 +437,19 @@ class SyncClientMixin(object):
Return a dictionary of functions and the inline documentation for each Return a dictionary of functions and the inline documentation for each
''' '''
if arg: if arg:
target_mod = arg + '.' if not arg.endswith('.') else arg if '*' in arg:
docs = [(fun, self.functions[fun].__doc__) target_mod = arg
for fun in sorted(self.functions) _use_fnmatch = True
if fun == arg or fun.startswith(target_mod)] else:
target_mod = arg + '.' if not arg.endswith('.') else arg
log.debug('target_mod {}'.format(target_mod))
if _use_fnmatch:
docs = [(fun, self.functions[fun].__doc__)
for fun in fnmatch.filter(self.functions, target_mod)]
else:
docs = [(fun, self.functions[fun].__doc__)
for fun in sorted(self.functions)
if fun == arg or fun.startswith(target_mod)]
else: else:
docs = [(fun, self.functions[fun].__doc__) docs = [(fun, self.functions[fun].__doc__)
for fun in sorted(self.functions)] for fun in sorted(self.functions)]

View File

@ -1520,12 +1520,16 @@ class Minion(MinionBase):
ret['return'] = '{0}: {1}'.format(msg, traceback.format_exc()) ret['return'] = '{0}: {1}'.format(msg, traceback.format_exc())
ret['out'] = 'nested' ret['out'] = 'nested'
else: else:
ret['return'] = minion_instance.functions.missing_fun_string(function_name) docs = minion_instance.functions['sys.doc']('{0}*'.format(function_name))
mod_name = function_name.split('.')[0] if docs:
if mod_name in minion_instance.function_errors: ret['return'] = docs
ret['return'] += ' Possible reasons: \'{0}\''.format( else:
minion_instance.function_errors[mod_name] ret['return'] = minion_instance.functions.missing_fun_string(function_name)
) mod_name = function_name.split('.')[0]
if mod_name in minion_instance.function_errors:
ret['return'] += ' Possible reasons: \'{0}\''.format(
minion_instance.function_errors[mod_name]
)
ret['success'] = False ret['success'] = False
ret['retcode'] = 254 ret['retcode'] = 254
ret['out'] = 'nested' ret['out'] = 'nested'

View File

@ -276,7 +276,13 @@ class Runner(RunnerClient):
'fun_args': fun_args, 'fun_args': fun_args,
'jid': self.jid}, 'jid': self.jid},
tag='salt/run/{0}/ret'.format(self.jid)) tag='salt/run/{0}/ret'.format(self.jid))
ret = '{0}'.format(exc) # Attempt to grab documentation
ret = self.get_docs('{0}*'.format(low['fun']))
# If we didn't get docs returned then
# return the `not availble` message.
if not ret:
ret = '{0}'.format(exc)
if not self.opts.get('quiet', False): if not self.opts.get('quiet', False):
display_output(ret, 'nested', self.opts) display_output(ret, 'nested', self.opts)
else: else: