diff --git a/CHANGELOG.md b/CHANGELOG.md index 63771f82e54..f8818916261 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ New core features: * new 'ansible_version' variable available contains a dictionary of version info * For ec2 dynamic inventory, ec2.ini can has various new configuration options * '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: diff --git a/docsite/rst/faq.rst b/docsite/rst/faq.rst index dff789c08f9..6c0287ae51c 100644 --- a/docsite/rst/faq.rst +++ b/docsite/rst/faq.rst @@ -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: +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 ++++++++++++++++++++++++++++ diff --git a/docsite/rst/intro_getting_started.rst b/docsite/rst/intro_getting_started.rst index b44bec65651..67136036479 100644 --- a/docsite/rst/intro_getting_started.rst +++ b/docsite/rst/intro_getting_started.rst @@ -126,8 +126,9 @@ Also note that host key checking in paramiko mode is reasonably slow, therefore .. _a_note_about_logging: -Ansible will log some information about module arguments on the remote system in the remote syslog. 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. +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. + +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:: diff --git a/lib/ansible/runner/__init__.py b/lib/ansible/runner/__init__.py index e79a22f0a5a..6e7955d3792 100644 --- a/lib/ansible/runner/__init__.py +++ b/lib/ansible/runner/__init__.py @@ -956,12 +956,17 @@ class Runner(object): 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) + if is_chained: # no callbacks return result if 'skipped' in data: 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) self.callbacks.on_failed(host, data, ignore_errors) else: diff --git a/lib/ansible/utils/__init__.py b/lib/ansible/utils/__init__.py index 0c504011a8d..8a8ebda7b40 100644 --- a/lib/ansible/utils/__init__.py +++ b/lib/ansible/utils/__init__.py @@ -1436,3 +1436,19 @@ def update_hash(hash, key, new_value): value = hash.get(key, {}) value.update(new_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 + + + diff --git a/test/units/TestUtils.py b/test/units/TestUtils.py index cc3e6e354e9..feaab36bbb0 100644 --- a/test/units/TestUtils.py +++ b/test/units/TestUtils.py @@ -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' +