Skip to content

Commit

Permalink
Merge pull request #56815 from garethgreenaway/master-port-49955
Browse files Browse the repository at this point in the history
[master] Port #49955 to master
  • Loading branch information
dwoz authored Apr 23, 2020
2 parents 25e6a05 + 962daf4 commit 1c3f08b
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 0 deletions.
9 changes: 9 additions & 0 deletions conf/minion
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,15 @@
#
#state_aggregate: False

# Disable requisites during state runs by specifying a single requisite
# or a list of requisites to disable.
#
# disabled_requisites: require_in
#
# disabled_requisites:
# - require
# - require_in

##### File Directory Settings #####
##########################################
# The Salt Minion can redirect all file server operations to a local directory,
Expand Down
6 changes: 6 additions & 0 deletions doc/topics/releases/sodium.rst
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,9 @@ You can set this setting in your roster file like so:
user: root
passwd: P@ssword
set_path: '$PATH:/usr/local/bin/'
State Changes
=============
- Adding a new option for the State compiler, ``disabled_requisites`` will allow
requisites to be disabled during State runs.
2 changes: 2 additions & 0 deletions salt/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -925,6 +925,7 @@ def _gather_buffer_space():
# Allow raw_shell option when using the ssh
# client via the Salt API
"netapi_allow_raw_shell": bool,
"disabled_requisites": (six.string_types, list),
}
)

Expand Down Expand Up @@ -1216,6 +1217,7 @@ def _gather_buffer_space():
"discovery": False,
"schedule": {},
"ssh_merge_pillar": True,
"disabled_requisites": [],
}
)

Expand Down
16 changes: 16 additions & 0 deletions salt/state.py
Original file line number Diff line number Diff line change
Expand Up @@ -1684,6 +1684,9 @@ def requisite_in(self, high):
)
extend = {}
errors = []
disabled_reqs = self.opts.get("disabled_requisites", [])
if not isinstance(disabled_reqs, list):
disabled_reqs = [disabled_reqs]
for id_, body in six.iteritems(high):
if not isinstance(body, dict):
continue
Expand All @@ -1702,6 +1705,11 @@ def requisite_in(self, high):
key = next(iter(arg))
if key not in req_in:
continue
if key in disabled_reqs:
log.warning(
"The %s requisite has been disabled, Ignoring.", key
)
continue
rkey = key.split("_")[0]
items = arg[key]
if isinstance(items, dict):
Expand Down Expand Up @@ -2543,6 +2551,9 @@ def check_requisite(self, low, running, chunks, pre=False):
Look into the running data to check the status of all requisite
states
"""
disabled_reqs = self.opts.get("disabled_requisites", [])
if not isinstance(disabled_reqs, list):
disabled_reqs = [disabled_reqs]
present = False
# If mod_watch is not available make it a require
if "watch" in low:
Expand Down Expand Up @@ -2598,6 +2609,11 @@ def check_requisite(self, low, running, chunks, pre=False):
reqs["prerequired"] = []
for r_state in reqs:
if r_state in low and low[r_state] is not None:
if r_state in disabled_reqs:
log.warning(
"The %s requisite has been disabled, Ignoring.", r_state
)
continue
for req in low[r_state]:
if isinstance(req, six.string_types):
req = {"id": req}
Expand Down
83 changes: 83 additions & 0 deletions tests/unit/test_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,89 @@ def test_verify_retry_parsing(self):
with patch.object(state_obj, "_run_check", return_value=mock):
self.assertDictContainsSubset(expected_result, state_obj.call(low_data))

def test_render_requisite_require_disabled(self):
"""
Test that the state compiler correctly deliver a rendering
exception when a requisite cannot be resolved
"""
with patch("salt.state.State._gather_pillar") as state_patch:
high_data = {
"step_one": OrderedDict(
[
(
"test",
[
OrderedDict(
[("require", [OrderedDict([("test", "step_two")])])]
),
"succeed_with_changes",
{"order": 10000},
],
),
("__sls__", "test.disable_require"),
("__env__", "base"),
]
),
"step_two": {
"test": ["succeed_with_changes", {"order": 10001}],
"__env__": "base",
"__sls__": "test.disable_require",
},
}

minion_opts = self.get_temp_config("minion")
minion_opts["disabled_requisites"] = ["require"]
state_obj = salt.state.State(minion_opts)
ret = state_obj.call_high(high_data)
run_num = ret["test_|-step_one_|-step_one_|-succeed_with_changes"][
"__run_num__"
]
self.assertEqual(run_num, 0)

def test_render_requisite_require_in_disabled(self):
"""
Test that the state compiler correctly deliver a rendering
exception when a requisite cannot be resolved
"""
with patch("salt.state.State._gather_pillar") as state_patch:
high_data = {
"step_one": {
"test": ["succeed_with_changes", {"order": 10000}],
"__env__": "base",
"__sls__": "test.disable_require_in",
},
"step_two": OrderedDict(
[
(
"test",
[
OrderedDict(
[
(
"require_in",
[OrderedDict([("test", "step_one")])],
)
]
),
"succeed_with_changes",
{"order": 10001},
],
),
("__sls__", "test.disable_require_in"),
("__env__", "base"),
]
),
}

minion_opts = self.get_temp_config("minion")
minion_opts["disabled_requisites"] = ["require_in"]
state_obj = salt.state.State(minion_opts)
ret = state_obj.call_high(high_data)
run_num = ret["test_|-step_one_|-step_one_|-succeed_with_changes"][
"__run_num__"
]
self.assertEqual(run_num, 0)


class HighStateTestCase(TestCase, AdaptedConfigurationTestCaseMixin):
def setUp(self):
Expand Down

0 comments on commit 1c3f08b

Please sign in to comment.