Files
ClusterCanvas/service/internal/settings/nodes.go
T
Squid f4dc8f63d7 Add SSH-managed node registry with connection testing and reauth.
Register hosts under Containers/VMs/Docker with encrypted key storage, and require re-authentication for sensitive account changes.
2026-07-18 16:39:10 +02:00

94 lines
2.3 KiB
Go

package settings
import (
"encoding/json"
"errors"
"fmt"
"os"
"path/filepath"
)
// LoadNodes reads and parses nodes.json from dir.
func LoadNodes(dir string) (NodeStore, error) {
path := filepath.Join(dir, NodesFileName)
payload, err := os.ReadFile(path)
if err != nil {
return NodeStore{}, err
}
var store NodeStore
if err := json.Unmarshal(payload, &store); err != nil {
return NodeStore{}, fmt.Errorf("parse nodes: %w", err)
}
if store.Nodes == nil {
store.Nodes = []Node{}
}
return store, nil
}
// LoadNodesOrEmpty returns an empty store when nodes.json is missing.
func LoadNodesOrEmpty(dir string) (NodeStore, error) {
store, err := LoadNodes(dir)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return NodeStore{Nodes: []Node{}}, nil
}
return NodeStore{}, err
}
return store, nil
}
// SaveNodes writes nodes.json to dir with mode 0640.
func SaveNodes(dir string, store NodeStore) error {
if err := ensureConfigDir(dir); err != nil {
return err
}
if store.Nodes == nil {
store.Nodes = []Node{}
}
payload, err := json.MarshalIndent(store, "", " ")
if err != nil {
return fmt.Errorf("encode nodes: %w", err)
}
payload = append(payload, '\n')
path := filepath.Join(dir, NodesFileName)
if err := os.WriteFile(path, payload, 0o640); err != nil {
return fmt.Errorf("write nodes: %w", err)
}
return nil
}
// LoadNodeKeys decrypts node-keys.enc from dir using key.
func LoadNodeKeys(dir string, key []byte) (NodeKeyStore, error) {
var store NodeKeyStore
if err := loadEncryptedJSON(dir, NodeKeysFileName, key, &store); err != nil {
return NodeKeyStore{}, err
}
if store.Keys == nil {
store.Keys = []NodeKeyEntry{}
}
return store, nil
}
// LoadNodeKeysOrEmpty returns an empty store when node-keys.enc is missing.
func LoadNodeKeysOrEmpty(dir string, key []byte) (NodeKeyStore, error) {
store, err := LoadNodeKeys(dir, key)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
return NodeKeyStore{Keys: []NodeKeyEntry{}}, nil
}
return NodeKeyStore{}, err
}
return store, nil
}
// SaveNodeKeys encrypts the node key store and writes node-keys.enc.
func SaveNodeKeys(dir string, store NodeKeyStore, key []byte) error {
if store.Keys == nil {
store.Keys = []NodeKeyEntry{}
}
return saveEncryptedJSON(dir, NodeKeysFileName, key, store)
}