Skip to content

Instantly share code, notes, and snippets.

@sivel
Last active July 29, 2020 17:19
Show Gist options
  • Save sivel/eaa83e2b1c36719359e0671afa8cd039 to your computer and use it in GitHub Desktop.
Save sivel/eaa83e2b1c36719359e0671afa8cd039 to your computer and use it in GitHub Desktop.
Ansible Callback to aid in replicating set_stats workflow behavior in Tower

dump_stats Ansible callback plugin

This callback plugin can aid in replicating the set_stats workflow behavior in Tower

It allows you to dump the stats set with set_stats to a file, and then use that file with --extra-vars in subsequent ansible-playbook calls.

Usage

  1. Download dump_stats.py file to a callback_plugins directory relative to your playbook
  2. Run ansible-playbook with ANSIBLE_CALLBACK_WHITELIST=dump_stats
  3. Call the 2nd playbook with --extra-vars @stats.json

The output file can be changed using DUMP_STATS_OUTPUT env var, or output under a [dump_stats_callback] section in ansible.cfg

Example layout

├── callback_plugins
│   └── dump_stats.py
├── playbook1.yml
└── playbook2.yml

Example execution

$ ANSIBLE_CALLBACK_WHITELIST=dump_stats DUMP_STATS_OUTPUT=my_stats.json ansible-playbook playbook1.yml
PLAY [localhost] *****************************************************************************************************************************************************************************************************************************

TASK [set_stats] *****************************************************************************************************************************************************************************************************************************
ok: [localhost]

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

$ ansible-playbook --extra-vars @my_stats.json playbook2.yml
PLAY [localhost] *****************************************************************************************************************************************************************************************************************************

TASK [debug] *********************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "foo": "bar"
}

PLAY RECAP ***********************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
# (c) 2020 Matt Martz <[email protected]>
# GNU General Public License v3.0+
# (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)
# Make coding more python3-ish
from __future__ import (absolute_import, division, print_function)
__metaclass__ = type
DOCUMENTATION = '''
callback: dump_stats
short_description: Callback to dump to stats from set_stat to a JSON file
description:
- Dumps the stats from set_stat to a JSON file that can be fed to subsequent
ansible-playbook calls using --extra-vars
type: aggregate
options:
output:
description: Output path to JSON file, defaults to stats.json in the CWD
default: stats.json
env:
- name: DUMP_STATS_OUTPUT
ini:
- key: output
section: dump_stats_callback
type: str
'''
import json
import os
from ansible.errors import AnsibleError
from ansible.plugins.callback import CallbackBase
class CallbackModule(CallbackBase):
CALLBACK_VERSION = 2.0
CALLBACK_TYPE = 'aggregate'
CALLBACK_NAME = 'dump_stats'
CALLBACK_NEEDS_WHITELIST = True
def set_options(self, *args, **kwargs):
super(CallbackModule, self).set_options(*args, **kwargs)
self._output = os.path.abspath(self.get_option('output'))
output_dir = os.path.dirname(self._output)
if not os.path.isdir(output_dir):
try:
os.path.makedirs(output_dir, mode=0o755)
except Exception:
pass
def v2_playbook_on_stats(self, stats):
with open(self._output, 'w+') as f:
json.dump(
stats.custom.get('_run', {}) if hasattr(stats, 'custom') else {},
f
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment