github.com/jlmeeker/kismatic@v1.10.1-0.20180612190640-57f9005a1f1a/ansible/callback/json_lines.py (about) 1 from __future__ import absolute_import 2 from ansible.plugins.callback import CallbackBase 3 from ansible import constants as C 4 5 import json 6 import pprint 7 from os.path import basename 8 import os 9 10 # JSON Lines STDOUT callback module for Ansible. 11 # 12 # This callback module prints Ansible events out to STDOUT as JSON Lines. 13 # The event consists of a type and data. The data has a different structure 14 # depending on the event type. 15 class CallbackModule(CallbackBase): 16 CALLBACK_VERSION = 2.0 17 CALLBACK_TYPE = 'notification' 18 CALLBACK_NAME = 'json-lines' 19 20 # The following is a list of supported event types 21 PLAYBOOK_START = "PLAYBOOK_START" 22 PLAYBOOK_END = "PLAYBOOK_END" 23 PLAY_START = "PLAY_START" 24 TASK_START = "TASK_START" 25 RUNNER_OK = "RUNNER_OK" 26 RUNNER_FAILED = "RUNNER_FAILED" 27 RUNNER_SKIPPED = "RUNNER_SKIPPED" 28 RUNNER_UNREACHABLE = "RUNNER_UNREACHABLE" 29 CLEANUP_TASK_START = "CLEANUP_TASK_START" 30 HANDLER_TASK_START = "HANDLER_TASK_START" 31 RUNNER_ITEM_OK = "RUNNER_ITEM_OK" 32 RUNNER_ITEM_FAILED = "RUNNER_ITEM_FAILED" 33 RUNNER_ITEM_SKIPPED = "RUNNER_ITEM_SKIPPED" 34 RUNNER_ITEM_RETRY = "RUNNER_ITEM_RETRY" 35 36 named_pipe = None 37 38 def _new_event(self, eventType, eventData): 39 return { 40 'eventType': eventType, 41 'eventData': eventData 42 } 43 44 def _new_task(self, task): 45 return { 46 'name':task.name, 47 'id': str(task._uuid) 48 } 49 50 def _print_event(self, event): 51 self.named_pipe.write(json.dumps(event, sort_keys = False)) 52 self.named_pipe.write("\n") 53 self.named_pipe.flush() 54 55 def __init__(self): 56 named_pipe_file = os.environ["ANSIBLE_JSON_LINES_PIPE"] 57 self.named_pipe = open(named_pipe_file, 'w', 0) 58 super(CallbackModule, self).__init__() 59 60 # This gets called when the playbook ends. Close the pipe. 61 def v2_playbook_on_stats(self, stats): 62 self._on_runner_result(self.PLAYBOOK_END, None) 63 self.named_pipe.close() 64 65 # def v2_on_any(self, *args, **kwargs): 66 # self.on_any(args, kwargs) 67 68 # def v2_runner_on_no_hosts(self, task): 69 # self.runner_on_no_hosts() 70 71 # def v2_runner_on_async_poll(self, result): 72 # host = result._host.get_name() 73 # jid = result._result.get('ansible_job_id') 74 # #FIXME, get real clock 75 # clock = 0 76 # self.runner_on_async_poll(host, result._result, jid, clock) 77 78 # def v2_runner_on_async_ok(self, result): 79 # host = result._host.get_name() 80 # jid = result._result.get('ansible_job_id') 81 # self.runner_on_async_ok(host, result._result, jid) 82 83 # def v2_runner_on_async_failed(self, result): 84 # host = result._host.get_name() 85 # jid = result._result.get('ansible_job_id') 86 # self.runner_on_async_failed(host, result._result, jid) 87 88 # def v2_runner_on_file_diff(self, result, diff): 89 # print "v2_runner_on_file_diff" 90 91 def v2_playbook_on_start(self, playbook): 92 data = { 93 'name': basename(playbook._file_name), 94 'count': len(playbook._entries) 95 } 96 e = self._new_event(self.PLAYBOOK_START, data) 97 self._print_event(e) 98 99 # def v2_playbook_on_notify(self, result, handler): 100 # host = result._host.get_name() 101 # self.playbook_on_notify(host, handler) 102 103 # def v2_playbook_on_no_hosts_matched(self): 104 # self.playbook_on_no_hosts_matched() 105 106 # def v2_playbook_on_no_hosts_remaining(self): 107 # self.playbook_on_no_hosts_remaining() 108 109 def v2_playbook_on_task_start(self, task, is_conditional): 110 event_data = self._new_task(task) 111 e = self._new_event(self.TASK_START, event_data) 112 self._print_event(e) 113 114 115 def _on_runner_result(self, event_type, result): 116 event_data = {} 117 if result is not None: 118 event_data = { 119 'host': result._host.name, 120 'result': result._result, 121 'ignoreErrors': result._task.ignore_errors 122 } 123 e = self._new_event(event_type, event_data) 124 self._print_event(e) 125 126 def v2_runner_on_failed(self, result, ignore_errors=False): 127 self._on_runner_result(self.RUNNER_FAILED, result) 128 129 def v2_runner_on_ok(self, result): 130 self._on_runner_result(self.RUNNER_OK, result) 131 132 def v2_runner_on_skipped(self, result): 133 self._on_runner_result(self.RUNNER_SKIPPED, result) 134 135 def v2_runner_on_unreachable(self, result): 136 self._on_runner_result(self.RUNNER_UNREACHABLE, result) 137 138 def v2_playbook_on_cleanup_task_start(self, task): 139 event_data = self._new_task(task) 140 e = self._new_event(self.CLEANUP_TASK_START, event_data) 141 self._print_event(e) 142 143 def v2_playbook_on_handler_task_start(self, task): 144 event_data = self._new_task(task) 145 e = self._new_event(self.HANDLER_TASK_START, event_data) 146 self._print_event(e) 147 148 # def v2_playbook_on_vars_prompt(self, varname, private=True, prompt=None, encrypt=None, confirm=False, salt_size=None, salt=None, default=None): 149 # self.playbook_on_vars_prompt(varname, private, prompt, encrypt, confirm, salt_size, salt, default) 150 151 # def v2_playbook_on_setup(self): 152 # self.playbook_on_setup() 153 154 # def v2_playbook_on_import_for_host(self, result, imported_file): 155 # host = result._host.get_name() 156 # self.playbook_on_import_for_host(host, imported_file) 157 158 # def v2_playbook_on_not_import_for_host(self, result, missing_file): 159 # host = result._host.get_name() 160 # self.playbook_on_not_import_for_host(host, missing_file) 161 162 def v2_playbook_on_play_start(self, play): 163 data = { 164 'name': play.name 165 } 166 e = self._new_event(self.PLAY_START, data) 167 self._print_event(e) 168 169 170 # def v2_on_file_diff(self, result): 171 # if 'diff' in result._result: 172 # host = result._host.get_name() 173 # self.on_file_diff(host, result._result['diff']) 174 175 # def v2_playbook_on_include(self, included_file): 176 # print "v2_playbook_on_include" 177 178 def v2_runner_item_on_ok(self, result): 179 self._on_runner_result(self.RUNNER_ITEM_OK, result) 180 181 def v2_runner_item_on_failed(self, result): 182 self._on_runner_result(self.RUNNER_ITEM_FAILED, result) 183 184 def v2_runner_item_on_skipped(self, result): 185 self._on_runner_result(self.RUNNER_ITEM_SKIPPED, result) 186 187 def v2_runner_retry(self, result): 188 self._on_runner_result(self.RUNNER_ITEM_RETRY, result)