Skip to content
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

option to always generate and record diff data in ara (without displaying on stdout) #535

Open
rptaylor opened this issue Jan 9, 2024 · 8 comments

Comments

@rptaylor
Copy link

rptaylor commented Jan 9, 2024

What is the idea ?

Using --diff or ANSIBLE_DIFF_ALWAYS collects and stores diff data in Ara, but also prints it to stdout which may cause too much undesired visual clutter on screen for end users and make it difficult to quickly scan play output. However, it would be great to nevertheless collect and store diff data in ara for auditing purposes, where nobody has to see it unless they want to and go look for it. The use case for Ara is to collect, store, and present as much Ansible play information as possible in an organized way so it would be beneficial to have a way to always include diff data for that purpose, without also sending it to stdout.

According to ansible/ansible#82445 (comment) it should be possible for the ara callback plugin to have an option that records and stores diff data in ARA, without printing it to stdout.

The user should still be able to see the diff data on stdout if using --diff.

@flowerysong
Copy link
Contributor

That is not what that comment is suggesting. The suggestion is that you should write a custom stdout callback which suppresses the diff display, since you don't want to see it. ARA is not involved in this.

@dmsimard
Copy link
Contributor

Hi @rptaylor, thanks for the issue.

That is not what that comment is suggesting. The suggestion is that you should write a custom stdout callback which suppresses the diff display, since you don't want to see it. ARA is not involved in this.

This is correct. Thanks @flowerysong :)

The part that prints the diff to stdout lives in ansible(-core) here: https://github.com/ansible/ansible/blob/21247c828ea58c5900fef7f2e9277fe2183b6ce0/lib/ansible/plugins/callback/default.py#L221-L235

If you wanted to suppress the --diff outout to stdout, you could in theory create your own version of that default.py file linked above, put it somewhere with a name like without_diff.py and then take out that method that prints the diff.

This is a stdout callback which can be enabled by putting it's path in ANSIBLE_STDOUT_CALLBACK: https://docs.ansible.com/ansible/latest/reference_appendices/config.html#envvar-ANSIBLE_STDOUT_CALLBACK

ANSIBLE_CALLBACK_PLUGINS is used to enable the ara callback plugin but it (mostly) doesn't touch stdout.

Pragmatically speaking, I think we could make an argument that ansible(-core) could have a setting like ANSIBLE_DIFF_PRINT (next to the existing settings) which defaults to true but can be set to false to provide the functionality of allowing the diffs to make it to callback plugins while not printing to stdout.

I have been wanting to be able to do this myself because diffs often contain information like usernames, passwords and certificates so you would rather not see them being printed to console stdout in something like a jenkins or gitlab job.
The usage of no_log comes necessary but it comes at the cost of not knowing anything about what happened because it strips most of the information about the tasks.

I will ask about the use case upstream.

@flowerysong
Copy link
Contributor

You don't have to copy the plugin, just override the parts you want to change.

# -*- coding: utf-8 -*-
# Copyright (c) 2024 Paul Arthur
# GNU General Public License v3.0+ (see https://www.gnu.org/licenses/gpl-3.0.txt)
# SPDX-License-Identifier: GPL-3.0-or-later

from __future__ import (absolute_import, division, print_function)
__metaclass__ = type

DOCUMENTATION = '''
    author: "Paul Arthur (@flowerysong)"
    name: nodiff
    type: stdout
    short_description: default callback with no diff output
    description:
        - default callback with no diff output
    extends_documentation_fragment:
      - default_callback
      - result_format_callback
'''


from ansible.plugins.callback.default import CallbackModule as Default


class CallbackModule(Default):
    CALLBACK_VERSION = 2.0
    CALLBACK_TYPE = 'stdout'
    CALLBACK_NAME = 'flowerysong.test.nodiff'

    def _get_diff(self, diff):
        return ''
ec2-user@pandora testing $ ansible-playbook --diff --check test.yml

PLAY [localhost] ***************************************************************

TASK [copy] ********************************************************************
--- before
+++ after: /home/ec2-user/.ansible/tmp/ansible-local-37123034qyvb1y2/tmpgotc3awr
@@ -0,0 +1 @@
+just a simple test

changed: [localhost]
ec2-user@pandora testing $ ANSIBLE_STDOUT_CALLBACK=flowerysong.test.nodiff ansible-playbook --diff --check test.yml

PLAY [localhost] ***************************************************************

TASK [copy] ********************************************************************
changed: [localhost]

@dmsimard
Copy link
Contributor

That's a cleaner way to do it, good call :)

@hille721
Copy link
Contributor

I have a similar use case as @rptaylor now, I want to have the diff in ARA as this is so great, but I'm getting more and more annoyed from the much output I get when using ANSIBLE_DIFF_ALWAYS .

@flowerysong Thanks for showing how to easily adapt the default stdout callback, but this solves not the problem, as then --diff does not work anymore.
But it is a good point to start, I will look further into it and keep you updated.

@hille721
Copy link
Contributor

The user should still be able to see the diff data on stdout if using --diff.

ok, I checked different possibility, but I think it will be pretty hard (or even impossible) to enable this on plugin level without doing ansible-core changes.

@felixfontein
Copy link

After @dmsimard mentioned this problem to me yesterday I decided to create a small plugin, which coincides quite a lot with what @flowerysong proposed, except that I overwrote v2_on_file_diff and not _get_diff :) I've created a PR for community.general here: ansible-collections/community.general#7949

@simonLeary42
Copy link

I've been working on a stdout callback plugin which is able to display large amounts of diff data without overwhelming the user. Rather than printing every result instantly it stores them until the end of the task, and then prints each unique diff with a list of the hosts which produced it. As a sort of progress bar it tallies up the statuses of all completed runners and displays them on one line like running=X ok=Y failed=Z\r. It also pipes the diff through diffr to do word highlighting. It also condenses host lists using nodeset, so host1,host2,host3 would instead be host[1-3]. Both diffr and nodeset are optional, if they aren't available the plugin will fall back on more vanilla functionality.

I have a plugin_utils called dedupe_callbackwhich exposes a python api similar to v2_task_on_completed and friends, and a stdout callback called clush (inspired by Clustershell) with the features described above using that api.

https://gitlab.rc.umass.edu/unity/ansible-collections/general/-/blob/master/plugins/plugin_utils/dedupe_callback.py?ref_type=heads

https://gitlab.rc.umass.edu/unity/ansible-collections/general/-/blob/master/plugins/callback/clush.py?ref_type=heads

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants