allow result parsing in unless/onlyif

This commit is contained in:
Christian McHugh 2020-05-30 08:08:59 +01:00 committed by Daniel Wozniak
parent 1aeee46cfc
commit ae206709b5
5 changed files with 104 additions and 1 deletions

1
changelog/57470.added Normal file
View file

@ -0,0 +1 @@
Add "get_return" key for onlyif and unless requisites to parse deep module results

View file

@ -919,6 +919,21 @@ In the above case, ``some_check`` will be run prior to _each_ name -- once for
args:
- mysql-server-5.7
.. versionchanged:: sodium
For modules which return a deeper data structure, the ``get_return`` key can
be used to access results.
.. code-block:: yaml
test:
test.nop:
- name: foo
- unless:
- fun: consul.get
consul_url: http://127.0.0.1:8500
key: not-existing
get_return: res
.. _onlyif-requisite:
onlyif
@ -992,6 +1007,22 @@ if the gluster commands return a 0 ret value.
- /etc/crontab
- 'entry1'
.. versionchanged:: sodium
For modules which return a deeper data structure, the ``get_return`` key can
be used to access results.
.. code-block:: yaml
test:
test.nop:
- name: foo
- onlyif:
- fun: consul.get
consul_url: http://127.0.0.1:8500
key: does-exist
get_return: res
.. _creates-requisite:
Creates

View file

@ -32,7 +32,22 @@ The ``creates`` state requisite has been migrated from the
states to become a global option. This acts similar to an equivalent
``unless: test -f filename`` but can also accept a list of filenames. This allows
all states to take advantage of the enhanced functionality released in Neon, of allowing
salt execution modules for requisite checks.
salt execution modules for requisite checks.
When using salt functions ``onlyif`` or ``unless`` requisites, a ``get_return`` key can
now be used to specify a key to evaluate for truthiness. This can be used for execution modules
which return status in a nested key.
.. code-block:: yaml
test:
test.nop:
- name: foo
- onlyif:
- fun: consul.get
consul_url: http://127.0.0.1:8500
key: not-existing
get_return: res
State Execution Module
======================

View file

@ -960,7 +960,10 @@ class State(object):
log.warning(ret["comment"])
return ret
get_return = entry.pop("get_return", None)
result = self._run_check_function(entry)
if get_return:
result = salt.utils.data.traverse_dict_and_list(result, get_return)
if self.state_con.get("retcode", 0):
_check_cmd(self.state_con["retcode"])
elif not result:
@ -1023,7 +1026,10 @@ class State(object):
log.warning(ret["comment"])
return ret
get_return = entry.pop("get_return", None)
result = self._run_check_function(entry)
if get_return:
result = salt.utils.data.traverse_dict_and_list(result, get_return)
if self.state_con.get("retcode", 0):
_check_cmd(self.state_con["retcode"])
elif result:

View file

@ -116,6 +116,31 @@ class StateCompilerTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
return_result = state_obj._run_check_onlyif(low_data, "")
self.assertEqual(expected_result, return_result)
def test_verify_onlyif_parse_deep_return(self):
low_data = {
"state": "test",
"name": "foo",
"__sls__": "consol",
"__env__": "base",
"__id__": "test",
"onlyif": [
{
"fun": "test.arg",
"get_return": "kwargs:deep:return",
"deep": {"return": "true"},
}
],
"order": 10000,
"fun": "nop",
}
expected_result = {"comment": "onlyif condition is true", "result": False}
with patch("salt.state.State._gather_pillar") as state_patch:
minion_opts = self.get_temp_config("minion")
state_obj = salt.state.State(minion_opts)
return_result = state_obj._run_check_onlyif(low_data, "")
self.assertEqual(expected_result, return_result)
def test_verify_onlyif_cmd_error(self):
"""
Simulates a failure in cmd.retcode from onlyif
@ -206,6 +231,31 @@ class StateCompilerTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
return_result = state_obj._run_check_unless(low_data, "")
self.assertEqual(expected_result, return_result)
def test_verify_unless_parse_deep_return(self):
low_data = {
"state": "test",
"name": "foo",
"__sls__": "consol",
"__env__": "base",
"__id__": "test",
"unless": [
{
"fun": "test.arg",
"get_return": "kwargs:deep:return",
"deep": {"return": False},
}
],
"order": 10000,
"fun": "nop",
}
expected_result = {"comment": "unless condition is false", "result": False}
with patch("salt.state.State._gather_pillar") as state_patch:
minion_opts = self.get_temp_config("minion")
state_obj = salt.state.State(minion_opts)
return_result = state_obj._run_check_unless(low_data, "")
self.assertEqual(expected_result, return_result)
def test_verify_creates(self):
low_data = {
"state": "cmd",