Fix OPNsense config.xml root element mismatch
Real config.xml root is the lowercase <opnsense> element (the whole firewall config); plugin/core model data like WireGuard lives nested inside a separate, capitalized <OPNsense> child element. The parser was matching the capitalized name as the document root, so every real export failed with "expected element type but have ...". Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019VjwLYRA87o8m9a9zztgs3
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
388a8377cd
commit
3a89a3cb5c
+45
-33
@@ -7,20 +7,27 @@
|
|||||||
// for the two-step preview/commit flow that does the actual store writes.
|
// for the two-step preview/commit flow that does the actual store writes.
|
||||||
//
|
//
|
||||||
// Schema reference (verified against OPNsense core master,
|
// 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 <OPNsense> element inside the lowercase <opnsense>
|
||||||
|
// root - the two are NOT the same element):
|
||||||
//
|
//
|
||||||
// <OPNsense><wireguard>
|
// <opnsense>
|
||||||
// <server><servers>
|
// ...
|
||||||
// <server uuid="..."><enabled/><name/><instance/><pubkey/><privkey/>
|
// <OPNsense><wireguard>
|
||||||
// <port/><mtu/><dns/><tunneladdress/><disableroutes/><gateway/>
|
// <server><servers>
|
||||||
// <peers/><debug/></server>
|
// <server uuid="..."><enabled/><name/><instance/><pubkey/><privkey/>
|
||||||
// </servers></server>
|
// <port/><mtu/><dns/><tunneladdress/><disableroutes/><gateway/>
|
||||||
// <client><clients>
|
// <peers/><debug/></server>
|
||||||
// <client uuid="..."><enabled/><name/><pubkey/><psk/><tunneladdress/>
|
// </servers></server>
|
||||||
// <serveraddress/><serverport/><keepalive/></client>
|
// <client><clients>
|
||||||
// </clients></client>
|
// <client uuid="..."><enabled/><name/><pubkey/><psk/><tunneladdress/>
|
||||||
// <general><enabled/></general>
|
// <serveraddress/><serverport/><keepalive/></client>
|
||||||
// </wireguard></OPNsense>
|
// </clients></client>
|
||||||
|
// <general><enabled/></general>
|
||||||
|
// </wireguard></OPNsense>
|
||||||
|
// ...
|
||||||
|
// </opnsense>
|
||||||
package opnsense
|
package opnsense
|
||||||
|
|
||||||
import (
|
import (
|
||||||
@@ -30,24 +37,29 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
// rawConfig mirrors the on-disk config.xml structure.
|
// rawConfig mirrors the on-disk config.xml structure. The root element is
|
||||||
|
// the lowercase <opnsense> (the whole firewall config); plugin/core model
|
||||||
|
// data lives inside a capitalized <OPNsense> child element - the two are
|
||||||
|
// distinct tags, not a casing quirk of one.
|
||||||
type rawConfig struct {
|
type rawConfig struct {
|
||||||
XMLName xml.Name `xml:"OPNsense"`
|
XMLName xml.Name `xml:"opnsense"`
|
||||||
Wireguard struct {
|
Ns struct {
|
||||||
Server struct {
|
Wireguard struct {
|
||||||
Servers struct {
|
Server struct {
|
||||||
Server []rawServer `xml:"server"`
|
Servers struct {
|
||||||
} `xml:"servers"`
|
Server []rawServer `xml:"server"`
|
||||||
} `xml:"server"`
|
} `xml:"servers"`
|
||||||
Client struct {
|
} `xml:"server"`
|
||||||
Clients struct {
|
Client struct {
|
||||||
Client []rawClient `xml:"client"`
|
Clients struct {
|
||||||
} `xml:"clients"`
|
Client []rawClient `xml:"client"`
|
||||||
} `xml:"client"`
|
} `xml:"clients"`
|
||||||
General struct {
|
} `xml:"client"`
|
||||||
Enabled string `xml:"enabled"`
|
General struct {
|
||||||
} `xml:"general"`
|
Enabled string `xml:"enabled"`
|
||||||
} `xml:"wireguard"`
|
} `xml:"general"`
|
||||||
|
} `xml:"wireguard"`
|
||||||
|
} `xml:"OPNsense"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type rawServer struct {
|
type rawServer struct {
|
||||||
@@ -97,13 +109,13 @@ func Parse(r io.Reader) (*ParsedConfig, error) {
|
|||||||
if err := dec.Decode(&cfg); err != nil {
|
if err := dec.Decode(&cfg); err != nil {
|
||||||
return nil, fmt.Errorf("could not parse config.xml: %w", err)
|
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 nil, fmt.Errorf("not an OPNsense config.xml (unexpected root element %q)", cfg.XMLName.Local)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ParsedConfig{
|
return &ParsedConfig{
|
||||||
Servers: cfg.Wireguard.Server.Servers.Server,
|
Servers: cfg.Ns.Wireguard.Server.Servers.Server,
|
||||||
Clients: cfg.Wireguard.Client.Clients.Client,
|
Clients: cfg.Ns.Wireguard.Client.Clients.Client,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user