mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #42290 from isbm/isbm-module_run_parambug_42270_217
Backport of #42270
This commit is contained in:
commit
22eea389fa
3 changed files with 60 additions and 15 deletions
|
@ -122,13 +122,12 @@ State Module Changes
|
|||
# After
|
||||
run_something:
|
||||
module.run:
|
||||
mymodule.something:
|
||||
- mymodule.something:
|
||||
- name: some name
|
||||
- first_arg: one
|
||||
- second_arg: two
|
||||
- do_stuff: True
|
||||
|
||||
|
||||
Since a lot of users are already using :py:func:`module.run
|
||||
<salt.states.module.run>` states, this new behavior must currently be
|
||||
explicitly turned on, to allow users to take their time updating their SLS
|
||||
|
@ -136,6 +135,36 @@ State Module Changes
|
|||
the next feature release of Salt (Oxygen) and the old usage will no longer be
|
||||
supported at that time.
|
||||
|
||||
Another feature of the new :py:func:`module.run <salt.states.module.run>` is that
|
||||
it allows calling many functions in a single batch, such as:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
run_something:
|
||||
module.run:
|
||||
- mymodule.function_without_parameters:
|
||||
- mymodule.another_function:
|
||||
- myparam
|
||||
- my_other_param
|
||||
|
||||
In a rare case that you have a function that needs to be called several times but
|
||||
with the different parameters, an additional feature of "tagging" is to the
|
||||
rescue. In order to tag a function, use a colon delimeter. For example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
run_something:
|
||||
module.run:
|
||||
- mymodule.same_function:1:
|
||||
- mymodule.same_function:2:
|
||||
- myparam
|
||||
- my_other_param
|
||||
- mymodule.same_function:3:
|
||||
- foo: bar
|
||||
|
||||
The example above will run `mymodule.same_function` three times with the
|
||||
different parameters.
|
||||
|
||||
To enable the new behavior for :py:func:`module.run <salt.states.module.run>`,
|
||||
add the following to the minion config file:
|
||||
|
||||
|
@ -143,6 +172,7 @@ State Module Changes
|
|||
|
||||
use_superseded:
|
||||
- module.run
|
||||
|
||||
- The default for the ``fingerprint_hash_type`` option used in the ``present``
|
||||
function in the :mod:`ssh <salt.states.ssh_know_hosts>` state changed from
|
||||
``md5`` to ``sha256``.
|
||||
|
|
|
@ -262,6 +262,7 @@ def run(**kwargs):
|
|||
missing = []
|
||||
tests = []
|
||||
for func in functions:
|
||||
func = func.split(':')[0]
|
||||
if func not in __salt__:
|
||||
missing.append(func)
|
||||
elif __opts__['test']:
|
||||
|
@ -284,8 +285,9 @@ def run(**kwargs):
|
|||
failures = []
|
||||
success = []
|
||||
for func in functions:
|
||||
_func = func.split(':')[0]
|
||||
try:
|
||||
func_ret = _call_function(func, returner=kwargs.get('returner'),
|
||||
func_ret = _call_function(_func, returner=kwargs.get('returner'),
|
||||
func_args=kwargs.get(func))
|
||||
if not _get_result(func_ret, ret['changes'].get('ret', {})):
|
||||
if isinstance(func_ret, dict):
|
||||
|
@ -313,22 +315,35 @@ def _call_function(name, returner=None, **kwargs):
|
|||
'''
|
||||
argspec = salt.utils.args.get_function_argspec(__salt__[name])
|
||||
func_kw = dict(zip(argspec.args[-len(argspec.defaults or []):], # pylint: disable=incompatible-py3-code
|
||||
argspec.defaults or []))
|
||||
func_args = []
|
||||
for funcset in kwargs.get('func_args') or {}:
|
||||
if isinstance(funcset, dict):
|
||||
func_kw.update(funcset)
|
||||
argspec.defaults or []))
|
||||
arg_type, na_type, kw_type = [], {}, False
|
||||
for funcset in reversed(kwargs.get('func_args') or []):
|
||||
if not isinstance(funcset, dict):
|
||||
kw_type = True
|
||||
if kw_type:
|
||||
if isinstance(funcset, dict):
|
||||
arg_type += funcset.values()
|
||||
na_type.update(funcset)
|
||||
else:
|
||||
arg_type.append(funcset)
|
||||
else:
|
||||
func_args.append(funcset)
|
||||
func_kw.update(funcset)
|
||||
arg_type.reverse()
|
||||
|
||||
_exp_prm = len(argspec.args or []) - len(argspec.defaults or [])
|
||||
_passed_prm = len(arg_type)
|
||||
missing = []
|
||||
for arg in argspec.args:
|
||||
if arg not in func_kw:
|
||||
missing.append(arg)
|
||||
if na_type and _exp_prm > _passed_prm:
|
||||
for arg in argspec.args:
|
||||
if arg not in func_kw:
|
||||
missing.append(arg)
|
||||
if missing:
|
||||
raise SaltInvocationError('Missing arguments: {0}'.format(', '.join(missing)))
|
||||
elif _exp_prm > _passed_prm:
|
||||
raise SaltInvocationError('Function expects {0} parameters, got only {1}'.format(
|
||||
_exp_prm, _passed_prm))
|
||||
|
||||
mret = __salt__[name](*func_args, **func_kw)
|
||||
mret = __salt__[name](*arg_type, **func_kw)
|
||||
if returner is not None:
|
||||
returners = salt.loader.returners(__opts__, __salt__)
|
||||
if returner in returners:
|
||||
|
|
|
@ -122,7 +122,7 @@ class ModuleStateTest(TestCase, LoaderModuleMockMixin):
|
|||
with patch.dict(module.__salt__, {CMD: _mocked_func_named}):
|
||||
with patch.dict(module.__opts__, {'use_superseded': ['module.run']}):
|
||||
ret = module.run(**{CMD: None})
|
||||
assert ret['comment'] == "'{0}' failed: Missing arguments: name".format(CMD)
|
||||
assert ret['comment'] == "'{0}' failed: Function expects 1 parameters, got only 0".format(CMD)
|
||||
|
||||
def test_run_correct_arg(self):
|
||||
'''
|
||||
|
@ -131,7 +131,7 @@ class ModuleStateTest(TestCase, LoaderModuleMockMixin):
|
|||
'''
|
||||
with patch.dict(module.__salt__, {CMD: _mocked_func_named}):
|
||||
with patch.dict(module.__opts__, {'use_superseded': ['module.run']}):
|
||||
ret = module.run(**{CMD: [{'name': 'Fred'}]})
|
||||
ret = module.run(**{CMD: ['Fred']})
|
||||
assert ret['comment'] == '{0}: Success'.format(CMD)
|
||||
assert ret['result']
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue