mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-02-22 10:26:26 +00:00
Update flask_notification_routes.py
This commit is contained in:
@@ -231,9 +231,10 @@ def _pve_remove_our_blocks(text, headers_to_remove):
|
|||||||
|
|
||||||
def _build_webhook_fallback():
|
def _build_webhook_fallback():
|
||||||
"""Build fallback manual commands for webhook setup."""
|
"""Build fallback manual commands for webhook setup."""
|
||||||
|
body_tpl = '{"title":"{{ escape title }}","message":"{{ escape message }}","severity":"{{ severity }}","timestamp":"{{ timestamp }}","type":"{{#if fields.type}}{{ fields.type }}{{else}}test{{/if}}","hostname":"{{#if fields.hostname}}{{ fields.hostname }}{{else}}unknown{{/if}}"}'
|
||||||
return [
|
return [
|
||||||
"# Append to END of /etc/pve/notifications.cfg",
|
"# 1. Append to END of /etc/pve/notifications.cfg",
|
||||||
"# (do NOT delete existing content):",
|
"# (do NOT delete existing content):",
|
||||||
"",
|
"",
|
||||||
f"webhook: {_PVE_ENDPOINT_ID}",
|
f"webhook: {_PVE_ENDPOINT_ID}",
|
||||||
f"\tmethod post",
|
f"\tmethod post",
|
||||||
@@ -243,8 +244,11 @@ def _build_webhook_fallback():
|
|||||||
f"\ttarget {_PVE_ENDPOINT_ID}",
|
f"\ttarget {_PVE_ENDPOINT_ID}",
|
||||||
"\tmode all",
|
"\tmode all",
|
||||||
"",
|
"",
|
||||||
"# ALSO append to /etc/pve/priv/notifications.cfg :",
|
"# 2. Append to /etc/pve/priv/notifications.cfg :",
|
||||||
f"webhook: {_PVE_ENDPOINT_ID}",
|
f"webhook: {_PVE_ENDPOINT_ID}",
|
||||||
|
"",
|
||||||
|
"# 3. Set body via pvesh (NOT in the config file -- PVE stores it base64):",
|
||||||
|
f"pvesh set /cluster/notifications/endpoints/webhook/{_PVE_ENDPOINT_ID} --body '{body_tpl}'",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
@@ -306,15 +310,10 @@ def setup_pve_webhook_core() -> dict:
|
|||||||
# PVE secret format is: secret name=key,value=<base64>
|
# PVE secret format is: secret name=key,value=<base64>
|
||||||
# Neither is needed for localhost calls.
|
# Neither is needed for localhost calls.
|
||||||
|
|
||||||
# PVE webhook format requires:
|
# Write ONLY basic properties (method, url) to the config file.
|
||||||
# - body: Handlebars template for the HTTP body
|
# body and header MUST be set via pvesh API (Step 10) because PVE
|
||||||
# - header: Content-Type header for JSON
|
# stores them base64-encoded internally. Writing them as plain text
|
||||||
# - A matching entry in priv/notifications.cfg (even if empty)
|
# to the config file corrupts PVE's config parser.
|
||||||
# The body template uses PVE's Handlebars syntax to pass notification
|
|
||||||
# metadata to our webhook handler as structured JSON.
|
|
||||||
# PVE sends JSON by default (title, message, severity, timestamp, fields).
|
|
||||||
# Do NOT set header or body -- PVE's config parser rejects custom header
|
|
||||||
# formats and a missing/malformed header line corrupts the ENTIRE config.
|
|
||||||
endpoint_block = (
|
endpoint_block = (
|
||||||
f"webhook: {_PVE_ENDPOINT_ID}\n"
|
f"webhook: {_PVE_ENDPOINT_ID}\n"
|
||||||
f"\tmethod post\n"
|
f"\tmethod post\n"
|
||||||
@@ -382,32 +381,43 @@ def setup_pve_webhook_core() -> dict:
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
# ── Step 10: Configure body and header via pvesh API ──
|
# ── Step 10: Configure body and header via pvesh API ──
|
||||||
# Writing header/body directly to the config file uses a different
|
# body and header are stored base64-encoded in the config file.
|
||||||
# internal format that PVE's parser rejects. Using pvesh set handles
|
# Writing them as plain text corrupts PVE's parser. pvesh handles
|
||||||
# escaping and the priv-config wire format correctly.
|
# the encoding correctly.
|
||||||
import subprocess
|
import subprocess
|
||||||
|
|
||||||
# Body template: PVE Handlebars that sends JSON to our webhook
|
pvesh_path = f'/cluster/notifications/endpoints/webhook/{_PVE_ENDPOINT_ID}'
|
||||||
body_template = '{"title":"{{ escape title }}","message":"{{ escape message }}","severity":"{{ severity }}","timestamp":"{{ timestamp }}"}'
|
|
||||||
|
# Body template using PVE Handlebars syntax.
|
||||||
|
# - {{ escape title }} and {{ escape message }} are PVE built-in helpers
|
||||||
|
# - {{ severity }} gives: info, notice, warning, error, unknown
|
||||||
|
# - {{ fields.X }} is populated for real events (backup, replication, etc.)
|
||||||
|
# but NOT for test notifications, so we use {{#if}} fallbacks.
|
||||||
|
# - {{ timestamp }} gives epoch seconds
|
||||||
|
body_template = (
|
||||||
|
'{'
|
||||||
|
'"title":"{{ escape title }}",'
|
||||||
|
'"message":"{{ escape message }}",'
|
||||||
|
'"severity":"{{ severity }}",'
|
||||||
|
'"timestamp":"{{ timestamp }}",'
|
||||||
|
'"type":"{{#if fields.type}}{{ fields.type }}{{else}}test{{/if}}",'
|
||||||
|
'"hostname":"{{#if fields.hostname}}{{ fields.hostname }}{{else}}unknown{{/if}}"'
|
||||||
|
'}'
|
||||||
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Set body template
|
# Set body template via pvesh (NOT in the config file -- PVE
|
||||||
subprocess.run(
|
# stores body base64-encoded internally, pvesh handles that).
|
||||||
['pvesh', 'set',
|
# No header needed: our webhook handler parses JSON from raw
|
||||||
f'/cluster/notifications/endpoints/webhook/{_PVE_ENDPOINT_ID}',
|
# body regardless of Content-Type.
|
||||||
'--body', body_template],
|
r1 = subprocess.run(
|
||||||
capture_output=True, text=True, timeout=10
|
['pvesh', 'set', pvesh_path, '--body', body_template],
|
||||||
)
|
|
||||||
|
|
||||||
# Set Content-Type header
|
|
||||||
subprocess.run(
|
|
||||||
['pvesh', 'set',
|
|
||||||
f'/cluster/notifications/endpoints/webhook/{_PVE_ENDPOINT_ID}',
|
|
||||||
'--header', 'Content-Type:application/json'],
|
|
||||||
capture_output=True, text=True, timeout=10
|
capture_output=True, text=True, timeout=10
|
||||||
)
|
)
|
||||||
|
if r1.returncode != 0:
|
||||||
|
result['body_config_warning'] = f'pvesh set --body failed: {r1.stderr.strip()}'
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
# Non-fatal: webhook still works, just sends raw format
|
# Non-fatal: if pvesh fails, webhook still receives POSTs (just empty body)
|
||||||
result['body_config_warning'] = str(e)
|
result['body_config_warning'] = str(e)
|
||||||
|
|
||||||
result['configured'] = True
|
result['configured'] = True
|
||||||
|
|||||||
Reference in New Issue
Block a user