Docs / Integrations
Integrations
What KLYRN VM connects to, and how. Each entry says what is built and tested, not what is planned.
| Integration | What it does | Where |
|---|---|---|
| WHMCS | Create, suspend, unsuspend, terminate and change package from billing | whmcs/ |
| Terraform | Machines, networks and keys as code | terraform-provider-klyrn/ |
| REST API | Everything the panel does, with scoped tokens | vm.klyrn.com/docs/api/ |
| Email notifications | Machine and node events to the people they concern | Settings |
| Webhooks | A signed POST for every audited action and finished task | Settings, Integrations |
| PowerDNS | Customers set reverse DNS for their own addresses; KLYRN publishes it | Settings, Integrations |
| Prometheus | The whole estate as time series for Grafana and Alertmanager | below |
| SolusVM 2, Virtualizor, VMware | Read-only estate import, then adoption | Migration |
Prometheus
GET /api/v1/metrics returns the estate in the Prometheus text format. Only an administrator may read it: create an API token for an administrator account with the Read everything scope and give it to Prometheus as a bearer token.
scrape_configs:
- job_name: klyrn-vm
scheme: https
metrics_path: /api/v1/metrics
authorization:
type: Bearer
credentials_file: /etc/prometheus/klyrn-vm.token
static_configs:
- targets: ['panel.example.com:8443']
| Metric | Labels | Meaning |
|---|---|---|
klyrn_build_info | version | Always 1; the running controller version |
klyrn_vms | state | Machines running, stopped, needs_attention, creating, unknown |
klyrn_vms_total | Machines in the estate | |
klyrn_node_up | node, node_id, state | 1 when a node is online or degraded and reporting |
klyrn_node_memory_bytes, _allocated_bytes, _used_bytes | node, node_id | Managed nodes only |
klyrn_node_storage_bytes, _allocated_bytes, _used_bytes | node, node_id | Managed nodes only |
klyrn_node_cpu_threads, klyrn_node_vcpus_allocated | node, node_id | Managed nodes only |
klyrn_ipv4_free, klyrn_ipv4_total | Addresses across every pool | |
klyrn_tasks_running, klyrn_tasks_failed_24h, klyrn_tasks_waiting_node | Task queue | |
klyrn_alerts_open | severity | Open alerts: fail, warn, info |
Every figure is read from the same store queries as the Overview page, so a Grafana panel and the panel's own dashboard cannot disagree.
Alert rules worth starting with:
groups:
- name: klyrn-vm
rules:
- alert: KlyrnNodeDown
expr: klyrn_node_up == 0
for: 5m
- alert: KlyrnIPv4Low
expr: klyrn_ipv4_free / klyrn_ipv4_total < 0.1
for: 30m
- alert: KlyrnStorageNearlyFull
expr: klyrn_node_storage_used_bytes / klyrn_node_storage_bytes > 0.85
for: 30m
- alert: KlyrnTasksFailing
expr: klyrn_tasks_failed_24h > 5
Webhooks
Settings, Integrations, Add webhook. Administrators only. Every action the Activity page records and every task that finishes is posted as JSON to each enabled webhook whose filter matches:
{"id":"evt_3f...","event":"vm.create","result":"ok","target":"vm:41",
"actor":"admin@example.com","task_id":9001,"at":"2026-09-28T12:00:00Z",
"controller":"panel.example.com"}
- Filter:
*, an exact code (vm.create), or a family (vm.*,node.*,backup.*). Codes are the ones in the Activity page. - Signature:
X-Klyrn-Signature: t=<unix>,v1=<hex>where v1 is HMAC-SHA256 oft + "." + bodywith the secret shown once at creation. Reject atolder than five minutes. - Delivery: within a second, never blocking the action; retried after 2s and 10s on a network error, a 5xx, 408 or 429; switched off after 20 failures in a row. The last 100 attempts per hook, with the body and the answer, open from its row.
- Refused destinations: link-local addresses such as the cloud metadata service 169.254.169.254, checked after DNS; redirects are not followed.
Verifying in Node:
const [t, v1] = sig.split(',').map((p) => p.split('=')[1])
const ok = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex') === v1
&& Date.now() / 1000 - Number(t) < 300
Reverse DNS (PowerDNS)
Settings, Integrations, Reverse DNS: the PowerDNS API address, its API key and server id (usually localhost). Test connection lists the server's zones and counts the reverse ones.
A customer sets a name on the machine's Networking tab, for an address allocated to that machine now, checked against the allocation table and never the request. KLYRN writes the PTR into the longest reverse zone on the server that contains it, so one zone per /24 and one per /16 both work without mapping. The zone itself is the provider's to create.
Every change is audited as vm.rdns, so a webhook on vm.* sees it. A PTR is kept even when no server is configured (shown as waiting) or the server refuses it (shown as not published, with the server's reason).
This page is generated from the guide that ships in the product's repository, so it describes the release it was built from. What changed in each release.