mirror of
https://github.com/juanfont/headscale.git
synced 2026-10-31 02:34:07 +09:00
servertest: compare user profiles in via captures
Self and peer profiles, by login and display name. A tagged self gets its own profile in SaaS; listed as a skip entry until headscale matches.
This commit is contained in:
1 parent
7d787867c9
commit
32652326b9
2 files changed
+78
No files matched your search
@@ -67,6 +67,13 @@ var viaCompatTests = []struct {
|
||||
{"via-grant-v62", "via exit steering plus a member rule to autogroup:internet on one port"},
|
||||
}
|
||||
|
||||
// viaCompatSkipReasons lists checks where headscale differs from SaaS,
|
||||
// keyed by check alone where every capture differs the same way. A listed
|
||||
// check that matches fails, so a fix must delete its entry.
|
||||
var viaCompatSkipReasons = map[string]string{
|
||||
"tagged-self": "TAGGED_SELF_PROFILE: SaaS gives a tagged node a profile of its own, headscale the shared tagged-devices one",
|
||||
}
|
||||
|
||||
// TestViaGrantMapCompat loads golden captures from Tailscale SaaS and
|
||||
// compares headscale's [tailcfg.MapResponse] structure against the captured [netmap.NetworkMap].
|
||||
//
|
||||
@@ -479,6 +486,75 @@ func compareNetmap(
|
||||
}
|
||||
|
||||
comparePacketFilter(t, got, want, clients, saasAddrs)
|
||||
compareUserProfiles(t, got, want.Netmap, clients)
|
||||
}
|
||||
|
||||
// compareUserProfiles compares the profile the viewer holds for itself and
|
||||
// for each peer in clients. Profile IDs differ between SaaS and headscale, so
|
||||
// a profile is its login, with SaaS emails mapped to user names, and its
|
||||
// display name.
|
||||
func compareUserProfiles(
|
||||
t require.TestingT,
|
||||
got, want *netmap.NetworkMap,
|
||||
clients map[string]*servertest.TestClient,
|
||||
) {
|
||||
if h, ok := t.(interface{ Helper() }); ok {
|
||||
h.Helper()
|
||||
}
|
||||
|
||||
gotProfiles := nodeProfiles(got, clients)
|
||||
|
||||
for name, wantProfile := range nodeProfiles(want, clients) {
|
||||
check := "peer"
|
||||
if name == "" {
|
||||
check = "self"
|
||||
if want.SelfNode.Tags().Len() > 0 {
|
||||
check = "tagged-self"
|
||||
}
|
||||
}
|
||||
|
||||
if reason, listed := viaCompatSkipReasons[check]; listed {
|
||||
if gotProfiles[name] == wantProfile {
|
||||
t.Errorf("node %q: %s profile matches SaaS; delete viaCompatSkipReasons[%q] (%s)",
|
||||
name, check, check, reason)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
assert.Equalf(t, wantProfile, gotProfiles[name], "node %q: %s profile mismatch", name, check)
|
||||
}
|
||||
}
|
||||
|
||||
// nodeProfiles maps "" (self) and each peer in clients to its user profile.
|
||||
func nodeProfiles(
|
||||
nm *netmap.NetworkMap,
|
||||
clients map[string]*servertest.TestClient,
|
||||
) map[string]string {
|
||||
profile := func(id tailcfg.UserID) string {
|
||||
p, ok := nm.UserProfiles[id]
|
||||
if !ok {
|
||||
return "no profile"
|
||||
}
|
||||
|
||||
login := p.LoginName()
|
||||
if name, ok := captureUserNames[login]; ok {
|
||||
login = name
|
||||
}
|
||||
|
||||
return login + " / " + p.DisplayName()
|
||||
}
|
||||
|
||||
out := map[string]string{"": profile(nm.SelfNode.User())}
|
||||
|
||||
for _, peer := range nm.Peers {
|
||||
name := extractHostname(peer.Name())
|
||||
if _, isOurs := clients[name]; isOurs {
|
||||
out[name] = profile(peer.User())
|
||||
}
|
||||
}
|
||||
|
||||
return out
|
||||
}
|
||||
|
||||
// comparePacketFilter compares PacketFilter rules as a set of (source,
|
||||
|
||||
@@ -337,6 +337,8 @@ func compareCaptureNetmap(
|
||||
len(want.PacketFilterRules), gotLen,
|
||||
)
|
||||
}
|
||||
|
||||
compareUserProfiles(t, nm, want.Netmap, clients)
|
||||
}
|
||||
|
||||
type capturePeerSummary struct {
|
||||
|
||||
Reference in new issue
Block a user