add uptimerobot monitor subcommand to app.sh

This commit is contained in:
2026-03-26 13:13:41 -04:00
parent 43fc8c2e7b
commit 697de3e199
3 changed files with 49 additions and 2 deletions
+2 -1
View File
@@ -78,7 +78,7 @@ server. Everything is idempotent.
This single command handles everything: DNS records (Vultr), Gitea repo This single command handles everything: DNS records (Vultr), Gitea repo
(from `static-site-template`), nginx/compose/workflow configs, SSL cert, (from `static-site-template`), nginx/compose/workflow configs, SSL cert,
Garage media bucket, first build, and verification. Garage media bucket, first build, verification, and UptimeRobot monitoring.
**Prerequisites:** domain nameservers pointed to Vultr, `bws`/`jq`/`dig` **Prerequisites:** domain nameservers pointed to Vultr, `bws`/`jq`/`dig`
installed, `BWS_ACCESS_TOKEN` env var or token at `~/.config/hantim/bws-token`. installed, `BWS_ACCESS_TOKEN` env var or token at `~/.config/hantim/bws-token`.
@@ -194,6 +194,7 @@ Project: `hantim`. Fetched via `bws` CLI on the server.
| `hantim-garage-admin-token` | Garage admin API token | `deploy.sh`, `app.sh` | | `hantim-garage-admin-token` | Garage admin API token | `deploy.sh`, `app.sh` |
| `hantim-garage-media-key-id` | S3 access key ID for media uploads | `app.sh`, `aws` CLI | | `hantim-garage-media-key-id` | S3 access key ID for media uploads | `app.sh`, `aws` CLI |
| `hantim-garage-media-secret-key` | S3 secret key for media uploads | `aws` CLI | | `hantim-garage-media-secret-key` | S3 secret key for media uploads | `aws` CLI |
| `hantim-uptimerobot-api-key` | UptimeRobot API key for monitors | `app.sh` |
Machine accounts: `hantim-server` (token at `/etc/bws-token`), `hantim-ci` (reserved). Machine accounts: `hantim-server` (token at `/etc/bws-token`), `hantim-ci` (reserved).
+1
View File
@@ -50,6 +50,7 @@ for stateless static sites.
- Garage media bucket created with media-key access - Garage media bucket created with media-key access
- First build triggered - First build triggered
- `https://www.example.com` responds within 3 minutes - `https://www.example.com` responds within 3 minutes
- UptimeRobot HTTPS monitor created (skipped if already exists)
- Site ready for customization via git clone + push - Site ready for customization via git clone + push
## 4. Update app code ## 4. Update app code
+46 -1
View File
@@ -28,7 +28,8 @@ usage() {
echo " garage Create Garage media bucket and grant access" echo " garage Create Garage media bucket and grant access"
echo " build Trigger initial build workflow" echo " build Trigger initial build workflow"
echo " verify Check if site is live" echo " verify Check if site is live"
echo " all Run all steps (dns, repo, files, cert, garage, commit, build, verify)" echo " monitor Create UptimeRobot HTTPS monitor"
echo " all Run all steps (dns, repo, files, cert, garage, commit, build, verify, monitor)"
echo "" echo ""
echo "Requires: bws, jq, dig" echo "Requires: bws, jq, dig"
exit 1 exit 1
@@ -467,6 +468,48 @@ cmd_verify() {
echo " - The container is running on the server: docker ps" echo " - The container is running on the server: docker ps"
} }
cmd_monitor() {
require_bws
echo "==> Fetching UptimeRobot API key..."
UPTIMEROBOT_API_KEY=$(bws_get "hantim-uptimerobot-api-key")
UPTIMEROBOT_API="https://api.uptimerobot.com/v3"
UPTIMEROBOT_AUTH="Authorization: Bearer $UPTIMEROBOT_API_KEY"
MONITOR_URL="https://www.$APP"
echo "==> Checking for existing UptimeRobot monitor for $MONITOR_URL..."
EXISTING=$(curl -s -G "$UPTIMEROBOT_API/monitors" \
-H "$UPTIMEROBOT_AUTH" \
--data-urlencode "search=$APP")
MATCH=$(echo "$EXISTING" | jq -r --arg url "$MONITOR_URL" \
'.monitors[]? | select(.url == $url) | .id')
if [ -n "$MATCH" ]; then
echo " Monitor already exists (id: $MATCH), skipping."
return
fi
echo "==> Fetching alert contacts..."
ALERT_CONTACTS=$(curl -s "$UPTIMEROBOT_API/user/alert-contacts" \
-H "$UPTIMEROBOT_AUTH" | jq '[.[] | {alertContactId: .id, threshold: 5, recurrence: 30}]')
echo "==> Creating UptimeRobot HTTPS monitor for $MONITOR_URL..."
RESP=$(curl -s -X POST "$UPTIMEROBOT_API/monitors" \
-H "$UPTIMEROBOT_AUTH" \
-H "Content-Type: application/json" \
-d "$(jq -n --arg name "$APP" --arg url "$MONITOR_URL" --argjson contacts "$ALERT_CONTACTS" \
'{friendlyName: $name, url: $url, type: 1, interval: 300, timeout: 30, assignedAlertContacts: $contacts, tagNames: ["hantim"]}')")
MONITOR_ID=$(echo "$RESP" | jq -r '.id // empty')
if [ -n "$MONITOR_ID" ]; then
echo " Monitor created (id: $MONITOR_ID)."
else
ERROR_MSG=$(echo "$RESP" | jq -r 'if .message then (.message | if type == "array" then join("; ") else . end) else .error // "unknown error" end')
echo " Warning: Failed to create monitor: $ERROR_MSG"
fi
}
cmd_all() { cmd_all() {
cmd_dns cmd_dns
cmd_repo cmd_repo
@@ -486,6 +529,7 @@ cmd_all() {
cmd_garage cmd_garage
cmd_build cmd_build
cmd_verify cmd_verify
cmd_monitor
} }
# --- Dispatch --- # --- Dispatch ---
@@ -498,6 +542,7 @@ case "$COMMAND" in
garage) cmd_garage ;; garage) cmd_garage ;;
build) cmd_build ;; build) cmd_build ;;
verify) cmd_verify ;; verify) cmd_verify ;;
monitor) cmd_monitor ;;
all) cmd_all ;; all) cmd_all ;;
*) *)
echo "Unknown command: $COMMAND" echo "Unknown command: $COMMAND"