New namespaced CRD KumaStatusPage (uptime.renner.uno/v1alpha1) and a reconciler that owns the Kuma status page completely: config, domain names and the full group/monitor list. Sections select KumaMonitors in any namespace by label; monitors are ordered by displayName, then namespace/name, a monitor goes to the first matching section only, and monitors without a Kuma ID are left out and counted in status. The reconciler adopts an existing page with the slug, writes only when the managed content differs (no write per resync), reuses Kuma group IDs by position so saves do not churn them, reverts UI edits on resync, deletes the page on resource deletion, and reports Ready=False/Conflict for a younger resource claiming the same slug. Every KumaMonitor change to labels, displayName, monitor ID or deletion enqueues all pages. kumaclient gains a StatusPages interface (Breml + Fake). The socket API returns no group list, so groups are read from Kuma's public GET /api/status-page/<slug>, as the bootstrap did. Fields kuma-sync does not manage (logo, custom CSS, analytics, RSS title, auto refresh interval) are written back unchanged. autoRefreshInterval is not in the spec: go-uptime-kuma-client v0.6.2 (latest) never sends it on save. The Ansible bootstrap no longer creates or edits status pages; the existing page is left in place for kuma-sync to adopt. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
220 lines
6.7 KiB
YAML
220 lines
6.7 KiB
YAML
---
|
|
# Admin bootstrap runs with the Traefik route disabled so /setup is never
|
|
# reachable from outside; the route is enabled once the admin exists.
|
|
|
|
- name: Read admin credentials from OpenBao
|
|
community.hashi_vault.vault_kv2_get:
|
|
url: "{{ uptime_kuma_openbao_url }}"
|
|
engine_mount_point: "{{ uptime_kuma_openbao_mount }}"
|
|
path: "{{ uptime_kuma_openbao_path }}"
|
|
auth_method: token
|
|
delegate_to: localhost
|
|
become: false
|
|
run_once: true
|
|
register: _uptime_kuma_secret
|
|
no_log: true
|
|
|
|
- name: Read SMTP credentials from OpenBao
|
|
community.hashi_vault.vault_kv2_get:
|
|
url: "{{ uptime_kuma_openbao_url }}"
|
|
engine_mount_point: "{{ uptime_kuma_openbao_mount }}"
|
|
path: "{{ uptime_kuma_openbao_smtp_path }}"
|
|
auth_method: token
|
|
delegate_to: localhost
|
|
become: false
|
|
run_once: true
|
|
register: _uptime_kuma_smtp
|
|
no_log: true
|
|
|
|
- name: Read metrics API key from OpenBao
|
|
community.hashi_vault.vault_kv2_get:
|
|
url: "{{ uptime_kuma_openbao_url }}"
|
|
engine_mount_point: "{{ uptime_kuma_openbao_mount }}"
|
|
path: "{{ uptime_kuma_openbao_metrics_path }}"
|
|
auth_method: token
|
|
delegate_to: localhost
|
|
become: false
|
|
run_once: true
|
|
register: _uptime_kuma_metrics_secret
|
|
failed_when:
|
|
- _uptime_kuma_metrics_secret.failed | default(false)
|
|
- "'Invalid or missing path' not in (_uptime_kuma_metrics_secret.msg | default(''))"
|
|
no_log: true
|
|
|
|
- name: Ensure Uptime Kuma directories exist
|
|
ansible.builtin.file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
mode: "0755"
|
|
loop:
|
|
- "{{ uptime_kuma_dir }}"
|
|
- "{{ uptime_kuma_dir }}/data"
|
|
- "{{ uptime_kuma_dir }}/setup"
|
|
|
|
- name: Deploy kuma-setup.js
|
|
ansible.builtin.copy:
|
|
src: kuma-setup.js
|
|
dest: "{{ uptime_kuma_dir }}/setup/kuma-setup.js"
|
|
mode: "0644"
|
|
|
|
- name: Check for setup marker
|
|
ansible.builtin.stat:
|
|
path: "{{ uptime_kuma_dir }}/data/.setup-done"
|
|
register: _uptime_kuma_marker
|
|
|
|
- name: Deploy docker-compose.yml
|
|
ansible.builtin.template:
|
|
src: docker-compose.yml.j2
|
|
dest: "{{ uptime_kuma_dir }}/docker-compose.yml"
|
|
mode: "0644"
|
|
vars:
|
|
uptime_kuma_route_enabled: "{{ _uptime_kuma_marker.stat.exists }}"
|
|
|
|
- name: Pull Uptime Kuma image
|
|
ansible.builtin.command: docker compose pull
|
|
args:
|
|
chdir: "{{ uptime_kuma_dir }}"
|
|
changed_when: false
|
|
|
|
- name: Start Uptime Kuma
|
|
ansible.builtin.command: docker compose up -d
|
|
args:
|
|
chdir: "{{ uptime_kuma_dir }}"
|
|
changed_when: false
|
|
|
|
- name: Remove the script from its former single-file mount path
|
|
ansible.builtin.file:
|
|
path: "{{ uptime_kuma_dir }}/kuma-setup.js"
|
|
state: absent
|
|
|
|
- name: Wait for Uptime Kuma on loopback
|
|
ansible.builtin.uri:
|
|
url: http://127.0.0.1:3001
|
|
status_code: 200
|
|
register: _uptime_kuma_up
|
|
until: _uptime_kuma_up.status == 200
|
|
retries: 30
|
|
delay: 5
|
|
|
|
- name: Check the stored metrics API key against Uptime Kuma
|
|
ansible.builtin.uri:
|
|
url: http://127.0.0.1:3001/metrics
|
|
headers:
|
|
Authorization: "Basic {{ (':' ~ _uptime_kuma_metrics_key) | b64encode }}"
|
|
status_code: [200, 401]
|
|
vars:
|
|
_uptime_kuma_metrics_key: "{{ (_uptime_kuma_metrics_secret.secret | default({})).api_key | default('') }}"
|
|
when: _uptime_kuma_metrics_key | length > 0
|
|
register: _uptime_kuma_metrics_check
|
|
no_log: true
|
|
|
|
- name: Remove a leftover metrics API key handoff file
|
|
ansible.builtin.file:
|
|
path: "{{ uptime_kuma_dir }}/data/.metrics-api-key"
|
|
state: absent
|
|
|
|
- name: Bootstrap Uptime Kuma
|
|
ansible.builtin.command:
|
|
argv:
|
|
- docker
|
|
- compose
|
|
- exec
|
|
- -T
|
|
- -e
|
|
- KUMA_SETUP_USERNAME
|
|
- -e
|
|
- KUMA_SETUP_PASSWORD
|
|
- -e
|
|
- KUMA_BASE_URL
|
|
- -e
|
|
- KUMA_SMTP_HOST
|
|
- -e
|
|
- KUMA_SMTP_PORT
|
|
- -e
|
|
- KUMA_SMTP_USERNAME
|
|
- -e
|
|
- KUMA_SMTP_PASSWORD
|
|
- -e
|
|
- KUMA_SMTP_FROM
|
|
- -e
|
|
- KUMA_SMTP_TO
|
|
- -e
|
|
- KUMA_METRICS_ROTATE
|
|
- -e
|
|
- KUMA_METRICS_KEY_FILE
|
|
- uptime-kuma
|
|
- node
|
|
- /app/setup/kuma-setup.js
|
|
args:
|
|
chdir: "{{ uptime_kuma_dir }}"
|
|
environment:
|
|
KUMA_SETUP_USERNAME: "{{ _uptime_kuma_secret.secret.username }}"
|
|
KUMA_SETUP_PASSWORD: "{{ _uptime_kuma_secret.secret.password }}"
|
|
KUMA_BASE_URL: "{{ uptime_kuma_base_url }}"
|
|
KUMA_SMTP_HOST: "{{ _uptime_kuma_smtp.secret.server }}"
|
|
KUMA_SMTP_PORT: "{{ _uptime_kuma_smtp.secret.port }}"
|
|
KUMA_SMTP_USERNAME: "{{ _uptime_kuma_smtp.secret.username }}"
|
|
KUMA_SMTP_PASSWORD: "{{ _uptime_kuma_smtp.secret.token }}"
|
|
KUMA_SMTP_FROM: "{{ uptime_kuma_smtp_from }}"
|
|
KUMA_SMTP_TO: "{{ uptime_kuma_smtp_to }}"
|
|
KUMA_METRICS_ROTATE: "{{ 'false' if (_uptime_kuma_metrics_check.status | default(0)) == 200 else 'true' }}"
|
|
KUMA_METRICS_KEY_FILE: /app/data/.metrics-api-key
|
|
register: _uptime_kuma_setup
|
|
changed_when: "'admin user created' in _uptime_kuma_setup.stdout or 'changed:' in _uptime_kuma_setup.stdout"
|
|
failed_when: false
|
|
no_log: true
|
|
|
|
- name: Fail if Uptime Kuma setup failed
|
|
ansible.builtin.fail:
|
|
msg: "kuma-setup.js failed: rc={{ _uptime_kuma_setup.rc | default('undefined') }} stdout={{ _uptime_kuma_setup.stdout | default('') }} stderr={{ _uptime_kuma_setup.stderr | default('') }}"
|
|
when: (_uptime_kuma_setup.rc | default(1)) != 0
|
|
|
|
- name: Store the new metrics API key in OpenBao
|
|
when: "'changed: metrics api key' in _uptime_kuma_setup.stdout"
|
|
block:
|
|
- name: Read the new metrics API key
|
|
ansible.builtin.slurp:
|
|
src: "{{ uptime_kuma_dir }}/data/.metrics-api-key"
|
|
register: _uptime_kuma_new_metrics_key
|
|
no_log: true
|
|
|
|
- name: Write the metrics API key to OpenBao
|
|
community.hashi_vault.vault_kv2_write:
|
|
url: "{{ uptime_kuma_openbao_url }}"
|
|
engine_mount_point: "{{ uptime_kuma_openbao_mount }}"
|
|
path: "{{ uptime_kuma_openbao_metrics_path }}"
|
|
auth_method: token
|
|
data:
|
|
api_key: "{{ _uptime_kuma_new_metrics_key.content | b64decode }}"
|
|
delegate_to: localhost
|
|
become: false
|
|
run_once: true
|
|
no_log: true
|
|
always:
|
|
- name: Remove the metrics API key handoff file
|
|
ansible.builtin.file:
|
|
path: "{{ uptime_kuma_dir }}/data/.metrics-api-key"
|
|
state: absent
|
|
|
|
- name: Record setup completion
|
|
ansible.builtin.copy:
|
|
content: ""
|
|
dest: "{{ uptime_kuma_dir }}/data/.setup-done"
|
|
mode: "0644"
|
|
force: false
|
|
|
|
- name: Deploy docker-compose.yml with the route enabled
|
|
ansible.builtin.template:
|
|
src: docker-compose.yml.j2
|
|
dest: "{{ uptime_kuma_dir }}/docker-compose.yml"
|
|
mode: "0644"
|
|
vars:
|
|
uptime_kuma_route_enabled: true
|
|
|
|
- name: Start Uptime Kuma with the route enabled
|
|
ansible.builtin.command: docker compose up -d
|
|
args:
|
|
chdir: "{{ uptime_kuma_dir }}"
|
|
register: _uptime_kuma_route
|
|
changed_when: "'Recreate' in _uptime_kuma_route.stderr or 'Started' in _uptime_kuma_route.stderr"
|