// Package provision owns the elastic-node control plane: it turns the // "nodes are cattle, not pets" principle (doc/04 §2) into running code. // // Responsibility split (doc/04 §4): // // - Terraform (infra/terraform) manages low-frequency baseline resources: // probe machines and the control-plane environment. Those live in // Terraform state. // - This package drives high-frequency, minute-scale node lifecycle through // vendor APIs. Disposable nodes are NOT in Terraform state. // // The package exposes a ProvisionService with idempotent operations: // // - CreateNode — insert nodes(status=provisioning) → vendor API boot → // render cloud-init (injecting a one-time bootstrap token, task #5) → // return. The agent self-registers (task #6) and flips the node to up. // - DestroyNode — vendor destroy + IP release + nodes→destroyed. // - RotateIP — swap the elastic IP without re-creating the machine // (change IP, keep the box), then bump the directory version. // - Replace — make-before-break one-click replacement: bring a fresh // node up BEFORE draining/destroying the old one, so capacity never dips. // - RotatePool — rolling Replace across a whole pool, concurrency 1–2. // // Vendor adapters live in providers/ behind the CloudAdapter interface. // Vendor credentials are injected ONLY from independent secrets (env/file) — // never stored in the database and never committed to git. The providers table // holds just name/api_kind/regions/pool/enabled. // // Hard red line (doc/06 §2): every operation here targets the new vendor pools. // It MUST NOT ever manage the production EC2 host (deploy/ marzban machine). package provision