Register hosts under Containers/VMs/Docker with encrypted key storage, and require re-authentication for sensitive account changes.
94 lines
2.3 KiB
Go
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)
|
|
}
|