mirror of
https://github.com/juanfont/headscale.git
synced 2026-11-01 03:04: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.
(cherry picked from commit 32652326b9)
This commit is contained in:
1 parent
46478663b9
commit
9ce0b28456
2 files changed
+78
No files matched your search
@@ -66,6 +66,13 @@ var viaCompatTests = []struct {
|
|||||||
{"via-grant-v62", "via exit steering plus a member rule to autogroup:internet on one port"},
|
{"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
|
// TestViaGrantMapCompat loads golden captures from Tailscale SaaS and
|
||||||
// compares headscale's [tailcfg.MapResponse] structure against the captured [netmap.NetworkMap].
|
// compares headscale's [tailcfg.MapResponse] structure against the captured [netmap.NetworkMap].
|
||||||
//
|
//
|
||||||
@@ -476,6 +483,75 @@ func compareNetmap(
|
|||||||
}
|
}
|
||||||
|
|
||||||
comparePacketFilter(t, got, want, clients, saasAddrs)
|
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,
|
// comparePacketFilter compares PacketFilter rules as a set of (source,
|
||||||
|
|||||||
@@ -337,6 +337,8 @@ func compareCaptureNetmap(
|
|||||||
len(want.PacketFilterRules), gotLen,
|
len(want.PacketFilterRules), gotLen,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compareUserProfiles(t, nm, want.Netmap, clients)
|
||||||
}
|
}
|
||||||
|
|
||||||
type capturePeerSummary struct {
|
type capturePeerSummary struct {
|
||||||
|
|||||||
Reference in new issue
Block a user