No description
  • Go 93%
  • Shell 2.6%
  • Just 2.3%
  • Dockerfile 1.4%
  • Go Template 0.7%
Find a file
wuast94 f9052a9a77
All checks were successful
Release / Check if release needed (push) Successful in 16s
Release / Release (push) Successful in 4m24s
Merge pull request 'chore: update go dependencies' (#172) from updatarr/go-dependencies-c171078cda into main
2026-08-13 22:56:18 +02:00
.devcontainer chore: update go dependencies 2026-08-13 22:38:16 +02:00
.forgejo/workflows chore: update github actions 2026-07-31 10:46:47 +02:00
.githooks ci: add comprehensive check target to pre-commit hook and Justfile 2026-04-03 03:05:27 +02:00
api/v1alpha1 feat: support Uptime Kuma 2.4.0 2026-06-01 19:20:04 +02:00
cmd/operator chore: remove sbom and dependency-track 2026-07-23 00:57:32 +02:00
docs chore: remove sbom and dependency-track 2026-07-23 00:57:32 +02:00
hack chore: remove sbom and dependency-track 2026-07-23 00:57:32 +02:00
helm/kumaste fix: stop self-referencing release updates 2026-07-23 00:46:54 +02:00
internal chore: remove sbom and dependency-track 2026-07-23 00:57:32 +02:00
scripts chore: remove sbom and dependency-track 2026-07-23 00:57:32 +02:00
test/e2e feat: support Uptime Kuma 2.4.0 2026-06-01 19:20:04 +02:00
uptime-kuma@41ecaf17bd chore: update uptime-kuma to 41ecaf17bdda1a16285dd1f164ba67ff7ad54fd3 2026-08-13 14:41:03 +02:00
.dockerignore fix: build e2e runner image 2026-06-19 15:07:27 +02:00
.gitignore chore: codebase cleanup 2026-03-27 22:20:00 +01:00
.gitmodules chore: define uptime kuma submodule 2026-07-21 14:40:16 +02:00
.golangci.yml feat(core): CI workflow and add E2E testing infrastructure 2026-03-26 08:39:32 +01:00
.updatarr.yaml chore: remove sbom and dependency-track 2026-07-23 00:57:32 +02:00
CHANGELOG.md chore(release): 1.5.8 [skip ci] 2026-03-29 04:01:47 +00:00
CLAUDE.md fix: stop self-referencing release updates 2026-07-23 00:46:54 +02:00
cliff.toml ci: migrate from semantic-release to git-cliff and consolidate workflows 2026-03-29 14:13:21 +02:00
docker-compose.yaml chore: update louislam/uptime-kuma to 2.5.0 2026-08-01 12:34:48 +02:00
Dockerfile chore: update go dependencies 2026-08-13 22:38:16 +02:00
Dockerfile.e2e chore: update go dependencies 2026-08-13 22:38:16 +02:00
go.mod chore: update go dependencies 2026-08-13 14:03:42 +02:00
go.sum chore: update go dependencies 2026-08-13 14:03:42 +02:00
Justfile chore: remove sbom and dependency-track 2026-07-23 00:57:32 +02:00
README.md feat: support Uptime Kuma 2.4.0 2026-06-01 19:20:04 +02:00
renovate.json chore: remove sbom and dependency-track 2026-07-23 00:57:32 +02:00
uptime-kuma-2.2.1-to-2.3.0.diff feat: add support for Uptime Kuma 2.3.0 monitor types and notification providers 2026-05-02 12:42:15 +02:00

kuma-operator

A Kubernetes operator that syncs Uptime Kuma monitors, notification providers, and tags as Kubernetes custom resources. Define your monitoring setup as code alongside your services — the operator creates, updates, and deletes everything in Uptime Kuma automatically.

Overview

The operator manages three custom resource types:

Resource Short name Purpose
UptimeKumaMonitor ukm A monitor (HTTP, ping, TCP, DNS, …)
UptimeKumaNotification A notification provider (Discord, Slack, webhook, …)
UptimeKumaTag A tag for labelling monitors

Monitors reference notification providers and tags by name, so you can declare everything in the same namespace as your service.

Installation

helm install kumaste oci://harbor.wuastbude.de/kumaste/kumaste \
  --namespace monitoring \
  --create-namespace \
  --set uptimeKuma.url=http://uptimekuma.monitoring.svc:3001 \
  --set uptimeKuma.username=admin \
  --set uptimeKuma.password=secret

Or with an existing Secret:

helm install kumaste oci://harbor.wuastbude.de/kumaste/kumaste \
  --namespace monitoring \
  --create-namespace \
  --set uptimeKuma.existingSecret=my-uptimekuma-creds

The Secret must contain the keys UPTIME_KUMA_URL, UPTIME_KUMA_USERNAME, and UPTIME_KUMA_PASSWORD.

Helm values

Value Default Description
uptimeKuma.url "" Required. URL of the Uptime Kuma instance
uptimeKuma.username "" Admin username
uptimeKuma.password "" Admin password
uptimeKuma.existingSecret "" Use a pre-existing Secret instead
syncInterval 60s How often to re-reconcile for drift detection
watchNamespaces [] Namespaces to watch; empty = cluster-wide
replicaCount 1 Number of operator replicas
resources {} CPU/memory requests and limits

UptimeKumaMonitor

Manages a single monitor in Uptime Kuma.

apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaMonitor
metadata:
  name: myapp
  namespace: myapp-ns
spec:
  type: http
  url: "https://myapp.example.com"
  interval: 60

Common fields

Field Default Description
name metadata.name Display name in Uptime Kuma
description "" Optional description
type http Monitor type (see below)
active true Whether the monitor runs
upsideDown false Invert status logic
interval 60 Check interval in seconds (min 20)
retryInterval 60 Retry interval when down (min 20)
maxRetries 1 Retries before marking down
resendInterval 0 Re-notify every N failed checks (0 = off)
timeout null Request timeout in seconds
parentName "" Display name of a group monitor to nest under
notifications [] Notification provider names to attach
tags [] Tags to attach (name + optional value)

Monitor types

http — HTTP/HTTPS endpoint

spec:
  type: http
  url: "https://example.com"
  method: GET                    # GET POST PUT PATCH DELETE HEAD OPTIONS
  acceptedStatuscodes: ["200-299"]
  maxRedirects: 10
  ignoreTls: false
  expiryNotification: false      # alert on TLS cert expiry
  domainExpiryNotification: false
  cacheBust: false
  saveResponse: false
  saveErrorResponse: false
  ipFamily: 0                    # 0=auto 4=IPv4 6=IPv6
  # HTTP Basic Auth
  basicAuthUser: ""
  basicAuthPass: ""
  # Bearer token auth
  authMethod: bearer
  bearerToken: ""
  # Custom request body
  httpBody: '{"key":"value"}'
  httpBodyEncoding: json         # json xml x-www-form-urlencoded form-data text
  # Custom headers (map)
  httpHeaders:
    X-API-Key: secret
    Accept: application/json

keyword — HTTP + keyword matching

All http fields apply, plus:

spec:
  type: keyword
  url: "https://example.com"
  keyword: "OK"
  invertKeyword: false           # true = alert when keyword IS found

json-query — HTTP + JSONPath assertion

All http fields apply, plus:

spec:
  type: json-query
  url: "https://api.example.com/health"
  jsonPath: "$.status"
  jsonPathOperator: "=="
  expectedValue: "ok"

ping — ICMP ping

spec:
  type: ping
  hostname: "1.1.1.1"
  packetSize: 56

tcp — TCP port check

spec:
  type: tcp
  hostname: "db.example.com"
  port: 5432

dns — DNS record check

spec:
  type: dns
  hostname: "example.com"
  dnsResolveType: A              # A AAAA MX NS CNAME PTR TXT SOA CAA
  dnsResolveServer: "1.1.1.1"
  expectedValue: "93.184.216.34"

push — Push monitor (heartbeat)

The operator creates the monitor; your service pings its push URL periodically.

spec:
  type: push
  interval: 60

docker — Docker container state

spec:
  type: docker
  dockerContainer: "my-container-name"
  dockerHostID: 1                # Docker host configured in Uptime Kuma

mqtt — MQTT topic

spec:
  type: mqtt
  hostname: "mqtt.example.com"
  port: 1883
  mqttTopic: "home/sensor/temperature"
  mqttSuccessMessage: "ok"
  mqttUsername: "user"
  mqttPassword: "pass"

smtp — SMTP connectivity

spec:
  type: smtp
  hostname: "smtp.example.com"
  port: 587
  smtpSecurity: STARTTLS         # STARTTLS TLS NONE

grpc-keyword — gRPC method response keyword

spec:
  type: grpc-keyword
  grpcUrl: "grpc.example.com:443"
  grpcProtobuf: |
    syntax = "proto3";
    service Health { rpc Check(Request) returns (Response); }
    message Request {}
    message Response { string status = 1; }
  grpcServiceName: Health
  grpcMethod: Check
  grpcBody: "{}"
  grpcEnableTls: true
  keyword: "SERVING"

sqlserver / postgres / mysql / mongodb / redis — Database monitors

spec:
  type: postgres
  databaseConnectionString: "postgres://user:pass@db.example.com:5432/mydb"
  databaseQuery: "SELECT 1"      # optional query to execute

kafka-producer — Kafka producer test

spec:
  type: kafka-producer
  kafkaProducerTopic: "health-check"
  kafkaProducerBrokers: ["kafka.example.com:9092"]
  kafkaProducerMessage: "ping"
  kafkaProducerSsl: false
  kafkaProducerAllowAutoTopicCreation: false
  kafkaProducerSaslOptions:
    mechanism: plain
    username: user
    password: pass

rabbit-mq — RabbitMQ management API

spec:
  type: rabbit-mq
  rabbitmqNodes: ["https://rabbitmq.example.com:15672"]
  rabbitmqUsername: admin
  rabbitmqPassword: secret

snmp — SNMP OID poll

spec:
  type: snmp
  hostname: "switch.example.com"
  snmpVersion: "2c"
  snmpOid: "1.3.6.1.2.1.1.1.0"
  expectedValue: "Linux"

radius — RADIUS authentication test

spec:
  type: radius
  hostname: "radius.example.com"
  port: 1812
  radiusUsername: testuser
  radiusPassword: testpass
  radiusSecret: sharedsecret
  radiusCalledStationId: "00-11-22-33-44-55"
  radiusCallingStationId: "66-77-88-99-AA-BB"

gamedig — Game server query

spec:
  type: gamedig
  hostname: "gameserver.example.com"
  port: 27015
  game: tf2
  gamedigToken: ""

real-browser — Headless browser check

spec:
  type: real-browser
  url: "https://example.com"
  remoteBrowser: "my-remote-browser-id"

group — Monitor group

Groups do not perform checks; they serve as containers for other monitors.

spec:
  type: group
  name: "Production Services"

Nest monitors inside a group via parentName:

spec:
  type: http
  url: "https://api.example.com"
  parentName: "Production Services"

manual — Manually controlled status

spec:
  type: manual
  manualStatus: 1                # 1=up 0=down

Tags

Attach tags by name with an optional value string:

spec:
  tags:
    - name: environment
      value: production
    - name: team

The tag must exist (created via UptimeKumaTag) before a monitor can reference it.

Notifications

Attach notification providers by name:

spec:
  notifications:
    - discord-alerts
    - pagerduty-critical

The providers must exist (created via UptimeKumaNotification) before the monitor is reconciled.

Status

status:
  monitorID: 42
  conditions:
    - type: Synced
      status: "True"
      reason: MonitorSynced
      message: "Monitor successfully synced to Uptime Kuma"
      lastTransitionTime: "2025-01-01T00:00:00Z"

UptimeKumaNotification

Manages a notification provider in Uptime Kuma.

apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaNotification
metadata:
  name: discord-alerts
  namespace: monitoring
spec:
  type: discord
  active: true
  config:
    discordWebhookUrl: "https://discord.com/api/webhooks/123/abc"
    discordUsername: "Uptime Kuma"

Fields

Field Description
name Display name in Uptime Kuma (defaults to metadata.name)
type Provider type (see below)
active Whether this provider is enabled
isDefault Auto-attach to newly created monitors
config Provider-specific key-value pairs (flat map)

Provider types and config keys

All config values are sent flat to the Uptime Kuma API at the same level as name and type. The keys must match Uptime Kuma's internal field names exactly.

discord

Key Description
discordWebhookUrl Discord webhook URL
discordUsername Bot display name
discordPrefixMessage Message prefix text

slack

Key Description
slackwebhookURL Slack incoming webhook URL
slackusername Bot username
slackchannel Channel (e.g. #alerts)
slackiconemo Emoji icon (e.g. :white_check_mark:)

telegram

Key Description
telegramBotToken Bot API token
telegramChatID Chat or group ID
telegramSendSilently "true" to suppress notification sound
telegramProtectContent "true" to protect from forwarding

webhook

Key Description
webhookURL Target URL
webhookContentType json or form
webhookAdditionalHeaders JSON string of extra headers

smtp

Key Description
smtpHost SMTP server hostname
smtpPort SMTP port
smtpSecure "true" for TLS
smtpUsername Auth username
smtpPassword Auth password
smtpTo Recipient address(es)
smtpFrom Sender address
smtpFromName Sender display name

gotify

Key Description
gotifyserverurl Gotify server URL
gotifyapplicationToken Application token
gotifyPriority Message priority (integer string)

ntfy

Key Description
ntfyserverurl ntfy server URL
ntfytopic Topic name
ntfyPriority Priority (15)
ntfyAuthenticationMethod none, username, or accesstoken
ntfyusername Username (if method=username)
ntfypassword Password (if method=username)
ntfyaccesstoken Access token (if method=accesstoken)

pushover

Key Description
pushoveruserkey Pushover user key
pushoverapikey Application API key
pushoversounds Notification sound
pushoverpriority Priority (-2 to 2)

matrix

Key Description
matrixHomeserverUrl Matrix homeserver URL
matrixAccessToken Access token
matrixInternalRoomId Room ID

mattermost

Key Description
mattermostwebhookUrl Incoming webhook URL
mattermostusername Bot username
mattermostchannel Channel name

pagerduty

Key Description
pagerdutyIntegrationKey Integration (routing) key
pagerdutyAutoResolve "true" to auto-resolve incidents

opsgenie

Key Description
opsgenieApiKey OpsGenie API key
opsgenieRegion us or eu
opsgeniePriority Priority (P1P5)

Examples

# Webhook
apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaNotification
metadata:
  name: generic-webhook
spec:
  type: webhook
  active: true
  config:
    webhookURL: "https://hooks.example.com/alert"
    webhookContentType: json

---
# Telegram
apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaNotification
metadata:
  name: telegram-ops
spec:
  type: telegram
  active: true
  isDefault: true
  config:
    telegramBotToken: "1234567890:AAFakeToken"
    telegramChatID: "-1001234567890"

Status

status:
  notificationID: 3
  conditions:
    - type: Synced
      status: "True"

UptimeKumaTag

Manages a tag in Uptime Kuma. Tags can be attached to monitors with an optional value.

apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaTag
metadata:
  name: environment
  namespace: monitoring
spec:
  color: "#3498DB"

Fields

Field Description
name Tag name in Uptime Kuma (defaults to metadata.name)
color Hex colour string, e.g. #FF5733

Status

status:
  tagID: 1
  conditions:
    - type: Synced
      status: "True"

Full example

# 1. Create a tag
apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaTag
metadata:
  name: environment
  namespace: monitoring
spec:
  color: "#27AE60"

---
# 2. Create a notification provider
apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaNotification
metadata:
  name: discord-ops
  namespace: monitoring
spec:
  type: discord
  active: true
  config:
    discordWebhookUrl: "https://discord.com/api/webhooks/123/abc"
    discordUsername: "Uptime Kuma"

---
# 3. Create a monitor group
apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaMonitor
metadata:
  name: production-group
  namespace: monitoring
spec:
  type: group
  name: "Production"

---
# 4. Create a monitor inside the group with tag and notification
apiVersion: monitoring.wuastbude.de/v1alpha1
kind: UptimeKumaMonitor
metadata:
  name: myapp
  namespace: myapp-ns
spec:
  type: http
  url: "https://myapp.example.com"
  interval: 60
  parentName: "Production"
  notifications:
    - discord-ops
  tags:
    - name: environment
      value: production

Development

# Run unit tests
just test

# Run e2e tests (requires Docker)
just test-e2e

# Lint
just lint

# Regenerate CRD manifests and deepcopy after editing API types
just generate

# Build binary
just build

# Build Docker image
just docker-build

# Render Helm templates
just helm-template

E2E test environment variables

Variable Default Description
E2E_UPTIME_KUMA_URL Uptime Kuma instance URL (required to run e2e tests)
E2E_UPTIME_KUMA_USERNAME admin Admin username
E2E_UPTIME_KUMA_PASSWORD testpassword123 Admin password