diff --git a/CHANGELOG.md b/CHANGELOG.md index e0e7cb6..ce63b3e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## Unreleased +- VMs-und-SSH-Keys-Migration mit Ressourcen-Mapping und eindeutigem Proxmox-VMID-Index angelegt. - Cluster-Migration fuer Proxmox-Verbindungen mit `encrypted_token bytea` angelegt. - Projekte-und-Quotas-Migration mit Defaults und Constraints angelegt. - Kern-Tabellen-Migration fuer `profiles`, `tenants` und `memberships` angelegt. diff --git a/TODO.md b/TODO.md index 24d409e..aec39d2 100644 --- a/TODO.md +++ b/TODO.md @@ -49,6 +49,11 @@ Arbeitsliste auf Basis von `proxmox-console-entwicklungsplan.md`. Die Entwurfsda - [x] `encrypted_token` als `bytea` ohne Klartext-Token-Spalte angelegt - [x] `token_id`, `api_endpoint`, `tls_fingerprint`, Status und Zeitstempel angelegt - [x] Checks und Indizes fuer Endpoint/Status gesetzt +- [x] E2-T05: VMs & Ressourcen-Mapping + - [x] Migration fuer `vms` und `ssh_keys` angelegt + - [x] VMs referenzieren eindeutig Projekt und Cluster + - [x] Unique-Index auf `(cluster_id, proxmox_vmid)` gesetzt + - [x] Ressourcen- und Pflichtfeld-Checks gesetzt ## MVP-Backlog @@ -91,3 +96,4 @@ Arbeitsliste auf Basis von `proxmox-console-entwicklungsplan.md`. Die Entwurfsda - 2026-06-10: Kern-Tabellen-Migration `0002_core_identity` angelegt und lokal gegen Supabase verifiziert. - 2026-06-10: Projekte-und-Quotas-Migration `0003_projects_and_quotas` angelegt und lokal gegen Supabase verifiziert. - 2026-06-10: Cluster-Migration `0004_clusters` angelegt und lokal gegen Supabase verifiziert. +- 2026-06-10: VMs-und-SSH-Keys-Migration `0005_vms_and_ssh_keys` angelegt und lokal gegen Supabase verifiziert. diff --git a/migrations/0005_vms_and_ssh_keys.down.sql b/migrations/0005_vms_and_ssh_keys.down.sql new file mode 100644 index 0000000..28cdcf8 --- /dev/null +++ b/migrations/0005_vms_and_ssh_keys.down.sql @@ -0,0 +1,8 @@ +DROP INDEX IF EXISTS public.ssh_keys_tenant_id_idx; +DROP TABLE IF EXISTS public.ssh_keys; +DROP INDEX IF EXISTS public.vms_status_idx; +DROP INDEX IF EXISTS public.vms_cluster_id_idx; +DROP INDEX IF EXISTS public.vms_project_id_idx; +DROP INDEX IF EXISTS public.vms_cluster_id_proxmox_vmid_key; +DROP TABLE IF EXISTS public.vms; +DROP TYPE IF EXISTS public.vm_status; diff --git a/migrations/0005_vms_and_ssh_keys.up.sql b/migrations/0005_vms_and_ssh_keys.up.sql new file mode 100644 index 0000000..17ed477 --- /dev/null +++ b/migrations/0005_vms_and_ssh_keys.up.sql @@ -0,0 +1,47 @@ +CREATE TYPE public.vm_status AS ENUM ( + 'provisioning', + 'running', + 'stopped', + 'suspended', + 'failed', + 'deleting', + 'deleted' +); + +CREATE TABLE public.vms ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + project_id uuid NOT NULL REFERENCES public.projects(id) ON DELETE CASCADE, + cluster_id uuid NOT NULL REFERENCES public.clusters(id) ON DELETE RESTRICT, + proxmox_vmid integer NOT NULL, + node text NOT NULL, + name text NOT NULL, + status public.vm_status NOT NULL DEFAULT 'provisioning', + vcpu integer NOT NULL, + ram_mb integer NOT NULL, + disk_gb integer NOT NULL, + created_at timestamptz NOT NULL DEFAULT now(), + updated_at timestamptz NOT NULL DEFAULT now(), + CONSTRAINT vms_proxmox_vmid_check CHECK (proxmox_vmid > 0), + CONSTRAINT vms_node_not_blank_check CHECK (btrim(node) <> ''), + CONSTRAINT vms_name_not_blank_check CHECK (btrim(name) <> ''), + CONSTRAINT vms_vcpu_check CHECK (vcpu > 0), + CONSTRAINT vms_ram_mb_check CHECK (ram_mb > 0), + CONSTRAINT vms_disk_gb_check CHECK (disk_gb > 0) +); + +CREATE UNIQUE INDEX vms_cluster_id_proxmox_vmid_key ON public.vms (cluster_id, proxmox_vmid); +CREATE INDEX vms_project_id_idx ON public.vms (project_id); +CREATE INDEX vms_cluster_id_idx ON public.vms (cluster_id); +CREATE INDEX vms_status_idx ON public.vms (status); + +CREATE TABLE public.ssh_keys ( + id uuid PRIMARY KEY DEFAULT gen_random_uuid(), + tenant_id uuid NOT NULL REFERENCES public.tenants(id) ON DELETE CASCADE, + name text NOT NULL, + public_key text NOT NULL, + created_at timestamptz NOT NULL DEFAULT now(), + CONSTRAINT ssh_keys_name_not_blank_check CHECK (btrim(name) <> ''), + CONSTRAINT ssh_keys_public_key_not_blank_check CHECK (btrim(public_key) <> '') +); + +CREATE INDEX ssh_keys_tenant_id_idx ON public.ssh_keys (tenant_id);