Migration 0016: backend_servers (id, backend_id, name, address, port, weight, backup, active) + backends.lb_algorithm. Daten-Migration kopiert bestehende backends.address/port als ersten Server, dann DROP COLUMN. HAProxy-Renderer: rendert pro Backend einen Block mit `balance <algo>` + N `server`-Zeilen (weight, backup-Flag, optional check inter 5s). LB-Algorithmen: roundrobin / leastconn / source. REST: /backends/:id/servers (GET/POST), /backend-servers/:id (PUT/DELETE). Re-rendert HAProxy nach jeder Server-Mutation. UI: address/port aus Backend-Form raus, lb_algorithm-Select rein. Server verwaltet ein expandable Sub-Panel pro Backend-Row (Tabelle + Add/Edit/ Delete-Modal). Domain-Attachment-Multi-Select bleibt. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
82 lines
3.1 KiB
SQL
82 lines
3.1 KiB
SQL
-- +goose Up
|
|
-- +goose StatementBegin
|
|
|
|
-- v1.0.49: backends wird vom Single-Server-Endpoint zum Pool.
|
|
-- Bisher: backends.address/port → genau ein Upstream.
|
|
-- Jetzt: backends = Pool-Definition (LB-Algo, Healthcheck), die
|
|
-- konkreten Upstreams leben in backend_servers (1:N).
|
|
-- Damit kann eine Domain → ein Backend → N Server (HAProxy macht
|
|
-- den Loadbalance laut backends.lb_algorithm).
|
|
|
|
CREATE TABLE IF NOT EXISTS backend_servers (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
backend_id BIGINT NOT NULL REFERENCES backends(id) ON DELETE CASCADE,
|
|
name TEXT NOT NULL,
|
|
address TEXT NOT NULL,
|
|
port INTEGER NOT NULL,
|
|
weight INTEGER NOT NULL DEFAULT 100,
|
|
backup BOOLEAN NOT NULL DEFAULT FALSE,
|
|
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT backend_servers_name_unique UNIQUE (backend_id, name),
|
|
CONSTRAINT backend_servers_port_check CHECK (port > 0 AND port < 65536),
|
|
CONSTRAINT backend_servers_weight_check CHECK (weight >= 0 AND weight <= 256)
|
|
);
|
|
|
|
CREATE INDEX IF NOT EXISTS idx_backend_servers_backend
|
|
ON backend_servers (backend_id);
|
|
CREATE INDEX IF NOT EXISTS idx_backend_servers_active
|
|
ON backend_servers (backend_id, active) WHERE active;
|
|
|
|
-- LB-Algorithmus pro Backend. Default roundrobin entspricht haproxy-
|
|
-- default; source = sticky-per-Source-IP (für stateful Apps ohne
|
|
-- shared session store).
|
|
ALTER TABLE backends
|
|
ADD COLUMN IF NOT EXISTS lb_algorithm TEXT NOT NULL DEFAULT 'roundrobin';
|
|
|
|
ALTER TABLE backends
|
|
DROP CONSTRAINT IF EXISTS backends_lb_check;
|
|
ALTER TABLE backends
|
|
ADD CONSTRAINT backends_lb_check
|
|
CHECK (lb_algorithm IN ('roundrobin', 'leastconn', 'source'));
|
|
|
|
-- Daten-Migration: jede bisherige backends-Row produziert genau eine
|
|
-- backend_servers-Row mit demselben address/port. name = backends.name
|
|
-- damit der HAProxy-server-id stabil bleibt (haproxy stats / logs
|
|
-- referenzieren ihn). Idempotent — bei Re-Apply gibt's einen Skip
|
|
-- über das Unique-Constraint.
|
|
INSERT INTO backend_servers (backend_id, name, address, port, active)
|
|
SELECT id, name, address, port, active
|
|
FROM backends
|
|
WHERE address IS NOT NULL AND port IS NOT NULL
|
|
ON CONFLICT (backend_id, name) DO NOTHING;
|
|
|
|
-- Erst nach erfolgreichem Insert die alten Spalten droppen. Wenn die
|
|
-- Migration mittendrin abbricht, sind die Daten in beiden Tabellen
|
|
-- vorhanden — wir verlieren nichts.
|
|
ALTER TABLE backends DROP COLUMN IF EXISTS address;
|
|
ALTER TABLE backends DROP COLUMN IF EXISTS port;
|
|
|
|
-- +goose StatementEnd
|
|
|
|
-- +goose Down
|
|
-- +goose StatementBegin
|
|
ALTER TABLE backends ADD COLUMN IF NOT EXISTS address TEXT;
|
|
ALTER TABLE backends ADD COLUMN IF NOT EXISTS port INTEGER;
|
|
|
|
UPDATE backends b
|
|
SET address = bs.address,
|
|
port = bs.port
|
|
FROM (
|
|
SELECT DISTINCT ON (backend_id) backend_id, address, port
|
|
FROM backend_servers
|
|
ORDER BY backend_id, id ASC
|
|
) bs
|
|
WHERE b.id = bs.backend_id;
|
|
|
|
ALTER TABLE backends DROP CONSTRAINT IF EXISTS backends_lb_check;
|
|
ALTER TABLE backends DROP COLUMN IF EXISTS lb_algorithm;
|
|
DROP TABLE IF EXISTS backend_servers;
|
|
-- +goose StatementEnd
|