|
|
|
@ -2,16 +2,18 @@ import os
|
|
|
|
|
from collections import defaultdict |
|
|
|
|
from functools import reduce |
|
|
|
|
|
|
|
|
|
from django.conf import settings |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DefaultCallback: |
|
|
|
|
STATUS_MAPPER = { |
|
|
|
|
'successful': 'success', |
|
|
|
|
'failure': 'failed', |
|
|
|
|
'failed': 'failed', |
|
|
|
|
'running': 'running', |
|
|
|
|
'pending': 'pending', |
|
|
|
|
'timeout': 'timeout', |
|
|
|
|
'unknown': 'unknown' |
|
|
|
|
"successful": "success", |
|
|
|
|
"failure": "failed", |
|
|
|
|
"failed": "failed", |
|
|
|
|
"running": "running", |
|
|
|
|
"pending": "pending", |
|
|
|
|
"timeout": "timeout", |
|
|
|
|
"unknown": "unknown", |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
def __init__(self): |
|
|
|
@ -28,7 +30,7 @@ class DefaultCallback:
|
|
|
|
|
dark={}, |
|
|
|
|
skipped=[], |
|
|
|
|
) |
|
|
|
|
self.status = 'running' |
|
|
|
|
self.status = "running" |
|
|
|
|
self.finished = False |
|
|
|
|
self.local_pid = 0 |
|
|
|
|
self.private_data_dir = None |
|
|
|
@ -42,61 +44,63 @@ class DefaultCallback:
|
|
|
|
|
return results |
|
|
|
|
|
|
|
|
|
def is_success(self): |
|
|
|
|
return self.status != 'success' |
|
|
|
|
return self.status != "success" |
|
|
|
|
|
|
|
|
|
def event_handler(self, data, **kwargs): |
|
|
|
|
event = data.get('event', None) |
|
|
|
|
event = data.get("event", None) |
|
|
|
|
if not event: |
|
|
|
|
return |
|
|
|
|
|
|
|
|
|
pid = data.get('pid', None) |
|
|
|
|
pid = data.get("pid", None) |
|
|
|
|
if pid: |
|
|
|
|
self.write_pid(pid) |
|
|
|
|
|
|
|
|
|
event_data = data.get('event_data', {}) |
|
|
|
|
host = event_data.get('remote_addr', '') |
|
|
|
|
task = event_data.get('task', '') |
|
|
|
|
res = event_data.get('res', {}) |
|
|
|
|
event_data = data.get("event_data", {}) |
|
|
|
|
host = event_data.get("remote_addr", "") |
|
|
|
|
task = event_data.get("task", "") |
|
|
|
|
res = event_data.get("res", {}) |
|
|
|
|
handler = getattr(self, event, self.on_any) |
|
|
|
|
handler(event_data, host=host, task=task, res=res) |
|
|
|
|
|
|
|
|
|
def runner_on_ok(self, event_data, host=None, task=None, res=None): |
|
|
|
|
detail = { |
|
|
|
|
'action': event_data.get('task_action', ''), |
|
|
|
|
'res': res, |
|
|
|
|
'rc': res.get('rc', 0), |
|
|
|
|
'stdout': res.get('stdout', ''), |
|
|
|
|
"action": event_data.get("task_action", ""), |
|
|
|
|
"res": res, |
|
|
|
|
"rc": res.get("rc", 0), |
|
|
|
|
"stdout": res.get("stdout", ""), |
|
|
|
|
} |
|
|
|
|
self.result['ok'][host][task] = detail |
|
|
|
|
self.result["ok"][host][task] = detail |
|
|
|
|
|
|
|
|
|
def runner_on_skipped(self, event_data, host=None, task=None, **kwargs): |
|
|
|
|
detail = { |
|
|
|
|
'action': event_data.get('task_action', ''), |
|
|
|
|
'res': {}, |
|
|
|
|
'rc': 0, |
|
|
|
|
"action": event_data.get("task_action", ""), |
|
|
|
|
"res": {}, |
|
|
|
|
"rc": 0, |
|
|
|
|
} |
|
|
|
|
self.result['skipped'][host][task] = detail |
|
|
|
|
self.result["skipped"][host][task] = detail |
|
|
|
|
|
|
|
|
|
def runner_on_failed(self, event_data, host=None, task=None, res=None, **kwargs): |
|
|
|
|
detail = { |
|
|
|
|
'action': event_data.get('task_action', ''), |
|
|
|
|
'res': res, |
|
|
|
|
'rc': res.get('rc', 0), |
|
|
|
|
'stdout': res.get('stdout', ''), |
|
|
|
|
'stderr': ';'.join([res.get('stderr', ''), res.get('msg', '')]).strip(';') |
|
|
|
|
"action": event_data.get("task_action", ""), |
|
|
|
|
"res": res, |
|
|
|
|
"rc": res.get("rc", 0), |
|
|
|
|
"stdout": res.get("stdout", ""), |
|
|
|
|
"stderr": ";".join([res.get("stderr", ""), res.get("msg", "")]).strip(";"), |
|
|
|
|
} |
|
|
|
|
ignore_errors = event_data.get('ignore_errors', False) |
|
|
|
|
error_key = 'ignored' if ignore_errors else 'failures' |
|
|
|
|
ignore_errors = event_data.get("ignore_errors", False) |
|
|
|
|
error_key = "ignored" if ignore_errors else "failures" |
|
|
|
|
self.result[error_key][host][task] = detail |
|
|
|
|
|
|
|
|
|
def runner_on_unreachable(self, event_data, host=None, task=None, res=None, **kwargs): |
|
|
|
|
def runner_on_unreachable( |
|
|
|
|
self, event_data, host=None, task=None, res=None, **kwargs |
|
|
|
|
): |
|
|
|
|
detail = { |
|
|
|
|
'action': event_data.get('task_action', ''), |
|
|
|
|
'res': res, |
|
|
|
|
'rc': 255, |
|
|
|
|
'stderr': ';'.join([res.get('stderr', ''), res.get('msg', '')]).strip(';') |
|
|
|
|
"action": event_data.get("task_action", ""), |
|
|
|
|
"res": res, |
|
|
|
|
"rc": 255, |
|
|
|
|
"stderr": ";".join([res.get("stderr", ""), res.get("msg", "")]).strip(";"), |
|
|
|
|
} |
|
|
|
|
self.result['dark'][host][task] = detail |
|
|
|
|
self.result["dark"][host][task] = detail |
|
|
|
|
|
|
|
|
|
def runner_on_start(self, event_data, **kwargs): |
|
|
|
|
pass |
|
|
|
@ -117,21 +121,26 @@ class DefaultCallback:
|
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
def playbook_on_stats(self, event_data, **kwargs): |
|
|
|
|
error_func = lambda err, task_detail: err + f"{task_detail[0]}: {task_detail[1]['stderr']};" |
|
|
|
|
for tp in ['dark', 'failures']: |
|
|
|
|
error_func = ( |
|
|
|
|
lambda err, task_detail: err |
|
|
|
|
+ f"{task_detail[0]}: {task_detail[1]['stderr']};" |
|
|
|
|
) |
|
|
|
|
for tp in ["dark", "failures"]: |
|
|
|
|
for host, tasks in self.result[tp].items(): |
|
|
|
|
error = reduce(error_func, tasks.items(), '').strip(';') |
|
|
|
|
error = reduce(error_func, tasks.items(), "").strip(";") |
|
|
|
|
self.summary[tp][host] = error |
|
|
|
|
failures = list(self.result['failures'].keys()) |
|
|
|
|
dark_or_failures = list(self.result['dark'].keys()) + failures |
|
|
|
|
failures = list(self.result["failures"].keys()) |
|
|
|
|
dark_or_failures = list(self.result["dark"].keys()) + failures |
|
|
|
|
|
|
|
|
|
for host, tasks in self.result.get('ignored', {}).items(): |
|
|
|
|
ignore_errors = reduce(error_func, tasks.items(), '').strip(';') |
|
|
|
|
for host, tasks in self.result.get("ignored", {}).items(): |
|
|
|
|
ignore_errors = reduce(error_func, tasks.items(), "").strip(";") |
|
|
|
|
if host in failures: |
|
|
|
|
self.summary['failures'][host] += ignore_errors |
|
|
|
|
self.summary["failures"][host] += ignore_errors |
|
|
|
|
|
|
|
|
|
self.summary['ok'] = list(set(self.result['ok'].keys()) - set(dark_or_failures)) |
|
|
|
|
self.summary['skipped'] = list(set(self.result['skipped'].keys()) - set(dark_or_failures)) |
|
|
|
|
self.summary["ok"] = list(set(self.result["ok"].keys()) - set(dark_or_failures)) |
|
|
|
|
self.summary["skipped"] = list( |
|
|
|
|
set(self.result["skipped"].keys()) - set(dark_or_failures) |
|
|
|
|
) |
|
|
|
|
|
|
|
|
|
def playbook_on_include(self, event_data, **kwargs): |
|
|
|
|
pass |
|
|
|
@ -151,6 +160,13 @@ class DefaultCallback:
|
|
|
|
|
def playbook_on_no_hosts_remaining(self, event_data, **kwargs): |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
def playbook_on_start(self, event_data, **kwargs): |
|
|
|
|
if settings.DEBUG_DEV: |
|
|
|
|
print("DEBUG: delete inventory: ", os.path.join(self.private_data_dir, 'inventory')) |
|
|
|
|
inventory_path = os.path.join(self.private_data_dir, 'inventory', 'hosts') |
|
|
|
|
if os.path.exists(inventory_path): |
|
|
|
|
os.remove(inventory_path) |
|
|
|
|
|
|
|
|
|
def warning(self, event_data, **kwargs): |
|
|
|
|
pass |
|
|
|
|
|
|
|
|
@ -158,11 +174,11 @@ class DefaultCallback:
|
|
|
|
|
pass |
|
|
|
|
|
|
|
|
|
def status_handler(self, data, **kwargs): |
|
|
|
|
status = data.get('status', '') |
|
|
|
|
self.status = self.STATUS_MAPPER.get(status, 'unknown') |
|
|
|
|
status = data.get("status", "") |
|
|
|
|
self.status = self.STATUS_MAPPER.get(status, "unknown") |
|
|
|
|
self.private_data_dir = data.get("private_data_dir", None) |
|
|
|
|
|
|
|
|
|
def write_pid(self, pid): |
|
|
|
|
pid_filepath = os.path.join(self.private_data_dir, 'local.pid') |
|
|
|
|
with open(pid_filepath, 'w') as f: |
|
|
|
|
pid_filepath = os.path.join(self.private_data_dir, "local.pid") |
|
|
|
|
with open(pid_filepath, "w") as f: |
|
|
|
|
f.write(str(pid)) |
|
|
|
|