diff --git a/opnsense/parse.go b/opnsense/parse.go index b3560f0..5d7cc26 100644 --- a/opnsense/parse.go +++ b/opnsense/parse.go @@ -7,20 +7,27 @@ // for the two-step preview/commit flow that does the actual store writes. // // Schema reference (verified against OPNsense core master, -// src/opnsense/mvc/app/models/OPNsense/Wireguard/{Server,Client}.xml): +// src/opnsense/mvc/app/models/OPNsense/Wireguard/{Server,Client}.xml, and +// against real config.xml exports/fixtures, which nest plugin model data +// under a capitalized element inside the lowercase +// root - the two are NOT the same element): // -// -// -// -// -// -// -// -// -// -// -// -// +// +// ... +// +// +// +// +// +// +// +// +// +// +// +// +// ... +// package opnsense import ( @@ -30,24 +37,29 @@ import ( "strings" ) -// rawConfig mirrors the on-disk config.xml structure. +// rawConfig mirrors the on-disk config.xml structure. The root element is +// the lowercase (the whole firewall config); plugin/core model +// data lives inside a capitalized child element - the two are +// distinct tags, not a casing quirk of one. type rawConfig struct { - XMLName xml.Name `xml:"OPNsense"` - Wireguard struct { - Server struct { - Servers struct { - Server []rawServer `xml:"server"` - } `xml:"servers"` - } `xml:"server"` - Client struct { - Clients struct { - Client []rawClient `xml:"client"` - } `xml:"clients"` - } `xml:"client"` - General struct { - Enabled string `xml:"enabled"` - } `xml:"general"` - } `xml:"wireguard"` + XMLName xml.Name `xml:"opnsense"` + Ns struct { + Wireguard struct { + Server struct { + Servers struct { + Server []rawServer `xml:"server"` + } `xml:"servers"` + } `xml:"server"` + Client struct { + Clients struct { + Client []rawClient `xml:"client"` + } `xml:"clients"` + } `xml:"client"` + General struct { + Enabled string `xml:"enabled"` + } `xml:"general"` + } `xml:"wireguard"` + } `xml:"OPNsense"` } type rawServer struct { @@ -97,13 +109,13 @@ func Parse(r io.Reader) (*ParsedConfig, error) { if err := dec.Decode(&cfg); err != nil { return nil, fmt.Errorf("could not parse config.xml: %w", err) } - if cfg.XMLName.Local != "OPNsense" { + if cfg.XMLName.Local != "opnsense" { return nil, fmt.Errorf("not an OPNsense config.xml (unexpected root element %q)", cfg.XMLName.Local) } return &ParsedConfig{ - Servers: cfg.Wireguard.Server.Servers.Server, - Clients: cfg.Wireguard.Client.Clients.Client, + Servers: cfg.Ns.Wireguard.Server.Servers.Server, + Clients: cfg.Ns.Wireguard.Client.Clients.Client, }, nil }