111 lines
2.5 KiB
Go
111 lines
2.5 KiB
Go
package cluster
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestStoreLoadMissing(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
store, err := NewStore(filepath.Join(t.TempDir(), "clusters.enc"))
|
|
if err != nil {
|
|
t.Fatalf("NewStore error: %v", err)
|
|
}
|
|
|
|
reg, err := store.Load()
|
|
if err != nil {
|
|
t.Fatalf("Load error: %v", err)
|
|
}
|
|
|
|
if reg.Version != currentVersion {
|
|
t.Fatalf("expected version %d, got %d", currentVersion, reg.Version)
|
|
}
|
|
if len(reg.Clusters) != 0 {
|
|
t.Fatalf("expected empty clusters, got %d", len(reg.Clusters))
|
|
}
|
|
}
|
|
|
|
func TestStoreSaveLoadRoundtrip(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
path := filepath.Join(t.TempDir(), "clusters.enc")
|
|
store, err := NewStore(path)
|
|
if err != nil {
|
|
t.Fatalf("NewStore error: %v", err)
|
|
}
|
|
|
|
seed := newRegistry()
|
|
seed.ActiveClusterID = "clu_1"
|
|
seed.Clusters = []Cluster{{
|
|
ID: "clu_1",
|
|
Name: "prod",
|
|
Host: "10.0.0.10",
|
|
Port: 22,
|
|
User: "root",
|
|
AuthMethod: AuthMethodPassword,
|
|
Password: "secret123",
|
|
}}
|
|
|
|
if err := store.Save(seed); err != nil {
|
|
t.Fatalf("Save error: %v", err)
|
|
}
|
|
|
|
got, err := store.Load()
|
|
if err != nil {
|
|
t.Fatalf("Load error: %v", err)
|
|
}
|
|
|
|
if got.ActiveClusterID != "clu_1" {
|
|
t.Fatalf("active cluster mismatch: %s", got.ActiveClusterID)
|
|
}
|
|
if len(got.Clusters) != 1 || got.Clusters[0].Name != "prod" {
|
|
t.Fatalf("unexpected clusters: %+v", got.Clusters)
|
|
}
|
|
if got.Clusters[0].Password != "secret123" {
|
|
t.Fatalf("password mismatch after decrypt: %s", got.Clusters[0].Password)
|
|
}
|
|
}
|
|
|
|
func TestStorePersistsEncryptedPayload(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
dir := t.TempDir()
|
|
path := filepath.Join(dir, "clusters.enc")
|
|
store, err := NewStore(path)
|
|
if err != nil {
|
|
t.Fatalf("NewStore error: %v", err)
|
|
}
|
|
|
|
reg := newRegistry()
|
|
reg.Clusters = []Cluster{{
|
|
ID: "clu_1",
|
|
Name: "sensitive-prod",
|
|
Host: "192.168.1.1",
|
|
Port: 22,
|
|
User: "root",
|
|
AuthMethod: AuthMethodPassword,
|
|
Password: "very-secret",
|
|
}}
|
|
if err := store.Save(reg); err != nil {
|
|
t.Fatalf("Save error: %v", err)
|
|
}
|
|
|
|
raw, err := os.ReadFile(path)
|
|
if err != nil {
|
|
t.Fatalf("ReadFile error: %v", err)
|
|
}
|
|
if !strings.HasPrefix(string(raw), filePrefix) {
|
|
t.Fatalf("expected encrypted file prefix %q", filePrefix)
|
|
}
|
|
if strings.Contains(string(raw), "sensitive-prod") || strings.Contains(string(raw), "very-secret") {
|
|
t.Fatal("plaintext secrets leaked into encrypted file")
|
|
}
|
|
|
|
if _, err := os.Stat(store.KeyPath()); err != nil {
|
|
t.Fatalf("master key not created: %v", err)
|
|
}
|
|
}
|