uptime kuma: remove every live reference, repoint the probes to Gatus
Nothing in the repo pushes to, authenticates against, or is gated by Uptime
Kuma any more.
── The sixth instance of the banner bug ────────────────────────────────────
memos had `Restart memos` guarded by `uptime_kuma_enabled`, because the
deprecation banner was placed immediately above it and swept it in. It is a
HANDLER, so every memos config change since 2026-09-11 applied to disk and
silently never restarted the service. Ungated.
That is the same failure found in forgejo-runner's self-assert, phoenixd's timer
enable, mempool's three timer enables, fulcrum's restart handler and bitcoind's
restart handler. Every guard was read and asked "monitoring or deployment?"
before being deleted, which is the only reason this was caught.
── What was removed ────────────────────────────────────────────────────────
30 uptime_kuma_enabled guards across 7 unconverted service playbooks, and
the 29 Kuma monitor-creation tasks they gated (embedded Python that drove
the Kuma API, temp credential files, cleanup)
7 dead uptime_kuma_api_url definitions
7 stale DEPRECATED banners
uptime_kuma_enabled and subdomains.uptime_kuma from group_vars/all
healthcheck_push_urls from the vault - 30 push tokens
services/ntfy/setup_ntfy_uptime_kuma_notification.yml -> archive/
The explanatory comments in the six converted roles are KEPT on purpose. They
record why a handler is ungated, and deleting the explanation invites someone
to helpfully re-add the guard.
── The probes moved rather than died ───────────────────────────────────────
Eight per-service health checks were still pushing to Kuma. They are not
superseded by infra/401: that answers "is the unit running", these answer "does
the service actually respond" - an RPC call to bitcoind, a TCP connect to
Fulcrum's Electrum port, an HTTP fetch from Mempool's backend. A process can be
perfectly `active` and useless.
So they were repointed, not deleted. Gatus external endpoints take a POST with
a bearer token and success=true|false where Kuma took a GET with ?status=up, so
report() now maps up/down to true/false internally and no call site changed.
Registered by infra/403 as the `probe` group, one token per host.
Two bugs fixed while in there:
* forgejo-runner's check only ever reported SUCCESS - it exited before pushing
when the runner was down, so a failure was invisible until the heartbeat
window expired. Reporting the failure is the entire point of a check.
* All six healthcheck .service units were mode 0644 and now carry a bearer
token. They are 0600.
Verified: 91 endpoints, 91 UP, 0 DOWN. Every probe triggered by hand and
confirmed arriving. Zero Kuma URLs left in the vault, zero live references in
any playbook or role.
Still standing, deliberately: the Kuma container on watchtower, its Caddy vhost,
and the uptime.contrapeso.xyz DNS record. Turning the service off is a separate
decision from removing the code that talked to it.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
853e62a19c
commit
bf3d21fef7
44 changed files with 337 additions and 1171 deletions
|
|
@ -12,7 +12,8 @@
|
|||
vars:
|
||||
# Preserves the push URL this check has been reporting to. The role knows
|
||||
# nothing about Uptime Kuma — this is just "a URL that accepts a ping".
|
||||
healthcheck_push_url: "{{ healthcheck_push_urls.bitcoin_knots | default('') }}"
|
||||
healthcheck_push_url: "https://{{ subdomains.gatus }}.{{ root_domain }}/api/v1/endpoints/probe_bitcoin-knots/external"
|
||||
healthcheck_push_token: "{{ gatus_push_tokens[inventory_hostname] }}"
|
||||
roles:
|
||||
- bitcoin_knots
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,8 @@
|
|||
vars:
|
||||
# Preserves the push URL this check reports to. The role knows nothing about
|
||||
# Uptime Kuma — this is just "a URL that accepts a ping".
|
||||
healthcheck_push_url: "{{ healthcheck_push_urls.datum_gateway | default('') }}"
|
||||
healthcheck_push_url: "https://{{ subdomains.gatus }}.{{ root_domain }}/api/v1/endpoints/probe_datum-gateway/external"
|
||||
healthcheck_push_token: "{{ gatus_push_tokens[inventory_hostname] }}"
|
||||
roles:
|
||||
- datum_gateway
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
# move to a role changes no behaviour. The role itself knows nothing about
|
||||
# Uptime Kuma — this is just "a URL that accepts a ping", and whatever
|
||||
# replaces it sets the same variable.
|
||||
healthcheck_push_url: "{{ healthcheck_push_urls.forgejo_runner | default('') }}"
|
||||
healthcheck_push_url: "https://{{ subdomains.gatus }}.{{ root_domain }}/api/v1/endpoints/probe_forgejo-runner/external"
|
||||
healthcheck_push_token: "{{ gatus_push_tokens[inventory_hostname] }}"
|
||||
roles:
|
||||
- forgejo_runner
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
vars:
|
||||
forgejo_subdomain: "{{ subdomains.forgejo }}"
|
||||
forgejo_domain: "{{ forgejo_subdomain }}.{{ root_domain }}"
|
||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||
|
||||
tasks:
|
||||
- name: Ensure required packages are installed
|
||||
|
|
@ -91,123 +90,3 @@
|
|||
caddy_site_name: forgejo
|
||||
caddy_site_domain: "{{ forgejo_domain }}"
|
||||
caddy_site_upstream: "localhost:{{ forgejo_port }}"
|
||||
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||
#
|
||||
# Every task below is inert: uptime_kuma_enabled is false in
|
||||
# group_vars/all/main.yml, so they all skip and the deployment above still
|
||||
# runs normally. Kept because the health-check logic is the durable part —
|
||||
# when a replacement exists, rewire the push transport and flip the flag.
|
||||
#
|
||||
# What was being monitored: archive/uptime_kuma/MONITORS.md
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
- name: Create Uptime Kuma monitor setup script for Forgejo
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/setup_forgejo_monitor.py
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import yaml
|
||||
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
||||
|
||||
try:
|
||||
with open('/tmp/ansible_config.yml', 'r') as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
url = config['uptime_kuma_url']
|
||||
username = config['username']
|
||||
password = config['password']
|
||||
monitor_url = config['monitor_url']
|
||||
monitor_name = config['monitor_name']
|
||||
|
||||
api = UptimeKumaApi(url, timeout=30)
|
||||
api.login(username, password)
|
||||
|
||||
# Get all monitors
|
||||
monitors = api.get_monitors()
|
||||
|
||||
# Find or create "services" group
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
if not group:
|
||||
group_result = api.add_monitor(type='group', name='services')
|
||||
# Refresh to get the group with id
|
||||
monitors = api.get_monitors()
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
|
||||
# Check if monitor already exists
|
||||
existing_monitor = None
|
||||
for monitor in monitors:
|
||||
if monitor.get('name') == monitor_name:
|
||||
existing_monitor = monitor
|
||||
break
|
||||
|
||||
# Get ntfy notification ID
|
||||
notifications = api.get_notifications()
|
||||
ntfy_notification_id = None
|
||||
for notif in notifications:
|
||||
if notif.get('type') == 'ntfy':
|
||||
ntfy_notification_id = notif.get('id')
|
||||
break
|
||||
|
||||
if existing_monitor:
|
||||
print(f"Monitor '{monitor_name}' already exists (ID: {existing_monitor['id']})")
|
||||
print("Skipping - monitor already configured")
|
||||
else:
|
||||
print(f"Creating monitor '{monitor_name}'...")
|
||||
api.add_monitor(
|
||||
type=MonitorType.HTTP,
|
||||
name=monitor_name,
|
||||
url=monitor_url,
|
||||
parent=group['id'],
|
||||
interval=60,
|
||||
maxretries=3,
|
||||
retryInterval=60,
|
||||
notificationIDList={ntfy_notification_id: True} if ntfy_notification_id else {}
|
||||
)
|
||||
|
||||
api.disconnect()
|
||||
print("SUCCESS")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: {str(e)}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
mode: '0755'
|
||||
|
||||
- name: Create temporary config for monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/ansible_config.yml
|
||||
content: |
|
||||
uptime_kuma_url: "{{ uptime_kuma_api_url }}"
|
||||
username: "{{ uptime_kuma_username }}"
|
||||
password: "{{ uptime_kuma_password }}"
|
||||
monitor_url: "https://{{ forgejo_domain }}/api/healthz"
|
||||
monitor_name: "Forgejo"
|
||||
mode: '0644'
|
||||
|
||||
- name: Run Uptime Kuma monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
command: python3 /tmp/setup_forgejo_monitor.py
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
register: monitor_setup
|
||||
changed_when: "'SUCCESS' in monitor_setup.stdout"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clean up temporary files
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/setup_forgejo_monitor.py
|
||||
- /tmp/ansible_config.yml
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,8 @@
|
|||
vars:
|
||||
# Preserves the push URL this check has been configured with. The role knows
|
||||
# nothing about Uptime Kuma — this is just "a URL that accepts a ping".
|
||||
healthcheck_push_url: "{{ healthcheck_push_urls.fulcrum | default('') }}"
|
||||
healthcheck_push_url: "https://{{ subdomains.gatus }}.{{ root_domain }}/api/v1/endpoints/probe_fulcrum/external"
|
||||
healthcheck_push_token: "{{ gatus_push_tokens[inventory_hostname] }}"
|
||||
roles:
|
||||
- fulcrum
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
headscale_subdomain: "{{ subdomains.headscale }}"
|
||||
headscale_domain: "{{ headscale_subdomain }}.{{ root_domain }}"
|
||||
headscale_base_domain: "tailnet.{{ root_domain }}"
|
||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||
|
||||
tasks:
|
||||
- name: Install required packages
|
||||
|
|
@ -254,125 +253,6 @@
|
|||
# All API operations require a valid Bearer token in the Authorization header
|
||||
reverse_proxy * http://localhost:{{ headscale_port }}
|
||||
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||
#
|
||||
# Every task below is inert: uptime_kuma_enabled is false in
|
||||
# group_vars/all/main.yml, so they all skip and the deployment above still
|
||||
# runs normally. Kept because the health-check logic is the durable part —
|
||||
# when a replacement exists, rewire the push transport and flip the flag.
|
||||
#
|
||||
# What was being monitored: archive/uptime_kuma/MONITORS.md
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
- name: Create Uptime Kuma monitor setup script for Headscale
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/setup_headscale_monitor.py
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import yaml
|
||||
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
||||
|
||||
try:
|
||||
with open('/tmp/ansible_config.yml', 'r') as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
url = config['uptime_kuma_url']
|
||||
username = config['username']
|
||||
password = config['password']
|
||||
monitor_url = config['monitor_url']
|
||||
monitor_name = config['monitor_name']
|
||||
|
||||
api = UptimeKumaApi(url, timeout=30)
|
||||
api.login(username, password)
|
||||
|
||||
# Get all monitors
|
||||
monitors = api.get_monitors()
|
||||
|
||||
# Find or create "services" group
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
if not group:
|
||||
group_result = api.add_monitor(type='group', name='services')
|
||||
# Refresh to get the group with id
|
||||
monitors = api.get_monitors()
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
|
||||
# Check if monitor already exists
|
||||
existing_monitor = None
|
||||
for monitor in monitors:
|
||||
if monitor.get('name') == monitor_name:
|
||||
existing_monitor = monitor
|
||||
break
|
||||
|
||||
# Get ntfy notification ID
|
||||
notifications = api.get_notifications()
|
||||
ntfy_notification_id = None
|
||||
for notif in notifications:
|
||||
if notif.get('type') == 'ntfy':
|
||||
ntfy_notification_id = notif.get('id')
|
||||
break
|
||||
|
||||
if existing_monitor:
|
||||
print(f"Monitor '{monitor_name}' already exists (ID: {existing_monitor['id']})")
|
||||
print("Skipping - monitor already configured")
|
||||
else:
|
||||
print(f"Creating monitor '{monitor_name}'...")
|
||||
api.add_monitor(
|
||||
type=MonitorType.HTTP,
|
||||
name=monitor_name,
|
||||
url=monitor_url,
|
||||
parent=group['id'],
|
||||
interval=60,
|
||||
maxretries=3,
|
||||
retryInterval=60,
|
||||
notificationIDList={ntfy_notification_id: True} if ntfy_notification_id else {}
|
||||
)
|
||||
|
||||
api.disconnect()
|
||||
print("SUCCESS")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: {str(e)}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
mode: '0755'
|
||||
|
||||
- name: Create temporary config for monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/ansible_config.yml
|
||||
content: |
|
||||
uptime_kuma_url: "{{ uptime_kuma_api_url }}"
|
||||
username: "{{ uptime_kuma_username }}"
|
||||
password: "{{ uptime_kuma_password }}"
|
||||
monitor_url: "https://{{ headscale_domain }}/health"
|
||||
monitor_name: "Headscale"
|
||||
mode: '0644'
|
||||
|
||||
- name: Run Uptime Kuma monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
command: python3 /tmp/setup_headscale_monitor.py
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
register: monitor_setup
|
||||
changed_when: "'SUCCESS' in monitor_setup.stdout"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clean up temporary files
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/setup_headscale_monitor.py
|
||||
- /tmp/ansible_config.yml
|
||||
|
||||
handlers:
|
||||
- name: Restart headscale
|
||||
become: yes
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
vars:
|
||||
lnbits_subdomain: "{{ subdomains.lnbits }}"
|
||||
lnbits_domain: "{{ lnbits_subdomain }}.{{ root_domain }}"
|
||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||
|
||||
tasks:
|
||||
- name: Create lnbits directory
|
||||
|
|
@ -152,123 +151,3 @@
|
|||
caddy_site_upstream: "localhost:{{ lnbits_port }}"
|
||||
caddy_site_headers_up:
|
||||
X-Forwarded-Host: "{{ lnbits_domain }}"
|
||||
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||
#
|
||||
# Every task below is inert: uptime_kuma_enabled is false in
|
||||
# group_vars/all/main.yml, so they all skip and the deployment above still
|
||||
# runs normally. Kept because the health-check logic is the durable part —
|
||||
# when a replacement exists, rewire the push transport and flip the flag.
|
||||
#
|
||||
# What was being monitored: archive/uptime_kuma/MONITORS.md
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
- name: Create Uptime Kuma monitor setup script for LNBits
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/setup_lnbits_monitor.py
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import yaml
|
||||
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
||||
|
||||
try:
|
||||
with open('/tmp/ansible_config.yml', 'r') as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
url = config['uptime_kuma_url']
|
||||
username = config['username']
|
||||
password = config['password']
|
||||
monitor_url = config['monitor_url']
|
||||
monitor_name = config['monitor_name']
|
||||
|
||||
api = UptimeKumaApi(url, timeout=30)
|
||||
api.login(username, password)
|
||||
|
||||
# Get all monitors
|
||||
monitors = api.get_monitors()
|
||||
|
||||
# Find or create "services" group
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
if not group:
|
||||
group_result = api.add_monitor(type='group', name='services')
|
||||
# Refresh to get the group with id
|
||||
monitors = api.get_monitors()
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
|
||||
# Check if monitor already exists
|
||||
existing_monitor = None
|
||||
for monitor in monitors:
|
||||
if monitor.get('name') == monitor_name:
|
||||
existing_monitor = monitor
|
||||
break
|
||||
|
||||
# Get ntfy notification ID
|
||||
notifications = api.get_notifications()
|
||||
ntfy_notification_id = None
|
||||
for notif in notifications:
|
||||
if notif.get('type') == 'ntfy':
|
||||
ntfy_notification_id = notif.get('id')
|
||||
break
|
||||
|
||||
if existing_monitor:
|
||||
print(f"Monitor '{monitor_name}' already exists (ID: {existing_monitor['id']})")
|
||||
print("Skipping - monitor already configured")
|
||||
else:
|
||||
print(f"Creating monitor '{monitor_name}'...")
|
||||
api.add_monitor(
|
||||
type=MonitorType.HTTP,
|
||||
name=monitor_name,
|
||||
url=monitor_url,
|
||||
parent=group['id'],
|
||||
interval=60,
|
||||
maxretries=3,
|
||||
retryInterval=60,
|
||||
notificationIDList={ntfy_notification_id: True} if ntfy_notification_id else {}
|
||||
)
|
||||
|
||||
api.disconnect()
|
||||
print("SUCCESS")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: {str(e)}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
mode: '0755'
|
||||
|
||||
- name: Create temporary config for monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/ansible_config.yml
|
||||
content: |
|
||||
uptime_kuma_url: "{{ uptime_kuma_api_url }}"
|
||||
username: "{{ uptime_kuma_username }}"
|
||||
password: "{{ uptime_kuma_password }}"
|
||||
monitor_url: "https://{{ lnbits_domain }}/api/v1/health"
|
||||
monitor_name: "LNBits"
|
||||
mode: '0644'
|
||||
|
||||
- name: Run Uptime Kuma monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
command: python3 /tmp/setup_lnbits_monitor.py
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
register: monitor_setup
|
||||
changed_when: "'SUCCESS' in monitor_setup.stdout"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clean up temporary files
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/setup_lnbits_monitor.py
|
||||
- /tmp/ansible_config.yml
|
||||
|
||||
|
|
|
|||
|
|
@ -62,14 +62,6 @@
|
|||
owner: root
|
||||
group: root
|
||||
|
||||
- name: Clean up temporary files
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/memos.tar.gz
|
||||
- /tmp/memos
|
||||
|
||||
- name: Create memos environment file
|
||||
copy:
|
||||
dest: "{{ memos_config_dir }}/memos.env"
|
||||
|
|
@ -136,18 +128,7 @@
|
|||
msg: "Memos is running on port {{ memos_port }}. Access via Tailscale at http://{{ memos_tailscale_hostname }}:{{ memos_port }}"
|
||||
|
||||
handlers:
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||
#
|
||||
# Every task below is inert: uptime_kuma_enabled is false in
|
||||
# group_vars/all/main.yml, so they all skip and the deployment above still
|
||||
# runs normally. Kept because the health-check logic is the durable part —
|
||||
# when a replacement exists, rewire the push transport and flip the flag.
|
||||
#
|
||||
# What was being monitored: archive/uptime_kuma/MONITORS.md
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
- name: Restart memos
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
systemd:
|
||||
name: memos
|
||||
state: restarted
|
||||
|
|
@ -161,7 +142,6 @@
|
|||
vars:
|
||||
memos_subdomain: "{{ subdomains.memos }}"
|
||||
memos_domain: "{{ memos_subdomain }}.{{ root_domain }}"
|
||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||
|
||||
tasks:
|
||||
- name: Publish Memos through Caddy (via Tailscale)
|
||||
|
|
@ -172,117 +152,3 @@
|
|||
caddy_site_domain: "{{ memos_domain }}"
|
||||
caddy_site_upstream: "{{ memos_tailscale_hostname }}:{{ memos_port }}"
|
||||
caddy_site_resolvers: "100.100.100.100"
|
||||
|
||||
- name: Create Uptime Kuma monitor setup script for Memos
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/setup_memos_monitor.py
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import traceback
|
||||
import yaml
|
||||
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
||||
|
||||
try:
|
||||
# Load configs
|
||||
with open('/tmp/ansible_memos_config.yml', 'r') as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
url = config['uptime_kuma_url']
|
||||
username = config['username']
|
||||
password = config['password']
|
||||
monitor_url = config['monitor_url']
|
||||
monitor_name = config['monitor_name']
|
||||
|
||||
# Connect to Uptime Kuma
|
||||
api = UptimeKumaApi(url, timeout=30)
|
||||
api.login(username, password)
|
||||
|
||||
# Get all monitors
|
||||
monitors = api.get_monitors()
|
||||
|
||||
# Find or create "services" group
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
if not group:
|
||||
group_result = api.add_monitor(type='group', name='services')
|
||||
# Refresh to get the group with id
|
||||
monitors = api.get_monitors()
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
|
||||
# Check if monitor already exists
|
||||
existing_monitor = None
|
||||
for monitor in monitors:
|
||||
if monitor.get('name') == monitor_name:
|
||||
existing_monitor = monitor
|
||||
break
|
||||
|
||||
# Get ntfy notification ID
|
||||
notifications = api.get_notifications()
|
||||
ntfy_notification_id = None
|
||||
for notif in notifications:
|
||||
if notif.get('type') == 'ntfy':
|
||||
ntfy_notification_id = notif.get('id')
|
||||
break
|
||||
|
||||
if existing_monitor:
|
||||
print(f"Monitor '{monitor_name}' already exists (ID: {existing_monitor['id']})")
|
||||
print("Skipping - monitor already configured")
|
||||
else:
|
||||
print(f"Creating monitor '{monitor_name}'...")
|
||||
api.add_monitor(
|
||||
type=MonitorType.HTTP,
|
||||
name=monitor_name,
|
||||
url=monitor_url,
|
||||
parent=group['id'],
|
||||
interval=60,
|
||||
maxretries=3,
|
||||
retryInterval=60,
|
||||
notificationIDList={ntfy_notification_id: True} if ntfy_notification_id else {}
|
||||
)
|
||||
|
||||
api.disconnect()
|
||||
print("SUCCESS")
|
||||
|
||||
except Exception as e:
|
||||
error_msg = str(e) if str(e) else repr(e)
|
||||
print(f"ERROR: {error_msg}", file=sys.stderr)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
sys.exit(1)
|
||||
mode: '0755'
|
||||
|
||||
- name: Create temporary config for monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/ansible_memos_config.yml
|
||||
content: |
|
||||
uptime_kuma_url: "{{ uptime_kuma_api_url }}"
|
||||
username: "{{ uptime_kuma_username }}"
|
||||
password: "{{ uptime_kuma_password }}"
|
||||
monitor_url: "https://{{ memos_domain }}/healthz"
|
||||
monitor_name: "Memos"
|
||||
mode: '0644'
|
||||
|
||||
- name: Run Uptime Kuma monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
command: python3 /tmp/setup_memos_monitor.py
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
register: monitor_setup
|
||||
changed_when: "'SUCCESS' in monitor_setup.stdout"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clean up temporary files
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/setup_memos_monitor.py
|
||||
- /tmp/ansible_memos_config.yml
|
||||
|
|
|
|||
|
|
@ -8,9 +8,12 @@
|
|||
# about Uptime Kuma — these are just "URLs that accept a ping", and whatever
|
||||
# replaces it sets the same values.
|
||||
mempool_healthchecks:
|
||||
- {name: mariadb, label: MariaDB, push_url: "{{ healthcheck_push_urls.mempool.mariadb | default('') }}"}
|
||||
- {name: backend, label: Backend, push_url: "{{ healthcheck_push_urls.mempool.backend | default('') }}"}
|
||||
- {name: frontend, label: Frontend, push_url: "{{ healthcheck_push_urls.mempool.frontend | default('') }}"}
|
||||
- {name: mariadb, label: MariaDB, push_url: "https://{{ subdomains.gatus }}.{{ root_domain }}/api/v1/endpoints/probe_mempool-mariadb/external"}
|
||||
- {name: backend, label: Backend, push_url: "https://{{ subdomains.gatus }}.{{ root_domain }}/api/v1/endpoints/probe_mempool-backend/external"}
|
||||
- {name: frontend, label: Frontend, push_url: "https://{{ subdomains.gatus }}.{{ root_domain }}/api/v1/endpoints/probe_mempool-frontend/external"}
|
||||
# One token for all three components: they run on the same host, so the
|
||||
# blast radius is already that host.
|
||||
healthcheck_push_token: "{{ gatus_push_tokens[inventory_hostname] }}"
|
||||
roles:
|
||||
- mempool
|
||||
|
||||
|
|
|
|||
|
|
@ -10,7 +10,6 @@
|
|||
ntfy_emergency_app_ntfy_url: "https://{{ ntfy_service_domain }}"
|
||||
ntfy_emergency_app_ntfy_user: "{{ ntfy_username | default('') }}"
|
||||
ntfy_emergency_app_ntfy_password: "{{ ntfy_password | default('') }}"
|
||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||
|
||||
tasks:
|
||||
- name: Create ntfy-emergency-app directory
|
||||
|
|
@ -52,127 +51,3 @@
|
|||
caddy_site_name: ntfy-emergency-app
|
||||
caddy_site_domain: "{{ ntfy_emergency_app_domain }}"
|
||||
caddy_site_upstream: "localhost:{{ ntfy_emergency_app_port }}"
|
||||
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||
#
|
||||
# Every task below is inert: uptime_kuma_enabled is false in
|
||||
# group_vars/all/main.yml, so they all skip and the deployment above still
|
||||
# runs normally. Kept because the health-check logic is the durable part —
|
||||
# when a replacement exists, rewire the push transport and flip the flag.
|
||||
#
|
||||
# What was being monitored: archive/uptime_kuma/MONITORS.md
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
- name: Create Uptime Kuma monitor setup script for ntfy-emergency-app
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/setup_ntfy_emergency_app_monitor.py
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import traceback
|
||||
import yaml
|
||||
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
||||
|
||||
try:
|
||||
# Load configs
|
||||
with open('/tmp/ansible_config.yml', 'r') as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
url = config['uptime_kuma_url']
|
||||
username = config['username']
|
||||
password = config['password']
|
||||
monitor_url = config['monitor_url']
|
||||
monitor_name = config['monitor_name']
|
||||
|
||||
# Connect to Uptime Kuma
|
||||
api = UptimeKumaApi(url, timeout=30)
|
||||
api.login(username, password)
|
||||
|
||||
# Get all monitors
|
||||
monitors = api.get_monitors()
|
||||
|
||||
# Find or create "services" group
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
if not group:
|
||||
group_result = api.add_monitor(type='group', name='services')
|
||||
# Refresh to get the group with id
|
||||
monitors = api.get_monitors()
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
|
||||
# Check if monitor already exists
|
||||
existing_monitor = None
|
||||
for monitor in monitors:
|
||||
if monitor.get('name') == monitor_name:
|
||||
existing_monitor = monitor
|
||||
break
|
||||
|
||||
# Get ntfy notification ID
|
||||
notifications = api.get_notifications()
|
||||
ntfy_notification_id = None
|
||||
for notif in notifications:
|
||||
if notif.get('type') == 'ntfy':
|
||||
ntfy_notification_id = notif.get('id')
|
||||
break
|
||||
|
||||
if existing_monitor:
|
||||
print(f"Monitor '{monitor_name}' already exists (ID: {existing_monitor['id']})")
|
||||
print("Skipping - monitor already configured")
|
||||
else:
|
||||
print(f"Creating monitor '{monitor_name}'...")
|
||||
api.add_monitor(
|
||||
type=MonitorType.HTTP,
|
||||
name=monitor_name,
|
||||
url=monitor_url,
|
||||
parent=group['id'],
|
||||
interval=60,
|
||||
maxretries=3,
|
||||
retryInterval=60,
|
||||
notificationIDList={ntfy_notification_id: True} if ntfy_notification_id else {}
|
||||
)
|
||||
|
||||
api.disconnect()
|
||||
print("SUCCESS")
|
||||
|
||||
except Exception as e:
|
||||
error_msg = str(e) if str(e) else repr(e)
|
||||
print(f"ERROR: {error_msg}", file=sys.stderr)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
sys.exit(1)
|
||||
mode: '0755'
|
||||
|
||||
- name: Create temporary config for monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/ansible_config.yml
|
||||
content: |
|
||||
uptime_kuma_url: "{{ uptime_kuma_api_url }}"
|
||||
username: "{{ uptime_kuma_username }}"
|
||||
password: "{{ uptime_kuma_password }}"
|
||||
monitor_url: "https://{{ ntfy_emergency_app_domain }}"
|
||||
monitor_name: "ntfy-emergency-app"
|
||||
mode: '0644'
|
||||
|
||||
- name: Run Uptime Kuma monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
command: python3 /tmp/setup_ntfy_emergency_app_monitor.py
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
register: monitor_setup
|
||||
changed_when: "'SUCCESS' in monitor_setup.stdout"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clean up temporary files
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/setup_ntfy_emergency_app_monitor.py
|
||||
- /tmp/ansible_config.yml
|
||||
|
|
|
|||
|
|
@ -1,164 +0,0 @@
|
|||
# ═════════════════════════════════════════════════════════════════════════════
|
||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||
#
|
||||
# This play WILL FAIL if run as-is, and that is deliberate: uptime_kuma_username
|
||||
# and uptime_kuma_password were removed from the vault, so the "Validate Uptime
|
||||
# Kuma configuration" assert stops it before anything is installed or changed.
|
||||
#
|
||||
# It is kept because the CHECK LOGIC is the durable part — what gets measured,
|
||||
# the thresholds, and the systemd timer plumbing. When something replaces Uptime
|
||||
# Kuma, only the push transport needs rewriting; the rest still applies.
|
||||
#
|
||||
# What was being monitored: archive/uptime_kuma/MONITORS.md
|
||||
# ═════════════════════════════════════════════════════════════════════════════
|
||||
- name: Setup ntfy as Uptime Kuma Notification Channel
|
||||
hosts: observability
|
||||
become: no
|
||||
vars_files:
|
||||
- ./ntfy_vars.yml
|
||||
|
||||
vars:
|
||||
ntfy_subdomain: "{{ subdomains.ntfy }}"
|
||||
uptime_kuma_subdomain: "{{ subdomains.uptime_kuma }}"
|
||||
ntfy_domain: "{{ ntfy_subdomain }}.{{ root_domain }}"
|
||||
ntfy_server_url: "https://{{ ntfy_domain }}"
|
||||
ntfy_priority: 4 # 1=min, 2=low, 3=default, 4=high, 5=max
|
||||
uptime_kuma_api_url: "https://{{ uptime_kuma_subdomain }}.{{ root_domain }}"
|
||||
|
||||
tasks:
|
||||
- name: Validate Uptime Kuma configuration
|
||||
assert:
|
||||
that:
|
||||
- uptime_kuma_api_url is defined
|
||||
- uptime_kuma_api_url != ""
|
||||
- uptime_kuma_username is defined
|
||||
- uptime_kuma_username != ""
|
||||
- uptime_kuma_password is defined
|
||||
- uptime_kuma_password != ""
|
||||
fail_msg: "uptime_kuma_api_url, uptime_kuma_username and uptime_kuma_password must be set"
|
||||
|
||||
- name: Validate ntfy configuration
|
||||
assert:
|
||||
that:
|
||||
- ntfy_domain is defined
|
||||
- ntfy_domain != ""
|
||||
- ntfy_topic is defined
|
||||
- ntfy_topic != ""
|
||||
- ntfy_username is defined
|
||||
- ntfy_username != ""
|
||||
- ntfy_password is defined
|
||||
- ntfy_password != ""
|
||||
fail_msg: "ntfy_domain, ntfy_topic, ntfy_username and ntfy_password must be set"
|
||||
|
||||
- name: Create Uptime Kuma ntfy notification setup script
|
||||
copy:
|
||||
dest: /tmp/setup_uptime_kuma_ntfy_notification.py
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import json
|
||||
from uptime_kuma_api import UptimeKumaApi
|
||||
|
||||
def main():
|
||||
api_url = sys.argv[1]
|
||||
username = sys.argv[2]
|
||||
password = sys.argv[3]
|
||||
notification_name = sys.argv[4]
|
||||
ntfy_server_url = sys.argv[5]
|
||||
ntfy_topic = sys.argv[6]
|
||||
ntfy_username = sys.argv[7]
|
||||
ntfy_password = sys.argv[8]
|
||||
ntfy_priority = int(sys.argv[9])
|
||||
|
||||
api = UptimeKumaApi(api_url, timeout=60, wait_events=2.0)
|
||||
api.login(username, password)
|
||||
|
||||
# Get all notifications
|
||||
notifications = api.get_notifications()
|
||||
|
||||
# Find existing ntfy notification by name
|
||||
existing_notification = next((n for n in notifications if n.get('name') == notification_name), None)
|
||||
|
||||
notification_data = {
|
||||
'name': notification_name,
|
||||
'type': 'ntfy',
|
||||
'isDefault': True, # Apply to all monitors by default
|
||||
'applyExisting': True, # Apply to existing monitors
|
||||
'ntfyserverurl': ntfy_server_url,
|
||||
'ntfytopic': ntfy_topic,
|
||||
'ntfyusername': ntfy_username,
|
||||
'ntfypassword': ntfy_password,
|
||||
'ntfyPriority': ntfy_priority
|
||||
}
|
||||
|
||||
if existing_notification:
|
||||
notification = api.edit_notification(existing_notification['id'], **notification_data)
|
||||
action = "updated"
|
||||
else:
|
||||
notification = api.add_notification(**notification_data)
|
||||
action = "created"
|
||||
|
||||
# Output result as JSON
|
||||
result = {
|
||||
'notification_id': notification['id'],
|
||||
'notification_name': notification_name,
|
||||
'ntfy_server': ntfy_server_url,
|
||||
'ntfy_topic': ntfy_topic,
|
||||
'action': action
|
||||
}
|
||||
print(json.dumps(result))
|
||||
|
||||
api.disconnect()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
mode: '0755'
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
- name: Run Uptime Kuma ntfy notification setup script
|
||||
command: >
|
||||
{{ ansible_playbook_python }}
|
||||
/tmp/setup_uptime_kuma_ntfy_notification.py
|
||||
"{{ uptime_kuma_api_url }}"
|
||||
"{{ uptime_kuma_username }}"
|
||||
"{{ uptime_kuma_password }}"
|
||||
"ntfy ({{ ntfy_topic }})"
|
||||
"{{ ntfy_server_url }}"
|
||||
"{{ ntfy_topic }}"
|
||||
"{{ ntfy_username }}"
|
||||
"{{ ntfy_password }}"
|
||||
"{{ ntfy_priority }}"
|
||||
register: notification_setup_result
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
changed_when: false
|
||||
|
||||
- name: Parse notification setup result
|
||||
set_fact:
|
||||
notification_info_parsed: "{{ notification_setup_result.stdout | from_json }}"
|
||||
|
||||
- name: Display notification information
|
||||
debug:
|
||||
msg: |
|
||||
✓ ntfy notification channel {{ notification_info_parsed.action }} successfully!
|
||||
|
||||
Notification Name: ntfy ({{ ntfy_topic }})
|
||||
ntfy Server: {{ ntfy_server_url }}
|
||||
ntfy Topic: {{ ntfy_topic }}
|
||||
Priority: {{ ntfy_priority }} (4=high)
|
||||
Default for all monitors: Yes
|
||||
Applied to existing monitors: Yes
|
||||
|
||||
All Uptime Kuma monitors will now send alerts to your ntfy server
|
||||
on the "{{ ntfy_topic }}" topic.
|
||||
|
||||
You can subscribe to alerts at: {{ ntfy_server_url }}/{{ ntfy_topic }}
|
||||
|
||||
- name: Clean up temporary Uptime Kuma setup script
|
||||
file:
|
||||
path: /tmp/setup_uptime_kuma_ntfy_notification.py
|
||||
state: absent
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
|
|
@ -6,7 +6,6 @@
|
|||
vars:
|
||||
personal_blog_subdomain: "{{ subdomains.personal_blog }}"
|
||||
personal_blog_domain: "{{ personal_blog_subdomain }}.{{ root_domain }}"
|
||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||
|
||||
tasks:
|
||||
- name: Ensure user is in www-data group
|
||||
|
|
@ -54,123 +53,3 @@
|
|||
caddy_site_name: personal-blog
|
||||
caddy_site_domain: "{{ personal_blog_domain }}"
|
||||
caddy_site_root: "{{ personal_blog_web_root }}"
|
||||
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||
#
|
||||
# Every task below is inert: uptime_kuma_enabled is false in
|
||||
# group_vars/all/main.yml, so they all skip and the deployment above still
|
||||
# runs normally. Kept because the health-check logic is the durable part —
|
||||
# when a replacement exists, rewire the push transport and flip the flag.
|
||||
#
|
||||
# What was being monitored: archive/uptime_kuma/MONITORS.md
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
- name: Create Uptime Kuma monitor setup script for Personal Blog
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/setup_personal_blog_monitor.py
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import yaml
|
||||
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
||||
|
||||
try:
|
||||
with open('/tmp/ansible_config.yml', 'r') as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
url = config['uptime_kuma_url']
|
||||
username = config['username']
|
||||
password = config['password']
|
||||
monitor_url = config['monitor_url']
|
||||
monitor_name = config['monitor_name']
|
||||
|
||||
api = UptimeKumaApi(url, timeout=30)
|
||||
api.login(username, password)
|
||||
|
||||
# Get all monitors
|
||||
monitors = api.get_monitors()
|
||||
|
||||
# Find or create "services" group
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
if not group:
|
||||
group_result = api.add_monitor(type='group', name='services')
|
||||
# Refresh to get the group with id
|
||||
monitors = api.get_monitors()
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
|
||||
# Check if monitor already exists
|
||||
existing_monitor = None
|
||||
for monitor in monitors:
|
||||
if monitor.get('name') == monitor_name:
|
||||
existing_monitor = monitor
|
||||
break
|
||||
|
||||
# Get ntfy notification ID
|
||||
notifications = api.get_notifications()
|
||||
ntfy_notification_id = None
|
||||
for notif in notifications:
|
||||
if notif.get('type') == 'ntfy':
|
||||
ntfy_notification_id = notif.get('id')
|
||||
break
|
||||
|
||||
if existing_monitor:
|
||||
print(f"Monitor '{monitor_name}' already exists (ID: {existing_monitor['id']})")
|
||||
print("Skipping - monitor already configured")
|
||||
else:
|
||||
print(f"Creating monitor '{monitor_name}'...")
|
||||
api.add_monitor(
|
||||
type=MonitorType.HTTP,
|
||||
name=monitor_name,
|
||||
url=monitor_url,
|
||||
parent=group['id'],
|
||||
interval=60,
|
||||
maxretries=3,
|
||||
retryInterval=60,
|
||||
notificationIDList={ntfy_notification_id: True} if ntfy_notification_id else {}
|
||||
)
|
||||
|
||||
api.disconnect()
|
||||
print("SUCCESS")
|
||||
|
||||
except Exception as e:
|
||||
print(f"ERROR: {str(e)}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
mode: '0755'
|
||||
|
||||
- name: Create temporary config for monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/ansible_config.yml
|
||||
content: |
|
||||
uptime_kuma_url: "{{ uptime_kuma_api_url }}"
|
||||
username: "{{ uptime_kuma_username }}"
|
||||
password: "{{ uptime_kuma_password }}"
|
||||
monitor_url: "https://{{ personal_blog_domain }}"
|
||||
monitor_name: "Personal Blog"
|
||||
mode: '0644'
|
||||
|
||||
- name: Run Uptime Kuma monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
command: python3 /tmp/setup_personal_blog_monitor.py
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
register: monitor_setup
|
||||
changed_when: "'SUCCESS' in monitor_setup.stdout"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clean up temporary files
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/setup_personal_blog_monitor.py
|
||||
- /tmp/ansible_config.yml
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
# decommissioning — its systemd Environment= was left empty. Leaving it empty
|
||||
# preserves that; the check still runs and its exit code is still the answer.
|
||||
# Set this to plug in whatever monitoring replaces it.
|
||||
healthcheck_push_url: "{{ healthcheck_push_urls.phoenixd | default('') }}"
|
||||
healthcheck_push_url: "https://{{ subdomains.gatus }}.{{ root_domain }}/api/v1/endpoints/probe_phoenixd/external"
|
||||
healthcheck_push_token: "{{ gatus_push_tokens[inventory_hostname] }}"
|
||||
roles:
|
||||
- phoenixd
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
vars:
|
||||
vaultwarden_subdomain: "{{ subdomains.vaultwarden }}"
|
||||
vaultwarden_domain: "{{ vaultwarden_subdomain }}.{{ root_domain }}"
|
||||
uptime_kuma_api_url: "https://{{ subdomains.uptime_kuma }}.{{ root_domain }}"
|
||||
|
||||
tasks:
|
||||
- name: Create vaultwarden directory
|
||||
|
|
@ -84,128 +83,3 @@
|
|||
caddy_site_name: vaultwarden
|
||||
caddy_site_domain: "{{ vaultwarden_domain }}"
|
||||
caddy_site_upstream: "localhost:{{ vaultwarden_port }}"
|
||||
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
# DEPRECATED — Uptime Kuma was decommissioned on 2026-09-11.
|
||||
#
|
||||
# Every task below is inert: uptime_kuma_enabled is false in
|
||||
# group_vars/all/main.yml, so they all skip and the deployment above still
|
||||
# runs normally. Kept because the health-check logic is the durable part —
|
||||
# when a replacement exists, rewire the push transport and flip the flag.
|
||||
#
|
||||
# What was being monitored: archive/uptime_kuma/MONITORS.md
|
||||
# ═════════════════════════════════════════════════════════════════════════
|
||||
- name: Create Uptime Kuma monitor setup script for Vaultwarden
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/setup_vaultwarden_monitor.py
|
||||
content: |
|
||||
#!/usr/bin/env python3
|
||||
import sys
|
||||
import traceback
|
||||
import yaml
|
||||
from uptime_kuma_api import UptimeKumaApi, MonitorType
|
||||
|
||||
try:
|
||||
# Load configs
|
||||
with open('/tmp/ansible_config.yml', 'r') as f:
|
||||
config = yaml.safe_load(f)
|
||||
|
||||
url = config['uptime_kuma_url']
|
||||
username = config['username']
|
||||
password = config['password']
|
||||
monitor_url = config['monitor_url']
|
||||
monitor_name = config['monitor_name']
|
||||
|
||||
# Connect to Uptime Kuma
|
||||
api = UptimeKumaApi(url, timeout=30)
|
||||
api.login(username, password)
|
||||
|
||||
# Get all monitors
|
||||
monitors = api.get_monitors()
|
||||
|
||||
# Find or create "services" group
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
if not group:
|
||||
group_result = api.add_monitor(type='group', name='services')
|
||||
# Refresh to get the group with id
|
||||
monitors = api.get_monitors()
|
||||
group = next((m for m in monitors if m.get('name') == 'services' and m.get('type') == 'group'), None)
|
||||
|
||||
# Check if monitor already exists
|
||||
existing_monitor = None
|
||||
for monitor in monitors:
|
||||
if monitor.get('name') == monitor_name:
|
||||
existing_monitor = monitor
|
||||
break
|
||||
|
||||
# Get ntfy notification ID
|
||||
notifications = api.get_notifications()
|
||||
ntfy_notification_id = None
|
||||
for notif in notifications:
|
||||
if notif.get('type') == 'ntfy':
|
||||
ntfy_notification_id = notif.get('id')
|
||||
break
|
||||
|
||||
if existing_monitor:
|
||||
print(f"Monitor '{monitor_name}' already exists (ID: {existing_monitor['id']})")
|
||||
print("Skipping - monitor already configured")
|
||||
else:
|
||||
print(f"Creating monitor '{monitor_name}'...")
|
||||
api.add_monitor(
|
||||
type=MonitorType.HTTP,
|
||||
name=monitor_name,
|
||||
url=monitor_url,
|
||||
parent=group['id'],
|
||||
interval=60,
|
||||
maxretries=3,
|
||||
retryInterval=60,
|
||||
notificationIDList={ntfy_notification_id: True} if ntfy_notification_id else {}
|
||||
)
|
||||
|
||||
api.disconnect()
|
||||
print("SUCCESS")
|
||||
|
||||
except Exception as e:
|
||||
error_msg = str(e) if str(e) else repr(e)
|
||||
print(f"ERROR: {error_msg}", file=sys.stderr)
|
||||
traceback.print_exc(file=sys.stderr)
|
||||
sys.exit(1)
|
||||
mode: '0755'
|
||||
|
||||
- name: Create temporary config for monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
copy:
|
||||
dest: /tmp/ansible_config.yml
|
||||
content: |
|
||||
uptime_kuma_url: "{{ uptime_kuma_api_url }}"
|
||||
username: "{{ uptime_kuma_username }}"
|
||||
password: "{{ uptime_kuma_password }}"
|
||||
monitor_url: "https://{{ vaultwarden_domain }}/alive"
|
||||
monitor_name: "Vaultwarden"
|
||||
mode: '0644'
|
||||
|
||||
- name: Run Uptime Kuma monitor setup
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
command: python3 /tmp/setup_vaultwarden_monitor.py
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
register: monitor_setup
|
||||
changed_when: "'SUCCESS' in monitor_setup.stdout"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Clean up temporary files
|
||||
when: uptime_kuma_enabled | default(false)
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
file:
|
||||
path: "{{ item }}"
|
||||
state: absent
|
||||
loop:
|
||||
- /tmp/setup_vaultwarden_monitor.py
|
||||
- /tmp/ansible_config.yml
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue