By popular request, make the no_log attribute also censor tasks from callbacks.

This commit is contained in:
Michael DeHaan 2014-08-12 13:35:38 -04:00
parent a04efa2d84
commit 99c39b1ff3
6 changed files with 61 additions and 3 deletions

View file

@ -11,6 +11,7 @@ New core features:
* new 'ansible_version' variable available contains a dictionary of version info * new 'ansible_version' variable available contains a dictionary of version info
* For ec2 dynamic inventory, ec2.ini can has various new configuration options * For ec2 dynamic inventory, ec2.ini can has various new configuration options
* 'ansible vault view filename.yml' opens filename.yml decrypted in a pager. * 'ansible vault view filename.yml' opens filename.yml decrypted in a pager.
* no_log parameter now surpressess data from callbacks/output as well as syslog
New Modules: New Modules:

View file

@ -250,6 +250,22 @@ If you would like to keep secret data in your Ansible content and still share it
.. _i_dont_see_my_question: .. _i_dont_see_my_question:
In Ansible 1.8 and later, if you have a task that you don't want to show the results or command given to it when using -v (verbose) mode, the following task or playbook attribute can be useful::
- name: secret task
shell: /usr/bin/do_something --value={{ secret_value }}
no_log: True
This can be used to keep verbose output but hide sensitive information from others who would otherwise like to be able to see the output.
The no_log attribute can also apply to an entire play::
- hosts: all
no_log: True
Though this will make the play somewhat difficult to debug. It's recommended that this
be applied to single tasks only, once a playbook is completed.
I don't see my question here I don't see my question here
++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++

View file

@ -126,8 +126,9 @@ Also note that host key checking in paramiko mode is reasonably slow, therefore
.. _a_note_about_logging: .. _a_note_about_logging:
Ansible will log some information about module arguments on the remote system in the remote syslog. To enable basic Ansible will log some information about module arguments on the remote system in the remote syslog, unless a task or play is marked with a "no_log: True" attribute, explained later.
logging on the control machine see :doc:`intro_configuration` document and set the 'log_path' configuration file setting. Enterprise users may also be interested in :doc:`tower`. Tower provides a very robust database logging feature where it is possible to drill down and see history based on hosts, projects, and particular inventories over time -- explorable both graphically and through a REST API.
To enable basic logging on the control machine see :doc:`intro_configuration` document and set the 'log_path' configuration file setting. Enterprise users may also be interested in :doc:`tower`. Tower provides a very robust database logging feature where it is possible to drill down and see history based on hosts, projects, and particular inventories over time -- explorable both graphically and through a REST API.
.. seealso:: .. seealso::

View file

@ -956,12 +956,17 @@ class Runner(object):
if failed_when is not None and 'skipped' not in data: if failed_when is not None and 'skipped' not in data:
data['failed_when_result'] = data['failed'] = utils.check_conditional(failed_when, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars) data['failed_when_result'] = data['failed'] = utils.check_conditional(failed_when, self.basedir, inject, fail_on_undefined=self.error_on_undefined_vars)
if is_chained: if is_chained:
# no callbacks # no callbacks
return result return result
if 'skipped' in data: if 'skipped' in data:
self.callbacks.on_skipped(host, inject.get('item',None)) self.callbacks.on_skipped(host, inject.get('item',None))
elif not result.is_successful():
if self.no_log:
data = utils.censor_unlogged_data(data)
if not result.is_successful():
ignore_errors = self.module_vars.get('ignore_errors', False) ignore_errors = self.module_vars.get('ignore_errors', False)
self.callbacks.on_failed(host, data, ignore_errors) self.callbacks.on_failed(host, data, ignore_errors)
else: else:

View file

@ -1436,3 +1436,19 @@ def update_hash(hash, key, new_value):
value = hash.get(key, {}) value = hash.get(key, {})
value.update(new_value) value.update(new_value)
hash[key] = value hash[key] = value
def censor_unlogged_data(data):
'''
used when the no_log: True attribute is passed to a task to keep data from a callback.
NOT intended to prevent variable registration, but only things from showing up on
screen
'''
new_data = {}
for (x,y) in data.iteritems():
if x in [ 'skipped', 'changed', 'failed', 'rc' ]:
new_data[x] = y
new_data['censored'] = 'results hidden due to no_log parameter'
return new_data

View file

@ -759,3 +759,22 @@ class TestUtils(unittest.TestCase):
) )
def test_censor_unlogged_data(self):
''' used by the no_log attribute '''
input = dict(
password='sekrit',
rc=12,
failed=True,
changed=False,
skipped=True,
msg='moo',
)
data = ansible.utils.censor_unlogged_data(input)
assert 'password' not in data
assert 'rc' in data
assert 'failed' in data
assert 'changed' in data
assert 'skipped' in data
assert 'msg' not in data
assert data['censored'] == 'results hidden due to no_log parameter'