Add per-device L2/misc long-tail: tunnels/stopped_rules/proxy_arp/proxy_ndp/arp_rules/maclist
Storage + CRUD (migration 0007, model, id-keyed store, REST handlers) + compiler rendering, each owned by a device. proxy_arp/proxy_ndp share the ProxyEntry shape via table-parameterized store helpers.
This commit is contained in:
@@ -39,6 +39,12 @@ type Input struct {
|
||||
Providers []model.Provider
|
||||
Routes []model.Route
|
||||
RoutingRules []model.RoutingRule
|
||||
Tunnels []model.Tunnel
|
||||
StoppedRules []model.StoppedRule
|
||||
ProxyARP []model.ProxyEntry
|
||||
ProxyNDP []model.ProxyEntry
|
||||
ArpRules []model.ArpRule
|
||||
Maclist []model.MaclistEntry
|
||||
}
|
||||
|
||||
// RenderedConfig is the per-device output served to the agent.
|
||||
@@ -60,6 +66,12 @@ type RenderedConfig struct {
|
||||
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"`
|
||||
Tunnels []RenderedTunnel `yaml:"tunnels,omitempty" json:"tunnels,omitempty"`
|
||||
StoppedRules []RenderedStoppedRule `yaml:"stopped_rules,omitempty" json:"stopped_rules,omitempty"`
|
||||
ProxyARP []RenderedProxy `yaml:"proxy_arp,omitempty" json:"proxy_arp,omitempty"`
|
||||
ProxyNDP []RenderedProxy `yaml:"proxy_ndp,omitempty" json:"proxy_ndp,omitempty"`
|
||||
ArpRules []RenderedArpRule `yaml:"arp_rules,omitempty" json:"arp_rules,omitempty"`
|
||||
Maclist []RenderedMaclist `yaml:"maclist,omitempty" json:"maclist,omitempty"`
|
||||
}
|
||||
|
||||
// RenderedSNAT is a resolved SNAT/masquerade rule: source addresses masqueraded
|
||||
@@ -207,6 +219,7 @@ func Render(in Input) (*RenderedConfig, error) {
|
||||
|
||||
// Per-device long-tail sections owned by this device.
|
||||
renderPerDevice(in, out)
|
||||
renderPerDeviceL2(in, out)
|
||||
|
||||
return out, nil
|
||||
}
|
||||
@@ -449,5 +462,23 @@ func Compile(ctx context.Context, s *store.Store, device string) (*RenderedConfi
|
||||
if in.RoutingRules, err = s.ListRoutingRules(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.Tunnels, err = s.ListTunnels(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.StoppedRules, err = s.ListStoppedRules(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.ProxyARP, err = s.ListProxyARP(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.ProxyNDP, err = s.ListProxyNDP(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.ArpRules, err = s.ListArpRules(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if in.Maclist, err = s.ListMaclist(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return Render(in)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
package compiler
|
||||
|
||||
import "git.unkin.net/unkin/tomswallapi/internal/model"
|
||||
|
||||
// Per-device L2/misc long-tail sections rendered into a device's config.
|
||||
|
||||
type RenderedTunnel struct {
|
||||
Type string `yaml:"type" json:"type"`
|
||||
Zone string `yaml:"zone" json:"zone"`
|
||||
Gateways []string `yaml:"gateways,omitempty" json:"gateways,omitempty"`
|
||||
GatewayZones []string `yaml:"gateway_zones,omitempty" json:"gateway_zones,omitempty"`
|
||||
Port int `yaml:"port,omitempty" json:"port,omitempty"`
|
||||
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
type RenderedStoppedRule struct {
|
||||
Action string `yaml:"action" json:"action"`
|
||||
Source string `yaml:"source,omitempty" json:"source,omitempty"`
|
||||
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
|
||||
Proto string `yaml:"proto,omitempty" json:"proto,omitempty"`
|
||||
DPort []string `yaml:"dport,omitempty" json:"dport,omitempty"`
|
||||
SPort []string `yaml:"sport,omitempty" json:"sport,omitempty"`
|
||||
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
type RenderedProxy struct {
|
||||
Address string `yaml:"address" json:"address"`
|
||||
Interface string `yaml:"interface,omitempty" json:"interface,omitempty"`
|
||||
External string `yaml:"external" json:"external"`
|
||||
HaveRoute bool `yaml:"haveroute,omitempty" json:"haveroute,omitempty"`
|
||||
Persistent bool `yaml:"persistent,omitempty" json:"persistent,omitempty"`
|
||||
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
type RenderedArpRule struct {
|
||||
Action string `yaml:"action" json:"action"`
|
||||
ActionAddress string `yaml:"action_address,omitempty" json:"action_address,omitempty"`
|
||||
ActionMAC string `yaml:"action_mac,omitempty" json:"action_mac,omitempty"`
|
||||
Source string `yaml:"source,omitempty" json:"source,omitempty"`
|
||||
Dest string `yaml:"dest,omitempty" json:"dest,omitempty"`
|
||||
Opcode int `yaml:"opcode,omitempty" json:"opcode,omitempty"`
|
||||
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
type RenderedMaclist struct {
|
||||
Action string `yaml:"action" json:"action"`
|
||||
Interface string `yaml:"interface" json:"interface"`
|
||||
MAC string `yaml:"mac,omitempty" json:"mac,omitempty"`
|
||||
Addresses []string `yaml:"addresses,omitempty" json:"addresses,omitempty"`
|
||||
Log string `yaml:"log,omitempty" json:"log,omitempty"`
|
||||
Comment string `yaml:"comment,omitempty" json:"comment,omitempty"`
|
||||
}
|
||||
|
||||
func renderPerDeviceL2(in Input, out *RenderedConfig) {
|
||||
dev := in.Device.Name
|
||||
for _, t := range in.Tunnels {
|
||||
if t.Device != dev {
|
||||
continue
|
||||
}
|
||||
out.Tunnels = append(out.Tunnels, RenderedTunnel{
|
||||
Type: t.Type, Zone: t.Zone, Gateways: t.Gateways,
|
||||
GatewayZones: t.GatewayZones, Port: t.Port, Comment: t.Comment,
|
||||
})
|
||||
}
|
||||
for _, r := range in.StoppedRules {
|
||||
if r.Device != dev {
|
||||
continue
|
||||
}
|
||||
out.StoppedRules = append(out.StoppedRules, RenderedStoppedRule{
|
||||
Action: r.Action, Source: r.Source, Dest: r.Dest, Proto: r.Proto,
|
||||
DPort: r.DPort, SPort: r.SPort, Comment: r.Comment,
|
||||
})
|
||||
}
|
||||
for _, p := range in.ProxyARP {
|
||||
if p.Device != dev {
|
||||
continue
|
||||
}
|
||||
out.ProxyARP = append(out.ProxyARP, renderProxy(p))
|
||||
}
|
||||
for _, p := range in.ProxyNDP {
|
||||
if p.Device != dev {
|
||||
continue
|
||||
}
|
||||
out.ProxyNDP = append(out.ProxyNDP, renderProxy(p))
|
||||
}
|
||||
for _, a := range in.ArpRules {
|
||||
if a.Device != dev {
|
||||
continue
|
||||
}
|
||||
out.ArpRules = append(out.ArpRules, RenderedArpRule{
|
||||
Action: a.Action, ActionAddress: a.ActionAddress, ActionMAC: a.ActionMAC,
|
||||
Source: a.Source, Dest: a.Dest, Opcode: a.Opcode, Comment: a.Comment,
|
||||
})
|
||||
}
|
||||
for _, m := range in.Maclist {
|
||||
if m.Device != dev {
|
||||
continue
|
||||
}
|
||||
out.Maclist = append(out.Maclist, RenderedMaclist{
|
||||
Action: m.Action, Interface: m.Interface, MAC: m.MAC,
|
||||
Addresses: m.Addresses, Log: m.Log, Comment: m.Comment,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func renderProxy(p model.ProxyEntry) RenderedProxy {
|
||||
return RenderedProxy{
|
||||
Address: p.Address, Interface: p.Interface, External: p.External,
|
||||
HaveRoute: p.HaveRoute, Persistent: p.Persistent, Comment: p.Comment,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user