From 042c1839f58e00e22e2cebd4106b3eb4fdc9099b Mon Sep 17 00:00:00 2001 From: riccardom Date: Fri, 9 Oct 2026 11:50:32 +0200 Subject: [PATCH] [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. --- .../cases/dns-config/golden/peer-a.json | 225 +++++++++--------- .../cases/dns-config/golden/peer-c.json | 91 +++---- .../testdata/cases/dns-config/nmdata.json | 207 ++++++++++------ .../server/types/legacynmap/proto_legacy.go | 5 + 4 files changed, 304 insertions(+), 224 deletions(-) diff --git a/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/golden/peer-a.json b/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/golden/peer-a.json index f06a19d9d..b83928a1d 100644 --- a/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/golden/peer-a.json +++ b/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/golden/peer-a.json @@ -1,115 +1,116 @@ { - "Serial": "8", - "peerConfig": { - "address": "100.64.0.1/10", - "sshConfig": {}, - "fqdn": "peer-a.netbird.test", - "RoutingPeerDnsResolutionEnabled": true, - "autoUpdate": {} - }, - "remotePeers": [ - { - "wgPubKey": "AvldyrZ12Pf90jzf3AXmhPwg3UcI+jtJHfbpBlupvko=", - "allowedIps": [ - "100.64.0.2/32" - ], - "sshConfig": {}, - "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" + "Serial": "8", + "peerConfig": { + "address": "100.64.0.1/10", + "sshConfig": {}, + "fqdn": "peer-a.netbird.test", + "RoutingPeerDnsResolutionEnabled": true, + "autoUpdate": {}, + "debugBundleUploadUrl": "https://upload.example.com/upload-url" + }, + "remotePeers": [ + { + "wgPubKey": "AvldyrZ12Pf90jzf3AXmhPwg3UcI+jtJHfbpBlupvko=", + "allowedIps": [ + "100.64.0.2/32" + ], + "sshConfig": {}, + "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" + } } diff --git a/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/golden/peer-c.json b/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/golden/peer-c.json index 7e04dca40..e4bd074a7 100644 --- a/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/golden/peer-c.json +++ b/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/golden/peer-c.json @@ -1,47 +1,48 @@ { - "Serial": "8", - "peerConfig": { - "address": "100.64.0.3/10", - "sshConfig": {}, - "fqdn": "peer-c.netbird.test", - "RoutingPeerDnsResolutionEnabled": true, - "autoUpdate": {} - }, - "remotePeersIsEmpty": true, - "DNSConfig": { - "ServiceEnable": true, - "CustomZones": [ - { - "Domain": "netbird.test.", - "Records": [ - { - "Name": "peer-c.netbird.test", - "Type": "1", - "Class": "IN", - "TTL": "300", - "RData": "100.64.0.3" - } - ] - }, - { - "Domain": "ops-only.internal.", - "NonAuthoritative": true, - "Records": [ - { - "Name": "tool.ops-only.internal.", - "Type": "1", - "Class": "IN", - "TTL": "300", - "RData": "10.10.0.7" - } - ] - } - ], - "ForwarderPort": "22054" - }, - "firewallRulesIsEmpty": true, - "routesFirewallRulesIsEmpty": true, - "sshAuth": { - "UserIDClaim": "sub" - } + "Serial": "8", + "peerConfig": { + "address": "100.64.0.3/10", + "sshConfig": {}, + "fqdn": "peer-c.netbird.test", + "RoutingPeerDnsResolutionEnabled": true, + "autoUpdate": {}, + "debugBundleUploadUrl": "https://upload.example.com/upload-url" + }, + "remotePeersIsEmpty": true, + "DNSConfig": { + "ServiceEnable": true, + "CustomZones": [ + { + "Domain": "netbird.test.", + "Records": [ + { + "Name": "peer-c.netbird.test", + "Type": "1", + "Class": "IN", + "TTL": "300", + "RData": "100.64.0.3" + } + ] + }, + { + "Domain": "ops-only.internal.", + "NonAuthoritative": true, + "Records": [ + { + "Name": "tool.ops-only.internal.", + "Type": "1", + "Class": "IN", + "TTL": "300", + "RData": "10.10.0.7" + } + ] + } + ], + "ForwarderPort": "22054" + }, + "firewallRulesIsEmpty": true, + "routesFirewallRulesIsEmpty": true, + "sshAuth": { + "UserIDClaim": "sub" + } } diff --git a/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/nmdata.json b/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/nmdata.json index b9741ef16..14777d392 100644 --- a/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/nmdata.json +++ b/management/internals/controllers/network_map/nmaptest/testdata/cases/dns-config/nmdata.json @@ -1,74 +1,147 @@ { - "Network": {"Serial": 8}, - "AccountSettings": {"RoutingPeerDNSResolutionEnabled": true}, - "Peers": { - "peer-a": {"IP": "100.64.0.1", "ExtraDNSLabels": ["www"], "Meta": {"WtVersion": "0.60.0"}}, - "peer-b": {"IP": "100.64.0.2", "Meta": {"WtVersion": "0.60.0"}}, - "peer-c": {"IP": "100.64.0.3", "Meta": {"WtVersion": "0.60.0"}} + "Network": { + "Serial": 8 + }, + "AccountSettings": { + "RoutingPeerDNSResolutionEnabled": true, + "DebugBundleUploadURL": "https://upload.example.com/upload-url" + }, + "Peers": { + "peer-a": { + "IP": "100.64.0.1", + "ExtraDNSLabels": [ + "www" + ], + "Meta": { + "WtVersion": "0.60.0" + } }, - "Groups": { - "grp-dev": {"Peers": ["peer-a", "peer-b"]}, - "grp-ops": {"Peers": ["peer-c"]} + "peer-b": { + "IP": "100.64.0.2", + "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", - "PublicID": "pol-mesh-pub", - "Enabled": true, - "Rules": [ - { - "Enabled": true, - "Action": "accept", - "Protocol": "all", - "Bidirectional": true, - "Sources": ["grp-dev"], - "Destinations": ["grp-dev"] - } - ] + "Enabled": true, + "Action": "accept", + "Protocol": "all", + "Bidirectional": true, + "Sources": [ + "grp-dev" + ], + "Destinations": [ + "grp-dev" + ] } - ], - "NameServerGroups": [ + ] + } + ], + "NameServerGroups": [ + { + "ID": "nsg-1", + "Name": "dns-primary", + "NameServers": [ { - "ID": "nsg-1", - "Name": "dns-primary", - "NameServers": [{"IP": "8.8.8.8", "Port": 53}], - "Groups": ["grp-dev"], - "Primary": true, - "Enabled": true + "IP": "8.8.8.8", + "Port": 53 } - ], - "AppliedZoneCandidates": [ - { - "DistributionGroups": ["grp-dev"], - "Zone": { - "Domain": "corp.internal.", - "NonAuthoritative": true, - "Records": [ - {"Name": "db.corp.internal.", "Type": 1, "Class": "IN", "TTL": 300, "RData": "10.10.0.5"} - ] - } - }, - { - "DistributionGroups": ["grp-dev"], - "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"} - ] - } - } - ] -} \ No newline at end of file + ], + "Groups": [ + "grp-dev" + ], + "Primary": true, + "Enabled": true + } + ], + "AppliedZoneCandidates": [ + { + "DistributionGroups": [ + "grp-dev" + ], + "Zone": { + "Domain": "corp.internal.", + "NonAuthoritative": true, + "Records": [ + { + "Name": "db.corp.internal.", + "Type": 1, + "Class": "IN", + "TTL": 300, + "RData": "10.10.0.5" + } + ] + } + }, + { + "DistributionGroups": [ + "grp-dev" + ], + "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" + } + ] + } + } + ] +} diff --git a/management/server/types/legacynmap/proto_legacy.go b/management/server/types/legacynmap/proto_legacy.go index 36dc35401..eb947922c 100644 --- a/management/server/types/legacynmap/proto_legacy.go +++ b/management/server/types/legacynmap/proto_legacy.go @@ -130,6 +130,11 @@ func toPeerConfig(peer *nbpeer.Peer, network *Network, dnsName string, settings Version: settings.AutoUpdateVersion, 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 {