Initial commit: Disaster recovery CLI tool

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>
This commit is contained in:
Olaf Berberich
2025-12-08 00:31:27 +00:00
commit 29a2886402
26 changed files with 3826 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
package providers
import (
"fmt"
)
// NewProvider creates a cloud provider by name
func NewProvider(name string, config map[string]string) (CloudProvider, error) {
switch name {
case "exoscale":
apiKey := config["api_key"]
apiSecret := config["api_secret"]
if apiKey == "" || apiSecret == "" {
return nil, fmt.Errorf("exoscale requires api_key and api_secret")
}
return NewExoscaleProvider(apiKey, apiSecret)
case "cloudscale":
token := config["token"]
if token == "" {
return nil, fmt.Errorf("cloudscale requires token")
}
return NewCloudscaleProvider(token)
case "hetzner":
token := config["token"]
if token == "" {
return nil, fmt.Errorf("hetzner requires token")
}
return NewHetznerProvider(token)
default:
return nil, fmt.Errorf("unknown provider: %s", name)
}
}
// SupportedProviders returns list of supported cloud providers
func SupportedProviders() []string {
return []string{"exoscale", "cloudscale", "hetzner"}
}