| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- 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()
- meta := mm.store.Interfaces[name]
- meta.Role = role
- meta.Description = desc
- mm.store.Interfaces[name] = meta
- return mm.save()
- }
- func (mm *MetadataManager) AddIP(name, cidr string) error {
- mm.mu.Lock()
- defer mm.mu.Unlock()
- meta := mm.store.Interfaces[name]
- for _, ip := range meta.IPAddresses {
- if ip == cidr {
- return nil
- }
- }
- meta.IPAddresses = append(meta.IPAddresses, cidr)
- meta.AutoUp = true
- mm.store.Interfaces[name] = meta
- return mm.save()
- }
- func (mm *MetadataManager) RemoveIP(name, cidr string) error {
- mm.mu.Lock()
- defer mm.mu.Unlock()
- meta := mm.store.Interfaces[name]
- var updated []string
- for _, ip := range meta.IPAddresses {
- if ip != cidr {
- updated = append(updated, ip)
- }
- }
- meta.IPAddresses = updated
- mm.store.Interfaces[name] = meta
- return mm.save()
- }
- func (mm *MetadataManager) GetAllWithIPs() map[string][]string {
- mm.mu.RLock()
- defer mm.mu.RUnlock()
- res := make(map[string][]string)
- for name, meta := range mm.store.Interfaces {
- if len(meta.IPAddresses) > 0 {
- res[name] = append([]string(nil), meta.IPAddresses...)
- }
- }
- return res
- }
- func (mm *MetadataManager) Delete(name string) error {
- mm.mu.Lock()
- defer mm.mu.Unlock()
- delete(mm.store.Interfaces, name)
- return mm.save()
- }
- // Rename migrates interface metadata when an interface is renamed.
- func (mm *MetadataManager) Rename(oldName, newName string) error {
- mm.mu.Lock()
- defer mm.mu.Unlock()
- if meta, exists := mm.store.Interfaces[oldName]; exists {
- delete(mm.store.Interfaces, oldName)
- mm.store.Interfaces[newName] = meta
- return mm.save()
- }
- return nil
- }
|