kedge/internal/topology/store.go
Tyler King 6058e62348 Initial commit: Kedge network automation platform
Go-based network automation with YANG models, gRPC, Ansible,
Terraform, and Kubernetes integration.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-26 12:09:30 -05:00

76 lines
1.8 KiB
Go

package topology
import (
"encoding/json"
"fmt"
"os"
"sync"
)
// Store provides thread-safe access to the mesh topology state.
// The DaemonSet writes topology updates, and the CNI plugin reads them.
// State is persisted to a JSON file on disk.
type Store struct {
mu sync.RWMutex
filePath string
topo *MeshTopology
}
// NewStore creates a topology store backed by the given file path.
func NewStore(filePath string) *Store {
return &Store{
filePath: filePath,
topo: &MeshTopology{},
}
}
// LoadFromFile reads a MeshTopology from a JSON file.
// Used by the CNI plugin to read the DaemonSet-written state.
func LoadFromFile(path string) (*MeshTopology, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, fmt.Errorf("failed to read topology file %s: %w", path, err)
}
var topo MeshTopology
if err := json.Unmarshal(data, &topo); err != nil {
return nil, fmt.Errorf("failed to parse topology file: %w", err)
}
return &topo, nil
}
// Get returns a copy of the current topology.
func (s *Store) Get() MeshTopology {
s.mu.RLock()
defer s.mu.RUnlock()
return *s.topo
}
// Update atomically updates the topology and persists to disk.
func (s *Store) Update(fn func(*MeshTopology)) error {
s.mu.Lock()
defer s.mu.Unlock()
fn(s.topo)
return s.persist()
}
func (s *Store) persist() error {
data, err := json.MarshalIndent(s.topo, "", " ")
if err != nil {
return fmt.Errorf("failed to marshal topology: %w", err)
}
// Atomic write: write to temp file, then rename.
tmpPath := s.filePath + ".tmp"
if err := os.WriteFile(tmpPath, data, 0644); err != nil {
return fmt.Errorf("failed to write topology file: %w", err)
}
if err := os.Rename(tmpPath, s.filePath); err != nil {
return fmt.Errorf("failed to rename topology file: %w", err)
}
return nil
}