package network import ( "encoding/json" "os" "path/filepath" "sync" ) var defaultMetadataPath = "/etc/proxmox-router/metadata.json" // MetadataManager manages user annotations for interfaces. type MetadataManager struct { mu sync.RWMutex filePath string store MetadataStore } func NewMetadataManager(customPath string) *MetadataManager { p := defaultMetadataPath if customPath != "" { p = customPath } mm := &MetadataManager{ filePath: p, store: MetadataStore{ Interfaces: make(map[string]InterfaceMetadata), }, } mm.load() return mm } func (mm *MetadataManager) load() { mm.mu.Lock() defer mm.mu.Unlock() data, err := os.ReadFile(mm.filePath) if err != nil { return } _ = json.Unmarshal(data, &mm.store) if mm.store.Interfaces == nil { mm.store.Interfaces = make(map[string]InterfaceMetadata) } } func (mm *MetadataManager) save() error { dir := filepath.Dir(mm.filePath) if err := os.MkdirAll(dir, 0755); err != nil { return err } data, err := json.MarshalIndent(mm.store, "", " ") if err != nil { return err } return os.WriteFile(mm.filePath, data, 0644) } func (mm *MetadataManager) Get(name string) InterfaceMetadata { mm.mu.RLock() defer mm.mu.RUnlock() return mm.store.Interfaces[name] } func (mm *MetadataManager) Set(name string, role, desc string) error { mm.mu.Lock() defer mm.mu.Unlock() mm.store.Interfaces[name] = InterfaceMetadata{ Role: role, Description: desc, } return mm.save() } func (mm *MetadataManager) Delete(name string) error { mm.mu.Lock() defer mm.mu.Unlock() delete(mm.store.Interfaces, name) return mm.save() }