mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 00:55:19 +00:00
Merge pull request #46022 from bloomberg/nested-orch-highstate
salt.outputter.highstate: recursion for orch
This commit is contained in:
commit
4e44fee506
@ -105,6 +105,7 @@ Example output with no special settings in configuration files:
|
||||
# Import python libs
|
||||
from __future__ import absolute_import, print_function, unicode_literals
|
||||
import pprint
|
||||
import re
|
||||
import textwrap
|
||||
|
||||
# Import salt libs
|
||||
@ -141,8 +142,9 @@ def output(data, **kwargs): # pylint: disable=unused-argument
|
||||
if 'data' in data:
|
||||
data = data.pop('data')
|
||||
|
||||
indent_level = kwargs.get('indent_level', 1)
|
||||
ret = [
|
||||
_format_host(host, hostdata)[0]
|
||||
_format_host(host, hostdata, indent_level=indent_level)[0]
|
||||
for host, hostdata in six.iteritems(data)
|
||||
]
|
||||
if ret:
|
||||
@ -155,7 +157,11 @@ def output(data, **kwargs): # pylint: disable=unused-argument
|
||||
return ''
|
||||
|
||||
|
||||
def _format_host(host, data):
|
||||
def _format_host(host, data, indent_level=1):
|
||||
'''
|
||||
Main highstate formatter. can be called recursively if a nested highstate
|
||||
contains other highstates (ie in an orchestration)
|
||||
'''
|
||||
host = salt.utils.data.decode(host)
|
||||
|
||||
colors = salt.utils.color.get_colors(
|
||||
@ -217,15 +223,17 @@ def _format_host(host, data):
|
||||
try:
|
||||
rdurations.append(float(rduration))
|
||||
except ValueError:
|
||||
log.error('Cannot parse a float from duration {0}'
|
||||
.format(ret.get('duration', 0)))
|
||||
log.error('Cannot parse a float from duration %s', ret.get('duration', 0))
|
||||
|
||||
tcolor = colors['GREEN']
|
||||
orchestration = ret.get('__orchestration__', False)
|
||||
schanged, ctext = _format_changes(ret['changes'], orchestration)
|
||||
if not ctext and 'pchanges' in ret:
|
||||
schanged, ctext = _format_changes(ret['pchanges'], orchestration)
|
||||
nchanges += 1 if schanged else 0
|
||||
if ret.get('name') in ['state.orch', 'state.orchestrate', 'state.sls']:
|
||||
nested = output(ret['changes']['return'], indent_level=indent_level+1)
|
||||
ctext = re.sub('^', ' ' * 14 * indent_level, '\n'+nested, flags=re.MULTILINE)
|
||||
schanged = True
|
||||
nchanges += 1
|
||||
else:
|
||||
schanged, ctext = _format_changes(ret['changes'])
|
||||
nchanges += 1 if schanged else 0
|
||||
|
||||
# Skip this state if it was successful & diff output was requested
|
||||
if __opts__.get('state_output_diff', False) and \
|
||||
|
@ -107,3 +107,93 @@ class JsonTestCase(TestCase, LoaderModuleMockMixin):
|
||||
self.assertIn('Succeeded: 1 (changed=1)', ret)
|
||||
self.assertIn('Failed: 0', ret)
|
||||
self.assertIn('Total states run: 1', ret)
|
||||
|
||||
|
||||
# this should all pass the above tests
|
||||
class JsonNestedTestCase(TestCase, LoaderModuleMockMixin):
|
||||
'''
|
||||
Test cases for nested salt.output.highstate (ie orchestrations calling other orchs)
|
||||
'''
|
||||
def setup_loader_modules(self):
|
||||
return {
|
||||
highstate: {
|
||||
'__opts__': {
|
||||
'extension_modules': '',
|
||||
'color': False,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
self.data = {
|
||||
'outputter': 'highstate',
|
||||
'data': {
|
||||
'local_master': {
|
||||
'salt_|-nested_|-state.orchestrate_|-runner': {
|
||||
'comment': 'Runner function \'state.orchestrate\' executed.',
|
||||
'name': 'state.orchestrate',
|
||||
'__orchestration__': True,
|
||||
'start_time': '09:22:53.158742',
|
||||
'result': True,
|
||||
'duration': 980.694,
|
||||
'__run_num__': 0,
|
||||
'__jid__': '20180326092253538853',
|
||||
'__sls__': 'orch.test.nested',
|
||||
'changes': {
|
||||
'return': {
|
||||
'outputter': 'highstate',
|
||||
'data': {
|
||||
'local_master': {
|
||||
'test_|-always-passes-with-changes_|-oinaosf_|-succeed_with_changes': {
|
||||
'comment': 'Success!',
|
||||
'name': 'oinaosf',
|
||||
'start_time': '09:22:54.128415',
|
||||
'result': True,
|
||||
'duration': 0.437,
|
||||
'__run_num__': 0,
|
||||
'__sls__': 'orch.test.changes',
|
||||
'changes': {
|
||||
'testing': {
|
||||
'new': 'Something pretended to change',
|
||||
'old': 'Unchanged'
|
||||
}
|
||||
},
|
||||
'__id__': 'always-passes-with-changes'
|
||||
},
|
||||
'test_|-always-passes_|-fasdfasddfasdfoo_|-succeed_without_changes': {
|
||||
'comment': 'Success!',
|
||||
'name': 'fasdfasddfasdfoo',
|
||||
'start_time': '09:22:54.128986',
|
||||
'result': True,
|
||||
'duration': 0.25,
|
||||
'__run_num__': 1,
|
||||
'__sls__': 'orch.test.changes',
|
||||
'changes': {},
|
||||
'__id__': 'always-passes'
|
||||
}
|
||||
}
|
||||
},
|
||||
'retcode': 0
|
||||
}
|
||||
},
|
||||
'__id__': 'nested'
|
||||
}
|
||||
}
|
||||
},
|
||||
'retcode': 0
|
||||
}
|
||||
|
||||
self.addCleanup(delattr, self, 'data')
|
||||
|
||||
def test_nested_output(self):
|
||||
ret = highstate.output(self.data)
|
||||
self.assertIn('Succeeded: 1 (changed=1)', ret)
|
||||
self.assertIn('Failed: 0', ret)
|
||||
self.assertIn('Total states run: 1', ret)
|
||||
|
||||
# the whitespace is relevant in this case, it is testing that it is nested
|
||||
self.assertIn(' ID: always-passes-with-changes', ret)
|
||||
self.assertIn(' Started: 09:22:54.128415', ret)
|
||||
self.assertIn(' Succeeded: 2 (changed=1)', ret)
|
||||
self.assertIn(' Failed: 0', ret)
|
||||
self.assertIn(' Total states run: 2', ret)
|
||||
|
Loading…
Reference in New Issue
Block a user