From 0493b8a42de01e0c9bd1671e4ae6463210a90f6f Mon Sep 17 00:00:00 2001 From: jared Date: Thu, 7 May 2026 11:13:57 -0400 Subject: [PATCH] feat(backup-monitor): add notify_backup script skeleton and test infrastructure --- scripts/notify_backup.rb | 58 +++++++++++++++++++++++++++++++++++ scripts/notify_backup_test.rb | 5 +++ 2 files changed, 63 insertions(+) create mode 100644 scripts/notify_backup.rb create mode 100644 scripts/notify_backup_test.rb diff --git a/scripts/notify_backup.rb b/scripts/notify_backup.rb new file mode 100644 index 0000000..6f703dd --- /dev/null +++ b/scripts/notify_backup.rb @@ -0,0 +1,58 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# notify_backup — send a backup run result to the n8n backup monitor +# +# USAGE +# notify_backup.rb [options] +# +# REQUIRED OPTIONS +# --machine NAME Identifier for this host (e.g. desktop, vps-ovh-prod-01) +# --destination NAME Backup destination (e.g. synology, backblaze-b2, local) +# --status STATUS Result: success | failure | skipped +# +# OPTIONAL OPTIONS +# --bytes N Bytes transferred (raw integer; formatted to human-readable before sending) +# --snapshot ID Restic snapshot ID or equivalent +# --log-path PATH Path to the backup log file for this run +# --notes TEXT Free-form output (restic tail, skip reason, error message, etc.) +# +# REQUIRED ENV VARS +# N8N_SWANSONCLOUD_URL Base URL of the n8n instance (no trailing slash) +# e.g. https://n8n.swansoncloud.com +# N8N_SWANSONCLOUD_BACKUP_AUTH_TOKEN Bearer token for webhook authentication +# +# EXIT BEHAVIOR +# Always exits 0. A notification failure is logged to stderr but never causes +# the calling backup process to fail — the backup ran; the log is the source of truth. +# +# ADDING A NEW BACKUP SOURCE +# 1. Ensure the two ENV vars above are available on the new host +# 2. Call this script at the end of the backup process with --machine, --destination, --status +# 3. Add the {machine, destination} pair to the Set: Expected Sources node in n8n Workflow 2 +# +# CLASSES +# ByteFormatter raw integer bytes → human-readable string (e.g. "4.50 GB") +# PayloadBuilder converts CLI option hash into a clean JSON-ready hash +# WebhookClient sends HTTP POST with auth header; knows nothing about backup data +# BackupNotifier orchestrates: build payload → send; the only public entry point + +require 'net/http' +require 'json' +require 'optparse' + +class ByteFormatter +end + +class PayloadBuilder +end + +class WebhookClient +end + +class BackupNotifier +end + +if __FILE__ == $PROGRAM_NAME + # CLI entry point — implemented in Task 5 +end diff --git a/scripts/notify_backup_test.rb b/scripts/notify_backup_test.rb new file mode 100644 index 0000000..9bf08c2 --- /dev/null +++ b/scripts/notify_backup_test.rb @@ -0,0 +1,5 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require 'minitest/autorun' +require_relative 'notify_backup'