# ~*~ coding: utf-8 ~*~ from collections import defaultdict from ansible.plugins.callback import CallbackBase class CommandResultCallback(CallbackBase): def __init__(self, display=None): self.result_q = dict(contacted={}, dark={}) super(CommandResultCallback, self).__init__(display) def gather_result(self, n, res): self.result_q[n][res._host.name] = {} self.result_q[n][res._host.name]['cmd'] = res._result.get('cmd') self.result_q[n][res._host.name]['stderr'] = res._result.get('stderr') self.result_q[n][res._host.name]['stdout'] = res._result.get('stdout') self.result_q[n][res._host.name]['rc'] = res._result.get('rc') def v2_runner_on_ok(self, result): self.gather_result("contacted", result) def v2_runner_on_failed(self, result, ignore_errors=False): self.gather_result("dark", result) def v2_runner_on_unreachable(self, result): self.gather_result("dark", result) def v2_runner_on_skipped(self, result): self.gather_result("dark", result) class AdHocResultCallback(CallbackBase): """ AdHoc result Callback """ def __init__(self, display=None): self.result_q = dict(contacted={}, dark={}) super(AdHocResultCallback, self).__init__(display) def gather_result(self, n, res): if res._host.name in self.result_q[n]: self.result_q[n][res._host.name].append(res._result) else: self.result_q[n][res._host.name] = [res._result] def v2_runner_on_ok(self, result): self.gather_result("contacted", result) def v2_runner_on_failed(self, result, ignore_errors=False): self.gather_result("dark", result) def v2_runner_on_unreachable(self, result): self.gather_result("dark", result) def v2_runner_on_skipped(self, result): self.gather_result("dark", result) def v2_playbook_on_task_start(self, task, is_conditional): pass def v2_playbook_on_play_start(self, play): pass class PlaybookResultCallBack(CallbackBase): """ Custom callback model for handlering the output data of execute playbook file, Base on the build-in callback plugins of ansible which named `json`. """ CALLBACK_VERSION = 2.0 CALLBACK_TYPE = 'stdout' CALLBACK_NAME = 'Dict' def __init__(self, display=None): super(PlaybookResultCallBack, self).__init__(display) self.results = [] self.output = "" self.item_results = {} # {"host": []} def _new_play(self, play): return { 'play': { 'name': play.name, 'id': str(play._uuid) }, 'tasks': [] } def _new_task(self, task): return { 'task': { 'name': task.get_name(), }, 'hosts': {} } def v2_playbook_on_no_hosts_matched(self): self.output = "skipping: No match hosts." def v2_playbook_on_no_hosts_remaining(self): pass def v2_playbook_on_task_start(self, task, is_conditional): self.results[-1]['tasks'].append(self._new_task(task)) def v2_playbook_on_play_start(self, play): self.results.append(self._new_play(play)) def v2_playbook_on_stats(self, stats): hosts = sorted(stats.processed.keys()) summary = {} for h in hosts: s = stats.summarize(h) summary[h] = s if self.output: pass else: self.output = { 'plays': self.results, 'stats': summary } def gather_result(self, res): if res._task.loop and "results" in res._result and res._host.name in self.item_results: res._result.update({"results": self.item_results[res._host.name]}) del self.item_results[res._host.name] self.results[-1]['tasks'][-1]['hosts'][res._host.name] = res._result def v2_runner_on_ok(self, res, **kwargs): if "ansible_facts" in res._result: del res._result["ansible_facts"] self.gather_result(res) def v2_runner_on_failed(self, res, **kwargs): self.gather_result(res) def v2_runner_on_unreachable(self, res, **kwargs): self.gather_result(res) def v2_runner_on_skipped(self, res, **kwargs): self.gather_result(res) def gather_item_result(self, res): self.item_results.setdefault(res._host.name, []).append(res._result) def v2_runner_item_on_ok(self, res): self.gather_item_result(res) def v2_runner_item_on_failed(self, res): self.gather_item_result(res) def v2_runner_item_on_skipped(self, res): self.gather_item_result(res)