[management] Cover the debug upload destination in the network-map drift guard

The drift guard asserts that the full, envelope and legacy paths produce the
same PeerConfig for a fixture. The new destination field was invisible to it:
the frozen legacy implementation never emitted it, so a fixture with a non-empty
account URL would have made legacy disagree with the other two, and no fixture
set one, so nothing failed and the field had no coverage at all.

The legacy path now emits the account setting, which is what AddressV6 already
does. It does not take the deployment-wide default the live path falls back to,
because the harness runs that path with no server config, so the two agree on
every fixture.

The dns-config case pins an account-level URL. Removing the legacy line makes it
fail on the legacy mode for that exact field, which is what makes the fixture
worth having.
This commit is contained in:
riccardom
2026-10-09 11:50:32 +02:00
parent 296bdc2849
commit 042c1839f5
4 changed files with 304 additions and 224 deletions
@@ -1,115 +1,116 @@
{ {
"Serial": "8", "Serial": "8",
"peerConfig": { "peerConfig": {
"address": "100.64.0.1/10", "address": "100.64.0.1/10",
"sshConfig": {}, "sshConfig": {},
"fqdn": "peer-a.netbird.test", "fqdn": "peer-a.netbird.test",
"RoutingPeerDnsResolutionEnabled": true, "RoutingPeerDnsResolutionEnabled": true,
"autoUpdate": {} "autoUpdate": {},
}, "debugBundleUploadUrl": "https://upload.example.com/upload-url"
"remotePeers": [ },
{ "remotePeers": [
"wgPubKey": "AvldyrZ12Pf90jzf3AXmhPwg3UcI+jtJHfbpBlupvko=", {
"allowedIps": [ "wgPubKey": "AvldyrZ12Pf90jzf3AXmhPwg3UcI+jtJHfbpBlupvko=",
"100.64.0.2/32" "allowedIps": [
], "100.64.0.2/32"
"sshConfig": {}, ],
"fqdn": "peer-b.netbird.test", "sshConfig": {},
"agentVersion": "0.60.0" "fqdn": "peer-b.netbird.test",
} "agentVersion": "0.60.0"
],
"DNSConfig": {
"ServiceEnable": true,
"NameServerGroups": [
{
"NameServers": [
{
"IP": "8.8.8.8",
"Port": "53"
}
],
"Primary": true
}
],
"CustomZones": [
{
"Domain": "corp.internal.",
"NonAuthoritative": true,
"Records": [
{
"Name": "db.corp.internal.",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "10.10.0.5"
}
]
},
{
"Domain": "search-off.internal.",
"SearchDomainDisabled": true,
"NonAuthoritative": true,
"Records": [
{
"Name": "alias.search-off.internal.",
"Type": "5",
"Class": "IN",
"TTL": "300",
"RData": "app.search-off.internal."
},
{
"Name": "app.search-off.internal.",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "10.10.0.6"
}
]
},
{
"Domain": "netbird.test.",
"Records": [
{
"Name": "peer-a.netbird.test",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "100.64.0.1"
},
{
"Name": "peer-b.netbird.test",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "100.64.0.2"
},
{
"Name": "www.netbird.test",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "100.64.0.1"
}
]
}
],
"ForwarderPort": "22054"
},
"FirewallRules": [
{
"PeerIP": "100.64.0.2",
"Protocol": "ALL",
"PolicyID": "cG9sLW1lc2g="
},
{
"PeerIP": "100.64.0.2",
"Direction": "OUT",
"Protocol": "ALL",
"PolicyID": "cG9sLW1lc2g="
}
],
"routesFirewallRulesIsEmpty": true,
"sshAuth": {
"UserIDClaim": "sub"
} }
],
"DNSConfig": {
"ServiceEnable": true,
"NameServerGroups": [
{
"NameServers": [
{
"IP": "8.8.8.8",
"Port": "53"
}
],
"Primary": true
}
],
"CustomZones": [
{
"Domain": "corp.internal.",
"NonAuthoritative": true,
"Records": [
{
"Name": "db.corp.internal.",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "10.10.0.5"
}
]
},
{
"Domain": "search-off.internal.",
"SearchDomainDisabled": true,
"NonAuthoritative": true,
"Records": [
{
"Name": "alias.search-off.internal.",
"Type": "5",
"Class": "IN",
"TTL": "300",
"RData": "app.search-off.internal."
},
{
"Name": "app.search-off.internal.",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "10.10.0.6"
}
]
},
{
"Domain": "netbird.test.",
"Records": [
{
"Name": "peer-a.netbird.test",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "100.64.0.1"
},
{
"Name": "peer-b.netbird.test",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "100.64.0.2"
},
{
"Name": "www.netbird.test",
"Type": "1",
"Class": "IN",
"TTL": "300",
"RData": "100.64.0.1"
}
]
}
],
"ForwarderPort": "22054"
},
"FirewallRules": [
{
"PeerIP": "100.64.0.2",
"Protocol": "ALL",
"PolicyID": "cG9sLW1lc2g="
},
{
"PeerIP": "100.64.0.2",
"Direction": "OUT",
"Protocol": "ALL",
"PolicyID": "cG9sLW1lc2g="
}
],
"routesFirewallRulesIsEmpty": true,
"sshAuth": {
"UserIDClaim": "sub"
}
} }
@@ -1,47 +1,48 @@
{ {
"Serial": "8", "Serial": "8",
"peerConfig": { "peerConfig": {
"address": "100.64.0.3/10", "address": "100.64.0.3/10",
"sshConfig": {}, "sshConfig": {},
"fqdn": "peer-c.netbird.test", "fqdn": "peer-c.netbird.test",
"RoutingPeerDnsResolutionEnabled": true, "RoutingPeerDnsResolutionEnabled": true,
"autoUpdate": {} "autoUpdate": {},
}, "debugBundleUploadUrl": "https://upload.example.com/upload-url"
"remotePeersIsEmpty": true, },
"DNSConfig": { "remotePeersIsEmpty": true,
"ServiceEnable": true, "DNSConfig": {
"CustomZones": [ "ServiceEnable": true,
{ "CustomZones": [
"Domain": "netbird.test.", {
"Records": [ "Domain": "netbird.test.",
{ "Records": [
"Name": "peer-c.netbird.test", {
"Type": "1", "Name": "peer-c.netbird.test",
"Class": "IN", "Type": "1",
"TTL": "300", "Class": "IN",
"RData": "100.64.0.3" "TTL": "300",
} "RData": "100.64.0.3"
] }
}, ]
{ },
"Domain": "ops-only.internal.", {
"NonAuthoritative": true, "Domain": "ops-only.internal.",
"Records": [ "NonAuthoritative": true,
{ "Records": [
"Name": "tool.ops-only.internal.", {
"Type": "1", "Name": "tool.ops-only.internal.",
"Class": "IN", "Type": "1",
"TTL": "300", "Class": "IN",
"RData": "10.10.0.7" "TTL": "300",
} "RData": "10.10.0.7"
] }
} ]
], }
"ForwarderPort": "22054" ],
}, "ForwarderPort": "22054"
"firewallRulesIsEmpty": true, },
"routesFirewallRulesIsEmpty": true, "firewallRulesIsEmpty": true,
"sshAuth": { "routesFirewallRulesIsEmpty": true,
"UserIDClaim": "sub" "sshAuth": {
} "UserIDClaim": "sub"
}
} }
@@ -1,74 +1,147 @@
{ {
"Network": {"Serial": 8}, "Network": {
"AccountSettings": {"RoutingPeerDNSResolutionEnabled": true}, "Serial": 8
"Peers": { },
"peer-a": {"IP": "100.64.0.1", "ExtraDNSLabels": ["www"], "Meta": {"WtVersion": "0.60.0"}}, "AccountSettings": {
"peer-b": {"IP": "100.64.0.2", "Meta": {"WtVersion": "0.60.0"}}, "RoutingPeerDNSResolutionEnabled": true,
"peer-c": {"IP": "100.64.0.3", "Meta": {"WtVersion": "0.60.0"}} "DebugBundleUploadURL": "https://upload.example.com/upload-url"
},
"Peers": {
"peer-a": {
"IP": "100.64.0.1",
"ExtraDNSLabels": [
"www"
],
"Meta": {
"WtVersion": "0.60.0"
}
}, },
"Groups": { "peer-b": {
"grp-dev": {"Peers": ["peer-a", "peer-b"]}, "IP": "100.64.0.2",
"grp-ops": {"Peers": ["peer-c"]} "Meta": {
"WtVersion": "0.60.0"
}
}, },
"Policies": [ "peer-c": {
"IP": "100.64.0.3",
"Meta": {
"WtVersion": "0.60.0"
}
}
},
"Groups": {
"grp-dev": {
"Peers": [
"peer-a",
"peer-b"
]
},
"grp-ops": {
"Peers": [
"peer-c"
]
}
},
"Policies": [
{
"ID": "pol-mesh",
"PublicID": "pol-mesh-pub",
"Enabled": true,
"Rules": [
{ {
"ID": "pol-mesh", "Enabled": true,
"PublicID": "pol-mesh-pub", "Action": "accept",
"Enabled": true, "Protocol": "all",
"Rules": [ "Bidirectional": true,
{ "Sources": [
"Enabled": true, "grp-dev"
"Action": "accept", ],
"Protocol": "all", "Destinations": [
"Bidirectional": true, "grp-dev"
"Sources": ["grp-dev"], ]
"Destinations": ["grp-dev"]
}
]
} }
], ]
"NameServerGroups": [ }
],
"NameServerGroups": [
{
"ID": "nsg-1",
"Name": "dns-primary",
"NameServers": [
{ {
"ID": "nsg-1", "IP": "8.8.8.8",
"Name": "dns-primary", "Port": 53
"NameServers": [{"IP": "8.8.8.8", "Port": 53}],
"Groups": ["grp-dev"],
"Primary": true,
"Enabled": true
} }
], ],
"AppliedZoneCandidates": [ "Groups": [
{ "grp-dev"
"DistributionGroups": ["grp-dev"], ],
"Zone": { "Primary": true,
"Domain": "corp.internal.", "Enabled": true
"NonAuthoritative": true, }
"Records": [ ],
{"Name": "db.corp.internal.", "Type": 1, "Class": "IN", "TTL": 300, "RData": "10.10.0.5"} "AppliedZoneCandidates": [
] {
} "DistributionGroups": [
}, "grp-dev"
{ ],
"DistributionGroups": ["grp-dev"], "Zone": {
"Zone": { "Domain": "corp.internal.",
"Domain": "search-off.internal.", "NonAuthoritative": true,
"NonAuthoritative": true, "Records": [
"SearchDomainDisabled": true, {
"Records": [ "Name": "db.corp.internal.",
{"Name": "app.search-off.internal.", "Type": 1, "Class": "IN", "TTL": 300, "RData": "10.10.0.6"}, "Type": 1,
{"Name": "alias.search-off.internal.", "Type": 5, "Class": "IN", "TTL": 300, "RData": "app.search-off.internal."} "Class": "IN",
] "TTL": 300,
} "RData": "10.10.0.5"
}, }
{ ]
"DistributionGroups": ["grp-ops"], }
"Zone": { },
"Domain": "ops-only.internal.", {
"NonAuthoritative": true, "DistributionGroups": [
"Records": [ "grp-dev"
{"Name": "tool.ops-only.internal.", "Type": 1, "Class": "IN", "TTL": 300, "RData": "10.10.0.7"} ],
] "Zone": {
} "Domain": "search-off.internal.",
} "NonAuthoritative": true,
] "SearchDomainDisabled": true,
"Records": [
{
"Name": "app.search-off.internal.",
"Type": 1,
"Class": "IN",
"TTL": 300,
"RData": "10.10.0.6"
},
{
"Name": "alias.search-off.internal.",
"Type": 5,
"Class": "IN",
"TTL": 300,
"RData": "app.search-off.internal."
}
]
}
},
{
"DistributionGroups": [
"grp-ops"
],
"Zone": {
"Domain": "ops-only.internal.",
"NonAuthoritative": true,
"Records": [
{
"Name": "tool.ops-only.internal.",
"Type": 1,
"Class": "IN",
"TTL": 300,
"RData": "10.10.0.7"
}
]
}
}
]
} }
@@ -130,6 +130,11 @@ func toPeerConfig(peer *nbpeer.Peer, network *Network, dnsName string, settings
Version: settings.AutoUpdateVersion, Version: settings.AutoUpdateVersion,
AlwaysUpdate: settings.AutoUpdateAlways, AlwaysUpdate: settings.AutoUpdateAlways,
}, },
// The account setting only. The live path also falls back to a
// deployment-wide default from the server config, which this frozen
// implementation is never given: the drift harness runs it with no server
// config at all, so the two agree on every fixture.
DebugBundleUploadUrl: settings.DebugBundleUploadURL,
} }
if peer.SupportsIPv6() && peer.IPv6.IsValid() && network.NetV6.IP != nil { if peer.SupportsIPv6() && peer.IPv6.IsValid() && network.NetV6.IP != nil {