diff --git a/internal/agent/rendered.go b/internal/agent/rendered.go index ab0ef3c..63e71fd 100644 --- a/internal/agent/rendered.go +++ b/internal/agent/rendered.go @@ -8,19 +8,60 @@ package agent // GET /api/v1/devices/{name}/config. It mirrors the control plane's compiler // output: interface-agnostic, address-matched rules plus named sets. type RenderedConfig struct { - Generation int64 `yaml:"generation" json:"generation"` - Device string `yaml:"device" json:"device"` - Class string `yaml:"class" json:"class"` - Enforcing bool `yaml:"enforcing" json:"enforcing"` - Settings RenderedSettings `yaml:"settings" json:"settings"` - Resolver []string `yaml:"resolver,omitempty" json:"resolver,omitempty"` - Bindings map[string][]string `yaml:"bindings,omitempty" json:"bindings,omitempty"` // zone -> interfaces - Sets []RenderedSet `yaml:"sets,omitempty" json:"sets,omitempty"` - Rules []RenderedRule `yaml:"rules,omitempty" json:"rules,omitempty"` - Policies []RenderedPolicy `yaml:"policies,omitempty" json:"policies,omitempty"` - SNAT []RenderedSNAT `yaml:"snat,omitempty" json:"snat,omitempty"` - Netmap []RenderedNetmap `yaml:"netmap,omitempty" json:"netmap,omitempty"` - NAT []RenderedNAT `yaml:"nat,omitempty" json:"nat,omitempty"` + Generation int64 `yaml:"generation" json:"generation"` + Device string `yaml:"device" json:"device"` + Class string `yaml:"class" json:"class"` + Enforcing bool `yaml:"enforcing" json:"enforcing"` + Settings RenderedSettings `yaml:"settings" json:"settings"` + Resolver []string `yaml:"resolver,omitempty" json:"resolver,omitempty"` + Bindings map[string][]string `yaml:"bindings,omitempty" json:"bindings,omitempty"` // zone -> interfaces + Sets []RenderedSet `yaml:"sets,omitempty" json:"sets,omitempty"` + Rules []RenderedRule `yaml:"rules,omitempty" json:"rules,omitempty"` + Policies []RenderedPolicy `yaml:"policies,omitempty" json:"policies,omitempty"` + SNAT []RenderedSNAT `yaml:"snat,omitempty" json:"snat,omitempty"` + Netmap []RenderedNetmap `yaml:"netmap,omitempty" json:"netmap,omitempty"` + NAT []RenderedNAT `yaml:"nat,omitempty" json:"nat,omitempty"` + Hosts []RenderedHost `yaml:"hosts,omitempty" json:"hosts,omitempty"` + Providers []RenderedProvider `yaml:"providers,omitempty" json:"providers,omitempty"` + Routes []RenderedRoute `yaml:"routes,omitempty" json:"routes,omitempty"` + RoutingRules []RenderedRoutingRule `yaml:"routing_rules,omitempty" json:"routing_rules,omitempty"` +} + +type RenderedHost struct { + Zone string `yaml:"zone" json:"zone"` + Interface string `yaml:"interface" json:"interface"` + Addresses []string `yaml:"addresses,omitempty" json:"addresses,omitempty"` + Exclusions []string `yaml:"exclusions,omitempty" json:"exclusions,omitempty"` + Dynamic bool `yaml:"dynamic,omitempty" json:"dynamic,omitempty"` +} + +type RenderedProvider struct { + Name string `yaml:"name" json:"name"` + Number int `yaml:"number" json:"number"` + Mark int `yaml:"mark,omitempty" json:"mark,omitempty"` + Duplicate string `yaml:"duplicate,omitempty" json:"duplicate,omitempty"` + Interface string `yaml:"interface" json:"interface"` + Gateway string `yaml:"gateway,omitempty" json:"gateway,omitempty"` + Copy []string `yaml:"copy,omitempty" json:"copy,omitempty"` +} + +type RenderedRoute struct { + Provider string `yaml:"provider,omitempty" json:"provider,omitempty"` + Dest string `yaml:"dest" json:"dest"` + Gateway string `yaml:"gateway,omitempty" json:"gateway,omitempty"` + Oif string `yaml:"oif,omitempty" json:"oif,omitempty"` + Persistent bool `yaml:"persistent,omitempty" json:"persistent,omitempty"` + Comment string `yaml:"comment,omitempty" json:"comment,omitempty"` +} + +type RenderedRoutingRule struct { + Source string `yaml:"source,omitempty" json:"source,omitempty"` + Dest string `yaml:"dest,omitempty" json:"dest,omitempty"` + Provider string `yaml:"provider" json:"provider"` + Priority int `yaml:"priority,omitempty" json:"priority,omitempty"` + Persistent bool `yaml:"persistent,omitempty" json:"persistent,omitempty"` + Mark string `yaml:"mark,omitempty" json:"mark,omitempty"` + Comment string `yaml:"comment,omitempty" json:"comment,omitempty"` } // RenderedSNAT is a resolved SNAT/masquerade rule (egress carries interface names). diff --git a/internal/agent/translate.go b/internal/agent/translate.go index 620bb2c..5a64a24 100644 --- a/internal/agent/translate.go +++ b/internal/agent/translate.go @@ -81,6 +81,31 @@ func Translate(rc *RenderedConfig) (*config.Config, error) { }) } + for _, h := range rc.Hosts { + cfg.Hosts = append(cfg.Hosts, config.Host{ + Zone: h.Zone, Interface: h.Interface, Addresses: h.Addresses, + Exclusions: h.Exclusions, Dynamic: h.Dynamic, + }) + } + for _, p := range rc.Providers { + cfg.Providers = append(cfg.Providers, config.Provider{ + Name: p.Name, Number: p.Number, Mark: p.Mark, Duplicate: p.Duplicate, + Interface: p.Interface, Gateway: p.Gateway, Copy: p.Copy, + }) + } + for _, r := range rc.Routes { + cfg.Routes = append(cfg.Routes, config.StaticRoute{ + Provider: r.Provider, Dest: r.Dest, Gateway: r.Gateway, + Device: r.Oif, Persistent: r.Persistent, Comment: r.Comment, + }) + } + for _, r := range rc.RoutingRules { + cfg.RoutingRules = append(cfg.RoutingRules, config.RoutingRule{ + Source: r.Source, Dest: r.Dest, Provider: r.Provider, Priority: r.Priority, + Persistent: r.Persistent, Mark: r.Mark, Comment: r.Comment, + }) + } + return cfg, nil }