fixes saltstack/salt#60990 add percent success/failure of state runs in highstate summary output

This commit is contained in:
nicholasmhughes 2021-10-02 10:01:55 -04:00 committed by Megan Wilhite
parent 1bdcbc19fb
commit ef8a9b8e55
10 changed files with 192 additions and 1 deletions

1
changelog/60990.added Normal file
View file

@ -0,0 +1 @@
Added percent success/failure of state runs in highstate summary output via new state_output_pct option

View file

@ -639,6 +639,10 @@
# will be shown for each state run.
#state_output_profile: True
# The state_output_pct setting changes whether success and failure information
# as a percent of total actions will be shown for each state run.
#state_output_pct: False
# Automatically aggregate all states that have support for mod_aggregate by
# setting to 'True'. Or pass a list of state module names to automatically
# aggregate just those types.

View file

@ -709,6 +709,10 @@
# will be shown for each state run.
#state_output_profile: True
# The state_output_pct setting changes whether success and failure information
# as a percent of total actions will be shown for each state run.
#state_output_pct: False
# Fingerprint of the master public key to validate the identity of your Salt master
# before the initial key exchange. The master fingerprint can be found by running
# "salt-key -f master.pub" on the Salt master.

View file

@ -514,6 +514,10 @@
# will be shown for each state run.
#state_output_profile: True
# The state_output_pct setting changes whether success and failure information
# as a percent of total actions will be shown for each state run.
#state_output_pct: False
# Fingerprint of the master public key to validate the identity of your Salt master
# before the initial key exchange. The master fingerprint can be found by running
# "salt-key -F master" on the Salt master.

View file

@ -574,6 +574,10 @@ syndic_user: salt
# states is cluttering the logs. Set it to True to ignore them.
#state_output_diff: False
# The state_output_pct setting changes whether success and failure information
# as a percent of total actions will be shown for each state run.
#state_output_pct: False
# Automatically aggregate all states that have support for mod_aggregate by
# setting to 'True'. Or pass a list of state module names to automatically
# aggregate just those types.

View file

@ -2565,6 +2565,20 @@ will be shown for each state run.
state_output_profile: True
.. conf_master:: state_output_pct
``state_output_pct``
------------------------
Default: ``False``
The ``state_output_pct`` setting changes whether success and failure information
as a percent of total actions will be shown for each state run.
.. code-block:: yaml
state_output_pct: False
.. conf_master:: state_aggregate
``state_aggregate``

View file

@ -2291,6 +2291,20 @@ will be shown for each state run.
state_output_profile: True
.. conf_minion:: state_output_pct
``state_output_pct``
------------------------
Default: ``False``
The ``state_output_pct`` setting changes whether success and failure information
as a percent of total actions will be shown for each state run.
.. code-block:: yaml
state_output_pct: False
.. conf_minion:: autoload_dynamic_modules
``autoload_dynamic_modules``

View file

@ -372,6 +372,8 @@ VALID_OPTS = immutabletypes.freeze(
"state_output_diff": bool,
# Tells the highstate outputter whether profile information will be shown for each state run
"state_output_profile": bool,
# Tells the highstate outputter whether success and failure percents will be shown for each state run
"state_output_pct": bool,
# When true, states run in the order defined in an SLS file, unless requisites re-order them
"state_auto_order": bool,
# Fire events as state chunks are processed by the state compiler

View file

@ -10,10 +10,11 @@ Two configurations can be set to modify the highstate outputter. These values
can be set in the master config to change the output of the ``salt`` command or
set in the minion config to change the output of the ``salt-call`` command.
state_verbose
state_verbose:
By default `state_verbose` is set to `True`, setting this to `False` will
instruct the highstate outputter to omit displaying anything in green, this
means that nothing with a result of True and no changes will not be printed
state_output:
The highstate outputter has six output modes,
``full``, ``terse``, ``mixed``, ``changes`` and ``filter``
@ -55,6 +56,10 @@ state_tabular:
output format. If you wish to use a custom format, this can be set to a
string.
state_output_pct:
Set `state_output_pct` to `True` in order to add "Success %" and "Failure %"
to the "Summary" section at the end of the highstate output.
Example usage:
If ``state_output: filter`` is set in the configuration file:
@ -479,6 +484,46 @@ def _format_host(host, data, indent_level=1):
)
)
if __opts__.get("state_output_pct", False):
# Add success percentages to the summary output
try:
success_pct = round(
(
(rcounts.get(True, 0) + rcounts.get(None, 0))
/ (sum(rcounts.values()) - rcounts.get("warnings", 0))
)
* 100,
2,
)
hstrs.append(
colorfmt.format(
colors["GREEN"],
_counts(f"Success %", success_pct),
colors,
)
)
except ZeroDivisionError:
pass
# Add failure percentages to the summary output
try:
failed_pct = round(
(num_failed / (sum(rcounts.values()) - rcounts.get("warnings", 0)))
* 100,
2,
)
hstrs.append(
colorfmt.format(
colors["RED"] if num_failed else colors["CYAN"],
_counts(f"Failure %", failed_pct),
colors,
)
)
except ZeroDivisionError:
pass
num_warnings = rcounts.get("warnings", 0)
if num_warnings:
hstrs.append(

View file

@ -220,3 +220,102 @@ class JsonNestedTestCase(TestCase, LoaderModuleMockMixin):
self.assertIn(" Succeeded: 2 (changed=1)", ret)
self.assertIn(" Failed: 0", ret)
self.assertIn(" Total states run: 2", ret)
class HighstatePercentTestCase(TestCase, LoaderModuleMockMixin):
"""
Test cases for salt.output.highstate with state_output_pct set to True
"""
def setup_loader_modules(self):
return {
highstate: {
"__opts__": {
"extension_modules": "",
"optimization_order": [0, 1, 2],
"color": False,
"state_output_pct": True,
}
}
}
def setUp(self):
self.data = {
"data": {
"master": {
"salt_|-call_sleep_state_|-call_sleep_state_|-state": {
"__id__": "call_sleep_state",
"__jid__": "20170418153529810135",
"__run_num__": 0,
"__sls__": "orch.simple",
"changes": {
"out": "highstate",
"ret": {
"minion": {
"module_|-simple-ping_|-test.ping_|-run": {
"__id__": "simple-ping",
"__run_num__": 0,
"__sls__": "simple-ping",
"changes": {"ret": True},
"comment": "Module function test.ping executed",
"duration": 56.179,
"name": "test.ping",
"result": True,
"start_time": "15:35:31.282099",
}
},
"sub_minion": {
"module_|-simple-ping_|-test.ping_|-run": {
"__id__": "simple-ping",
"__run_num__": 0,
"__sls__": "simple-ping",
"changes": {"ret": True},
"comment": "Module function test.ping executed",
"duration": 54.103,
"name": "test.ping",
"result": True,
"start_time": "15:35:31.005606",
}
},
},
},
"comment": (
"States ran successfully. Updating sub_minion, minion."
),
"duration": 1638.047,
"name": "call_sleep_state",
"result": True,
"start_time": "15:35:29.762657",
},
"salt_|-cmd_run_example_|-cmd.run_|-function": {
"__id__": "cmd_run_example",
"__jid__": "20200411195112288850",
"__run_num__": 1,
"__sls__": "orch.simple",
"changes": {
"out": "highstate",
"ret": {"minion": "file1\nfile2\nfile3"},
},
"comment": (
"Function ran successfully. Function cmd.run ran on minion."
),
"duration": 412.397,
"name": "cmd.run",
"result": True,
"start_time": "21:51:12.185868",
},
}
},
"outputter": "highstate",
"retcode": 0,
}
self.addCleanup(delattr, self, "data")
def test_default_output(self):
ret = highstate.output(self.data)
self.assertIn("Succeeded: 1 (changed=1)", ret)
self.assertIn("Failed: 0", ret)
self.assertIn("Success %: 100.0", ret)
self.assertIn("Failure %: 0.0", ret)
self.assertIn("Total states run: 1", ret)
self.assertIn(" file2", ret)