fix: bug: disinto-edge hard-fails on missing age key / secrets even when collect-engagement feature is not configured (#1038) #1045
1 changed files with 46 additions and 36 deletions
|
|
@ -173,11 +173,15 @@ PROJECT_TOML="${PROJECT_TOML:-projects/disinto.toml}"
|
||||||
sleep 1200 # 20 minutes
|
sleep 1200 # 20 minutes
|
||||||
done) &
|
done) &
|
||||||
|
|
||||||
# ── Load required secrets from secrets/*.enc (#777) ────────────────────
|
# ── Load optional secrets from secrets/*.enc (#777) ────────────────────
|
||||||
# Edge container declares its required secrets; missing ones cause a hard fail.
|
# Engagement collection (collect-engagement.sh) requires CADDY_ secrets to
|
||||||
|
# SCP access logs from a remote edge host. When age key or secrets dir is
|
||||||
|
# missing, or any secret fails to decrypt, log a warning and skip the cron.
|
||||||
|
# Caddy itself does not depend on these secrets.
|
||||||
_AGE_KEY_FILE="${HOME}/.config/sops/age/keys.txt"
|
_AGE_KEY_FILE="${HOME}/.config/sops/age/keys.txt"
|
||||||
_SECRETS_DIR="/opt/disinto/secrets"
|
_SECRETS_DIR="/opt/disinto/secrets"
|
||||||
EDGE_REQUIRED_SECRETS="CADDY_SSH_KEY CADDY_SSH_HOST CADDY_SSH_USER CADDY_ACCESS_LOG"
|
EDGE_REQUIRED_SECRETS="CADDY_SSH_KEY CADDY_SSH_HOST CADDY_SSH_USER CADDY_ACCESS_LOG"
|
||||||
|
EDGE_ENGAGEMENT_READY=0 # Assume not ready until proven otherwise
|
||||||
|
|
||||||
_edge_decrypt_secret() {
|
_edge_decrypt_secret() {
|
||||||
local enc_path="${_SECRETS_DIR}/${1}.enc"
|
local enc_path="${_SECRETS_DIR}/${1}.enc"
|
||||||
|
|
@ -192,47 +196,53 @@ if [ -f "$_AGE_KEY_FILE" ] && [ -d "$_SECRETS_DIR" ]; then
|
||||||
export "$_secret_name=$_val"
|
export "$_secret_name=$_val"
|
||||||
done
|
done
|
||||||
if [ -n "$_missing" ]; then
|
if [ -n "$_missing" ]; then
|
||||||
echo "FATAL: required secrets missing from secrets/*.enc:${_missing}" >&2
|
echo "WARN: required engagement secrets missing from secrets/*.enc:${_missing}" >&2
|
||||||
echo " Run 'disinto secrets add <NAME>' for each missing secret." >&2
|
echo " collect-engagement cron will be skipped. Run 'disinto secrets add <NAME>' to enable." >&2
|
||||||
echo " If migrating from .env.vault.enc, run 'disinto secrets migrate-from-vault' first." >&2
|
EDGE_ENGAGEMENT_READY=0
|
||||||
exit 1
|
else
|
||||||
|
echo "edge: loaded required engagement secrets: ${EDGE_REQUIRED_SECRETS}" >&2
|
||||||
|
EDGE_ENGAGEMENT_READY=1
|
||||||
fi
|
fi
|
||||||
echo "edge: loaded required secrets: ${EDGE_REQUIRED_SECRETS}" >&2
|
|
||||||
else
|
else
|
||||||
echo "FATAL: age key (${_AGE_KEY_FILE}) or secrets dir (${_SECRETS_DIR}) not found — cannot load required secrets" >&2
|
echo "WARN: age key (${_AGE_KEY_FILE}) or secrets dir (${_SECRETS_DIR}) not found — engagement secrets unavailable" >&2
|
||||||
echo " Ensure age is installed and secrets/*.enc files are present." >&2
|
echo " collect-engagement cron will be skipped. Run 'disinto secrets add <NAME>' to enable." >&2
|
||||||
exit 1
|
EDGE_ENGAGEMENT_READY=0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Start daily engagement collection cron loop in background (#745)
|
# Start daily engagement collection cron loop in background (#745)
|
||||||
# Runs collect-engagement.sh daily at ~23:50 UTC via a sleep loop that
|
# Runs collect-engagement.sh daily at ~23:50 UTC via a sleep loop that
|
||||||
# calculates seconds until the next 23:50 window. SSH key from secrets/*.enc (#777).
|
# calculates seconds until the next 23:50 window. SSH key from secrets/*.enc (#777).
|
||||||
(while true; do
|
# Guarded: only start if EDGE_ENGAGEMENT_READY=1.
|
||||||
# Calculate seconds until next 23:50 UTC
|
if [ "$EDGE_ENGAGEMENT_READY" -eq 1 ]; then
|
||||||
_now=$(date -u +%s)
|
(while true; do
|
||||||
_target=$(date -u -d "today 23:50" +%s 2>/dev/null || date -u -d "23:50" +%s 2>/dev/null || echo 0)
|
# Calculate seconds until next 23:50 UTC
|
||||||
if [ "$_target" -le "$_now" ]; then
|
_now=$(date -u +%s)
|
||||||
_target=$(( _target + 86400 ))
|
_target=$(date -u -d "today 23:50" +%s 2>/dev/null || date -u -d "23:50" +%s 2>/dev/null || echo 0)
|
||||||
fi
|
if [ "$_target" -le "$_now" ]; then
|
||||||
_sleep_secs=$(( _target - _now ))
|
_target=$(( _target + 86400 ))
|
||||||
echo "edge: collect-engagement scheduled in ${_sleep_secs}s (next 23:50 UTC)" >&2
|
fi
|
||||||
sleep "$_sleep_secs"
|
_sleep_secs=$(( _target - _now ))
|
||||||
_fetch_log="/tmp/caddy-access-log-fetch.log"
|
echo "edge: collect-engagement scheduled in ${_sleep_secs}s (next 23:50 UTC)" >&2
|
||||||
_ssh_key_file=$(mktemp)
|
sleep "$_sleep_secs"
|
||||||
printf '%s\n' "$CADDY_SSH_KEY" > "$_ssh_key_file"
|
_fetch_log="/tmp/caddy-access-log-fetch.log"
|
||||||
chmod 0600 "$_ssh_key_file"
|
_ssh_key_file=$(mktemp)
|
||||||
scp -i "$_ssh_key_file" -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 -o BatchMode=yes \
|
printf '%s\n' "$CADDY_SSH_KEY" > "$_ssh_key_file"
|
||||||
"${CADDY_SSH_USER}@${CADDY_SSH_HOST}:${CADDY_ACCESS_LOG}" \
|
chmod 0600 "$_ssh_key_file"
|
||||||
"$_fetch_log" 2>&1 | tee -a /opt/disinto-logs/collect-engagement.log || true
|
scp -i "$_ssh_key_file" -o StrictHostKeyChecking=accept-new -o ConnectTimeout=10 -o BatchMode=yes \
|
||||||
rm -f "$_ssh_key_file"
|
"${CADDY_SSH_USER}@${CADDY_SSH_HOST}:${CADDY_ACCESS_LOG}" \
|
||||||
if [ -s "$_fetch_log" ]; then
|
"$_fetch_log" 2>&1 | tee -a /opt/disinto-logs/collect-engagement.log || true
|
||||||
CADDY_ACCESS_LOG="$_fetch_log" bash /opt/disinto/site/collect-engagement.sh 2>&1 \
|
rm -f "$_ssh_key_file"
|
||||||
| tee -a /opt/disinto-logs/collect-engagement.log || true
|
if [ -s "$_fetch_log" ]; then
|
||||||
else
|
CADDY_ACCESS_LOG="$_fetch_log" bash /opt/disinto/site/collect-engagement.sh 2>&1 \
|
||||||
echo "edge: collect-engagement: fetched log is empty, skipping parse" >&2
|
| tee -a /opt/disinto-logs/collect-engagement.log || true
|
||||||
fi
|
else
|
||||||
rm -f "$_fetch_log"
|
echo "edge: collect-engagement: fetched log is empty, skipping parse" >&2
|
||||||
done) &
|
fi
|
||||||
|
rm -f "$_fetch_log"
|
||||||
|
done) &
|
||||||
|
else
|
||||||
|
echo "edge: collect-engagement cron skipped (EDGE_ENGAGEMENT_READY=0)" >&2
|
||||||
|
fi
|
||||||
|
|
||||||
# Nomad template renders Caddyfile to /local/Caddyfile via service discovery;
|
# Nomad template renders Caddyfile to /local/Caddyfile via service discovery;
|
||||||
# copy it into the expected location if present (compose uses the mounted path).
|
# copy it into the expected location if present (compose uses the mounted path).
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue