Update flask_notification_routes.py

This commit is contained in:
MacRimi
2026-02-21 21:11:57 +01:00
parent 50e5775062
commit 06c9ff481e

View File

@@ -231,12 +231,15 @@ def _pve_remove_our_blocks(text, headers_to_remove):
def _build_webhook_fallback():
"""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}}"}'
import base64
body_tpl = '{"title":"{{ title }}","message":"{{ message }}","severity":"{{ severity }}","timestamp":"{{ timestamp }}"}'
body_b64 = base64.b64encode(body_tpl.encode()).decode()
return [
"# 1. Append to END of /etc/pve/notifications.cfg",
"# (do NOT delete existing content):",
"",
f"webhook: {_PVE_ENDPOINT_ID}",
f"\tbody {body_b64}",
f"\tmethod post",
f"\turl {_PVE_WEBHOOK_URL}",
"",
@@ -246,9 +249,6 @@ def _build_webhook_fallback():
"",
"# 2. Append to /etc/pve/priv/notifications.cfg :",
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}'",
]
@@ -310,12 +310,16 @@ def setup_pve_webhook_core() -> dict:
# PVE secret format is: secret name=key,value=<base64>
# Neither is needed for localhost calls.
# Write ONLY basic properties (method, url) to the config file.
# body and header MUST be set via pvesh API (Step 10) because PVE
# stores them base64-encoded internally. Writing them as plain text
# to the config file corrupts PVE's config parser.
# PVE stores body as base64 in the config file. We encode it here
# so the config parser reads it correctly. The plain-text template:
# {"title":"{{ title }}","message":"{{ message }}","severity":"{{ severity }}","timestamp":"{{ timestamp }}"}
import base64
body_template = '{"title":"{{ title }}","message":"{{ message }}","severity":"{{ severity }}","timestamp":"{{ timestamp }}"}'
body_b64 = base64.b64encode(body_template.encode()).decode()
endpoint_block = (
f"webhook: {_PVE_ENDPOINT_ID}\n"
f"\tbody {body_b64}\n"
f"\tmethod post\n"
f"\turl {_PVE_WEBHOOK_URL}\n"
)
@@ -380,46 +384,6 @@ def setup_pve_webhook_core() -> dict:
except Exception:
pass
# ── Step 10: Configure body and header via pvesh API ──
# body and header are stored base64-encoded in the config file.
# Writing them as plain text corrupts PVE's parser. pvesh handles
# the encoding correctly.
import subprocess
pvesh_path = f'/cluster/notifications/endpoints/webhook/{_PVE_ENDPOINT_ID}'
# 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:
# Set body template via pvesh (NOT in the config file -- PVE
# stores body base64-encoded internally, pvesh handles that).
# No header needed: our webhook handler parses JSON from raw
# body regardless of Content-Type.
r1 = subprocess.run(
['pvesh', 'set', pvesh_path, '--body', body_template],
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:
# Non-fatal: if pvesh fails, webhook still receives POSTs (just empty body)
result['body_config_warning'] = str(e)
result['configured'] = True
result['secret'] = secret
return result