#!/usr/bin/env python3 import json import logging import requests from flask import Flask, request, jsonify # ----------------------------------------------------------------------------- # Flask app + logging setup # ----------------------------------------------------------------------------- app = Flask(__name__) logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s") log = logging.getLogger("centreon-storage-alert") # ----------------------------------------------------------------------------- # Configuration # ----------------------------------------------------------------------------- CENTREON_BASE = "https://x.x.x.x/centreon" CENTREON_URL_V2 = f"{CENTREON_BASE}/api/latest" CENTREON_API_TOKEN = "yyyyyyyyy" CENTREON_VERIFY_SSL = False HTTP_TIMEOUT = 15 # 👇 Manual storage device host ID (must already exist in Centreon) STORAGE_HOST_ID = 5 # ----------------------------------------------------------------------------- # Centreon API helpers # ----------------------------------------------------------------------------- def centreon_headers_v2(): return {"X-AUTH-TOKEN": CENTREON_API_TOKEN, "Content-Type": "application/json"} def centreon_url_v2(path: str) -> str: return CENTREON_URL_V2.rstrip("/") + path def log_request(method: str, url: str, params=None, payload=None, client_ips=None): msg = f"{method} {url}" if client_ips: msg += f" [client_ips={client_ips}]" if params: msg += f" params={json.dumps(params)}" if payload: msg += f"\nPayload:\n{json.dumps(payload, indent=2)}" log.info(msg) # ----------------------------------------------------------------------------- # Severity mapping # ----------------------------------------------------------------------------- def map_severity_to_host_status(sev: str) -> int: s = (sev or "").strip().upper() if s in {"INFORMATION", "INFO"}: return 0 if s in {"WARNING", "MAJOR", "CRITICAL"}: return 1 return 2 # ----------------------------------------------------------------------------- # Passive host result submission # ----------------------------------------------------------------------------- def submit_host_result(host_id: int, severity: str, alert_id: str, state: str, user: str, files: list, num_files: int, signal_strength: int, client_ips: list): url = centreon_url_v2(f"/monitoring/hosts/{host_id}/submit") status = map_severity_to_host_status(severity) first_file = files[0] if files else "n/a" client_ips_str = ",".join(client_ips) if client_ips else "n/a" output = (f"{severity.upper()} Storage Alert " f"(id={alert_id}, state={state}, user={user}) " f"[client_ips={client_ips_str}] First file={first_file} ") body = { "status": status, "output": output, "performance_data": ( f"'clientIPs'={client_ips_str};;;; " f"'files'={len(files)};;;; " f"'numFiles'={num_files};;;; " f"'signalStrength'={signal_strength};;;;" ) } log_request("POST", url, payload=body, client_ips=client_ips) r = requests.post(url, headers=centreon_headers_v2(), json=body, timeout=HTTP_TIMEOUT, verify=CENTREON_VERIFY_SSL) log.info("Response %s: %s [client_ips=%s]", r.status_code, r.text[:500], client_ips) r.raise_for_status() # ----------------------------------------------------------------------------- # Webhook # ----------------------------------------------------------------------------- @app.route("/webhook", methods=["POST"]) def webhook(): try: payload = request.get_json(silent=True) or {} client_ips = payload.get("clientIPs") or [] log.info("Incoming webhook payload from client_ips=%s:\n%s", client_ips, json.dumps(payload, indent=2)[:5000]) severity = payload.get("severity", "INFORMATION") alert_id = payload.get("id", "n/a") state = payload.get("state", "n/a") user = payload.get("userName", "unknown") files = payload.get("files") or [] num_files = payload.get("numFiles", len(files)) signal_strength = (payload.get("signalStrengths") or {}).get("THREAT_DETECTOR_07", 0) # Always update the manual storage host submit_host_result(STORAGE_HOST_ID, severity, alert_id, state, user, files, num_files, signal_strength, client_ips) return jsonify({ "status": "ok", "storage_host_id": STORAGE_HOST_ID, "client_ips": client_ips, "submitted": { "severity": severity, "alert_id": alert_id, "state": state, "user": user, "num_files": num_files, "signal_strength": signal_strength } }), 200 except requests.HTTPError as err: log.exception("HTTP error with Centreon API [client_ips=%s]", client_ips) return jsonify({"error": str(err), "status": err.response.status_code, "client_ips": client_ips}), err.response.status_code except Exception as e: log.exception("Unhandled error [client_ips=%s]", client_ips) return jsonify({"error": str(e), "client_ips": client_ips}), 500 # ----------------------------------------------------------------------------- # Entrypoint # ----------------------------------------------------------------------------- if __name__ == "__main__": app.run(host="0.0.0.0", port=5000)