-
Notifications
You must be signed in to change notification settings - Fork 23.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
better cleanup on task results display #27175
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,7 +5,12 @@ | |
from __future__ import (absolute_import, division, print_function) | ||
__metaclass__ = type | ||
|
||
from copy import deepcopy | ||
|
||
from ansible.parsing.dataloader import DataLoader | ||
from ansible.vars.manager import strip_internal_keys | ||
|
||
_IGNORE = ('changed', 'failed', 'skipped') | ||
|
||
|
||
class TaskResult: | ||
|
@@ -69,3 +74,32 @@ def _check_key(self, key): | |
if isinstance(res, dict): | ||
flag |= res.get(key, False) | ||
return flag | ||
|
||
def clean_copy(self): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [note for potential future changes that doesnt need to be addressed now for this PR] We have a couple of places where we do some variant of 'copy a dict, but then remove certain keys'. Might be worthwhile to generalize and add to utils and use. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should end up doing more than that, also creating mock task/play to avoid direct refs .. but that should not preclude such function |
||
|
||
''' returns 'clean' taskresult object ''' | ||
|
||
# FIXME: clean task_fields, _task and _host copies | ||
result = TaskResult(self._host, self._task, {}, self._task_fields) | ||
|
||
# statuses are already reflected on the event type | ||
if result._task and result._task.action in ['debug']: | ||
# debug is verbose by default to display vars, no need to add invocation | ||
ignore = _IGNORE + ('invocation',) | ||
else: | ||
ignore = _IGNORE | ||
|
||
if self._result.get('_ansible_no_log', False): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this is all for dealing with a TaskResult._result, move the _result processing code to it's own method and call from here? def _clean_result(self, result, ignore):
<...> It could even be staticmethod or module scope method def clean_result_dict(result_dict, ignore):
<..>
return result_dict so, clean_result() could: if self._result:
result._result = clean_result(result._result, ignore)
return result There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. self._result is the start, planning on also cleaning up task and play |
||
result._result = {"censored": "the output has been hidden due to the fact that 'no_log: true' was specified for this result"} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this could return here? Then the next stanza doesn't need the extra indent level There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, but i thought the preferred style was the 'single return' which we follow in most places, both do exact same thing. |
||
elif self._result: | ||
result._result = deepcopy(self._result) | ||
|
||
# actualy remove | ||
for remove_key in ignore: | ||
if remove_key in result._result: | ||
del result._result[remove_key] | ||
|
||
# remove almost ALL internal keys, keep ones relevant to callback | ||
strip_internal_keys(result._result, exceptions=('_ansible_verbose_always', '_ansible_item_label', '_ansible_no_log')) | ||
|
||
return result |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect this might break more esoteric uses of callbacks (if something is relying on the original reference...).
But I think that is ok since that isnt really something we can (or should) guarantee.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
callbacks should not be manipulating the 'live objects', it can create issues and alter play flow in 'magical' ways the user would not understand/see/be able to audit.
In any case we are moving this here to avoid doing it in the callback itself should not worry about security nor disclosures.