A Go-based CLI tool for recovering servers from backups to new cloud VMs. Features: - Multi-cloud support: Exoscale, Cloudscale, Hetzner Cloud - Backup sources: Local filesystem, Hetzner Storage Box - 6-stage restore pipeline with /etc whitelist protection - DNS migration with safety checks and auto-rollback - Dry-run by default, requires --yes to execute - Cloud-init for SSH key injection Packages: - cmd/recover-server: CLI commands (recover, migrate-dns, list, cleanup) - internal/providers: Cloud provider implementations - internal/backup: Backup source implementations - internal/restore: 6-stage restore pipeline - internal/dns: Exoscale DNS management - internal/ui: Prompts, progress, dry-run display - internal/config: Environment and host configuration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
97 lines
2.3 KiB
Go
97 lines
2.3 KiB
Go
package providers
|
|
|
|
import (
|
|
"context"
|
|
"time"
|
|
)
|
|
|
|
// VMOptions contains options for creating a new VM
|
|
type VMOptions struct {
|
|
Name string
|
|
Zone string // e.g., "ch-gva-2", "lpg1", "fsn1"
|
|
Flavor string // Instance type/size
|
|
Image string // OS image name or ID
|
|
SSHPublicKey string // Ephemeral public key content
|
|
UserData string // Cloud-init script
|
|
DiskSizeGB int64 // Root disk size
|
|
Tags map[string]string // Optional tags/labels
|
|
}
|
|
|
|
// VM represents a created virtual machine
|
|
type VM struct {
|
|
ID string
|
|
Name string
|
|
PublicIP string
|
|
PrivateIP string
|
|
Status string
|
|
Provider string
|
|
Zone string
|
|
CreatedAt time.Time
|
|
}
|
|
|
|
// Flavor represents an instance type/size
|
|
type Flavor struct {
|
|
ID string
|
|
Name string
|
|
CPUs int
|
|
Memory int // MB
|
|
Disk int // GB (if applicable)
|
|
}
|
|
|
|
// Image represents an OS image
|
|
type Image struct {
|
|
ID string
|
|
Name string
|
|
}
|
|
|
|
// CloudProvider defines the interface for cloud providers
|
|
type CloudProvider interface {
|
|
// Name returns the provider name
|
|
Name() string
|
|
|
|
// CreateVM creates a new virtual machine
|
|
CreateVM(ctx context.Context, opts VMOptions) (*VM, error)
|
|
|
|
// DeleteVM deletes a virtual machine by ID
|
|
DeleteVM(ctx context.Context, vmID string) error
|
|
|
|
// GetVM gets VM details by ID
|
|
GetVM(ctx context.Context, vmID string) (*VM, error)
|
|
|
|
// WaitForSSH waits until SSH is available on the VM
|
|
WaitForSSH(ctx context.Context, ip string, port int, timeout time.Duration) error
|
|
|
|
// ListFlavors lists available instance types
|
|
ListFlavors(ctx context.Context) ([]Flavor, error)
|
|
|
|
// ListImages lists available OS images
|
|
ListImages(ctx context.Context, filter string) ([]Image, error)
|
|
|
|
// ListZones lists available zones/regions
|
|
ListZones(ctx context.Context) ([]string, error)
|
|
}
|
|
|
|
// GenerateCloudInit creates a cloud-init user-data script
|
|
func GenerateCloudInit(ephemeralPubKey string) string {
|
|
return `#cloud-config
|
|
ssh_pwauth: false
|
|
users:
|
|
- name: root
|
|
ssh_authorized_keys:
|
|
- "` + ephemeralPubKey + `"
|
|
package_update: true
|
|
packages:
|
|
- rsync
|
|
- docker.io
|
|
- docker-compose
|
|
- wireguard-tools
|
|
write_files:
|
|
- path: /var/tmp/recovery-ready
|
|
content: "ready"
|
|
permissions: '0644'
|
|
runcmd:
|
|
- systemctl enable docker
|
|
- systemctl start docker
|
|
`
|
|
}
|