mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-10-08 14:36:38 +00:00
fix(backup): send host backup notifications over HTTPS when the Monitor uses it
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
"""A host backup and a finished restore tell the Monitor on its own port,
|
||||
over HTTPS once the Monitor has a certificate."""
|
||||
from pathlib import Path
|
||||
import subprocess
|
||||
import tempfile
|
||||
from unittest import TestCase
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[3]
|
||||
LIBRARY = ROOT / 'scripts/backup_restore/lib_host_backup_common.sh'
|
||||
POSTBOOT = ROOT / 'scripts/backup_restore/apply_cluster_postboot.sh'
|
||||
SETTING = '/etc/proxmenux/ssl_config.json'
|
||||
|
||||
|
||||
def function(text, name):
|
||||
start = text.index(name + '() {')
|
||||
return text[start:text.index('\n}\n', start) + 3]
|
||||
|
||||
|
||||
class BackupNotifyHttps(TestCase):
|
||||
def address(self, setting):
|
||||
with tempfile.TemporaryDirectory() as folder:
|
||||
path = Path(folder) / 'ssl_config.json'
|
||||
if setting is not None:
|
||||
path.write_text(setting)
|
||||
body = function(LIBRARY.read_text(), 'hb_notify_lifecycle').replace(SETTING, str(path))
|
||||
# The function silences curl, so the stub writes the address it was given.
|
||||
called = Path(folder) / 'called'
|
||||
script = (f'curl() {{ printf "%s" "${{@: -1}}" > {called}; }}\n' + body
|
||||
+ 'HB_NOTIFY_JOB_ID=job1 hb_notify_lifecycle complete\n')
|
||||
result = subprocess.run(['/bin/bash', '--noprofile', '--norc', '-c', script],
|
||||
capture_output=True, text=True, timeout=10)
|
||||
self.assertEqual(result.returncode, 0, result.stderr)
|
||||
return called.read_text()
|
||||
|
||||
def test_plain_http_while_the_monitor_has_no_certificate(self):
|
||||
expected = 'http://127.0.0.1:8008/api/notifications/webhook'
|
||||
self.assertEqual(self.address(None), expected)
|
||||
self.assertEqual(self.address('{"enabled": false}'), expected)
|
||||
|
||||
def test_https_once_the_monitor_has_a_certificate(self):
|
||||
self.assertEqual(self.address('{"enabled": true, "source": "proxmox"}'),
|
||||
'https://127.0.0.1:8008/api/notifications/webhook')
|
||||
|
||||
def test_the_finished_restore_follows_the_same_setting(self):
|
||||
source = POSTBOOT.read_text()
|
||||
self.assertIn('"${NOTIFY_SCHEME}://127.0.0.1:8008/api/internal/restore-event"', source)
|
||||
self.assertNotIn('"http://127.0.0.1:8008/api/internal/restore-event"', source)
|
||||
check = source[source.index('NOTIFY_SCHEME="http"'):source.index('NOTIFY_HTTP=$(curl')]
|
||||
with tempfile.TemporaryDirectory() as folder:
|
||||
path = Path(folder) / 'ssl_config.json'
|
||||
for setting, expected in (('{"enabled": true}', 'https'), ('{"enabled":false}', 'http'), (None, 'http')):
|
||||
path.unlink(missing_ok=True)
|
||||
if setting is not None:
|
||||
path.write_text(setting)
|
||||
result = subprocess.run(['/bin/bash', '--noprofile', '--norc', '-c',
|
||||
check.replace(SETTING, str(path)) + '\necho "$NOTIFY_SCHEME"'],
|
||||
capture_output=True, text=True, timeout=10)
|
||||
self.assertEqual(result.stdout.strip(), expected, setting)
|
||||
@@ -805,8 +805,12 @@ if command -v curl >/dev/null 2>&1; then
|
||||
"$POSTBOOT_DURATION_FMT" \
|
||||
"$SANITY_WARNINGS")
|
||||
fi
|
||||
NOTIFY_HTTP=$(curl -s -o /dev/null -w '%{http_code}' \
|
||||
-X POST "http://127.0.0.1:8008/api/internal/restore-event" \
|
||||
# The Monitor answers on the same port over HTTPS once it has a certificate.
|
||||
NOTIFY_SCHEME="http"
|
||||
grep -Eq '"enabled"[[:space:]]*:[[:space:]]*true' /etc/proxmenux/ssl_config.json 2>/dev/null && \
|
||||
NOTIFY_SCHEME="https"
|
||||
NOTIFY_HTTP=$(curl -sk -o /dev/null -w '%{http_code}' \
|
||||
-X POST "${NOTIFY_SCHEME}://127.0.0.1:8008/api/internal/restore-event" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$PAYLOAD" \
|
||||
--max-time 5 2>/dev/null || echo "000")
|
||||
|
||||
@@ -3420,11 +3420,16 @@ Log: ${HB_NOTIFY_LOG_FILE:-}"
|
||||
log_file:$log, reason:$reason}}' \
|
||||
2>/dev/null)
|
||||
[[ -z "$payload" ]] && return 0
|
||||
# The Monitor answers on the same port over HTTPS once it has a certificate.
|
||||
local scheme="http"
|
||||
[[ -f /etc/proxmenux/ssl_config.json ]] && \
|
||||
jq -e '.enabled' /etc/proxmenux/ssl_config.json >/dev/null 2>&1 && \
|
||||
scheme="https"
|
||||
curl -sk --connect-timeout 3 --max-time 5 \
|
||||
-X POST \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$payload" \
|
||||
http://127.0.0.1:8008/api/notifications/webhook \
|
||||
"${scheme}://127.0.0.1:8008/api/notifications/webhook" \
|
||||
>/dev/null 2>&1 || true
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user