mirror of
https://github.com/juanfont/headscale.git
synced 2026-07-08 00:50:20 +09:00
servertest: align via grant compat test with new tscap golden format
The previous tscap regeneration replaced the legacy uppercase
GRANT-V*.hujson files with lowercase via-grant-v*.hujson and switched
the topology nodes to anonymized pokémon identifiers, but
TestViaGrantMapCompat was still loading files by their old IDs and
matching topology entries by their old hostnames, so it could not even
open a single golden file.
- viaCompatTests: GRANT-V29/V30/V31/V36 → via-grant-v29/v30/v31/v36
so the path Join finds the renamed files on disk.
- taggedNodes: rewrite the hardcoded servertest hostname list to the
pokémon names tscap/anonymize writes (big-router→caterpie,
exit-a→pidgey, …) so the topology lookup picks up the matching
entries instead of skipping every node.
- goldenNode: track the tscap schema. Replace advertised_routes →
routable_ips and is_exit_node → approved_routes; the AdvertisedRoutes
field name is kept on the Go side because the rest of the test
code already references it.
- convertViaPolicy: also rewrite the anonymized odin/thor/freya
@example.com emails so the served policy resolves users when the
file came from tscap/anonymize.
Updates #3157
This commit is contained in:
@@ -38,8 +38,8 @@ type goldenNode struct {
|
||||
Tags []string `json:"tags"`
|
||||
IPv4 string `json:"ipv4"`
|
||||
IPv6 string `json:"ipv6"`
|
||||
AdvertisedRoutes []string `json:"advertised_routes"`
|
||||
IsExitNode bool `json:"is_exit_node"`
|
||||
AdvertisedRoutes []string `json:"routable_ips"`
|
||||
ApprovedRoutes []string `json:"approved_routes"`
|
||||
}
|
||||
|
||||
type goldenCapture struct {
|
||||
@@ -70,10 +70,10 @@ var viaCompatTests = []struct {
|
||||
id string
|
||||
desc string
|
||||
}{
|
||||
{"GRANT-V29", "crossed subnet steering: group-a via router-a, group-b via router-b"},
|
||||
{"GRANT-V30", "crossed mixed: subnet via router-a/b, exit via exit-b/a"},
|
||||
{"GRANT-V31", "peer connectivity + via exit A/B steering"},
|
||||
{"GRANT-V36", "full complex: peer connectivity + crossed subnet + crossed exit"},
|
||||
{"via-grant-v29", "crossed subnet steering: group-a via router-a, group-b via router-b"},
|
||||
{"via-grant-v30", "crossed mixed: subnet via router-a/b, exit via exit-b/a"},
|
||||
{"via-grant-v31", "peer connectivity + via exit A/B steering"},
|
||||
{"via-grant-v36", "full complex: peer connectivity + crossed subnet + crossed exit"},
|
||||
// TODO: V33 and V35 are not yet compatible due to:
|
||||
// - V33: PrimaryRoutes election differs (node ID ordering between SaaS and headscale)
|
||||
// - V35: Extra peer visibility (autoApprovers create different routing topology)
|
||||
@@ -90,9 +90,10 @@ var viaCompatTests = []struct {
|
||||
//
|
||||
// CROSS-DEPENDENCY WARNING:
|
||||
// This test reads golden files from ../policy/v2/testdata/grant_results/
|
||||
// (specifically GRANT-V29, V30, V31, V36). These files are shared with
|
||||
// TestGrantsCompat in the policy/v2 package. Any changes to the file
|
||||
// format, field structure, or naming must be coordinated with BOTH tests.
|
||||
// (specifically via-grant-v29, v30, v31, v36). These files are shared
|
||||
// with TestGrantsCompat in the policy/v2 package. Any changes to the
|
||||
// file format, field structure, or naming must be coordinated with
|
||||
// BOTH tests.
|
||||
//
|
||||
// Fields consumed by this test (but NOT by TestGrantsCompat):
|
||||
// - captures[name].netmap (Peers, AllowedIPs, PrimaryRoutes, PacketFilterRules)
|
||||
@@ -131,15 +132,24 @@ func TestViaGrantMapCompat(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// taggedNodes are the nodes we create in the servertest.
|
||||
// taggedNodes are the nodes we create in the servertest. Names match
|
||||
// the anonymized pokémon identifiers tscap writes into golden files —
|
||||
// see github.com/kradalby/tscap/anonymize for the full substitution
|
||||
// table (big-router→caterpie, exit-a→pidgey, etc).
|
||||
var taggedNodes = []string{
|
||||
"big-router",
|
||||
"exit-a", "exit-b", "exit-node",
|
||||
"group-a-client", "group-b-client",
|
||||
"router-a", "router-b",
|
||||
"subnet-router", "tagged-client",
|
||||
"tagged-server", "tagged-prod",
|
||||
"multi-exit-router",
|
||||
"caterpie", // big-router
|
||||
"pidgey", // exit-a
|
||||
"pidgeotto", // exit-b
|
||||
"charmander", // exit-node
|
||||
"rattata", // group-a-client
|
||||
"raticate", // group-b-client
|
||||
"spearow", // router-a
|
||||
"fearow", // router-b
|
||||
"squirtle", // subnet-router
|
||||
"weedle", // tagged-client
|
||||
"beedrill", // tagged-server
|
||||
"kakuna", // tagged-prod
|
||||
"blastoise", // multi-exit-router
|
||||
}
|
||||
|
||||
func runViaMapCompat(t *testing.T, gf goldenFile) {
|
||||
@@ -624,6 +634,11 @@ func extractHostname(fqdn string) string {
|
||||
// convertViaPolicy converts Tailscale SaaS policy emails to headscale format.
|
||||
func convertViaPolicy(raw json.RawMessage) []byte {
|
||||
s := string(raw)
|
||||
// Anonymized SaaS emails as written by tscap/anonymize.
|
||||
s = strings.ReplaceAll(s, "odin@example.com", "tag-user@")
|
||||
s = strings.ReplaceAll(s, "thor@example.com", "tag-user@")
|
||||
s = strings.ReplaceAll(s, "freya@example.com", "tag-user@")
|
||||
// Pre-anonymization emails (legacy captures / local reruns).
|
||||
s = strings.ReplaceAll(s, "kratail2tid@passkey", "tag-user@")
|
||||
s = strings.ReplaceAll(s, "kristoffer@dalby.cc", "tag-user@")
|
||||
s = strings.ReplaceAll(s, "monitorpasskeykradalby@passkey", "tag-user@")
|
||||
|
||||
Reference in New Issue
Block a user