diff --git a/cmd/headscale/cli/users.go b/cmd/headscale/cli/users.go index 5639aa82..a74d64e8 100644 --- a/cmd/headscale/cli/users.go +++ b/cmd/headscale/cli/users.go @@ -36,9 +36,7 @@ func usernameAndIDFromFlag(cmd *cobra.Command) (uint64, string, error) { // Normalise unset/negative identifiers to 0 so the uint64 // conversion does not produce a bogus large value. - if identifier < 0 { - identifier = 0 - } + identifier = max(identifier, 0) return uint64(identifier), username, nil //nolint:gosec // identifier is clamped to >= 0 above } diff --git a/hscontrol/mapper/mapper.go b/hscontrol/mapper/mapper.go index 8b83a62a..bd04d2e7 100644 --- a/hscontrol/mapper/mapper.go +++ b/hscontrol/mapper/mapper.go @@ -4,6 +4,7 @@ import ( "encoding/json" "fmt" "io/fs" + "maps" "net/url" "os" "path" @@ -70,7 +71,6 @@ func generateUserProfiles( peers views.Slice[types.NodeView], ) []tailcfg.UserProfile { userMap := make(map[uint]*types.UserView) - ids := make([]uint, 0, len(userMap)) user := node.Owner() if !user.Valid() { @@ -81,9 +81,7 @@ func generateUserProfiles( return nil } - userID := user.Model().ID - userMap[userID] = &user - ids = append(ids, userID) + userMap[user.Model().ID] = &user for _, peer := range peers.All() { peerUser := peer.Owner() @@ -91,20 +89,13 @@ func generateUserProfiles( continue } - peerUserID := peerUser.Model().ID - userMap[peerUserID] = &peerUser - ids = append(ids, peerUserID) + userMap[peerUser.Model().ID] = &peerUser } - slices.Sort(ids) - ids = slices.Compact(ids) - var profiles []tailcfg.UserProfile - for _, id := range ids { - if userMap[id] != nil { - profiles = append(profiles, userMap[id].TailscaleUserProfile()) - } + for _, id := range slices.Sorted(maps.Keys(userMap)) { + profiles = append(profiles, userMap[id].TailscaleUserProfile()) } return profiles diff --git a/hscontrol/policy/v2/tailnet_state_caps.go b/hscontrol/policy/v2/tailnet_state_caps.go index ddb2ac31..9ee11bf6 100644 --- a/hscontrol/policy/v2/tailnet_state_caps.go +++ b/hscontrol/policy/v2/tailnet_state_caps.go @@ -13,6 +13,7 @@ package v2 // one exists. import ( + "maps" "slices" "strings" @@ -170,15 +171,10 @@ func stripUnmodelledTailnetStateCaps(cm tailcfg.NodeCapMap) tailcfg.NodeCapMap { return nil } - out := make(tailcfg.NodeCapMap, len(cm)) - - for k, v := range cm { - if isUnmodelledTailnetStateCap(k) { - continue - } - - out[k] = v - } + out := maps.Clone(cm) + maps.DeleteFunc(out, func(k tailcfg.NodeCapability, _ []tailcfg.RawMessage) bool { + return isUnmodelledTailnetStateCap(k) + }) if len(out) == 0 { return nil diff --git a/hscontrol/policy/v2/types.go b/hscontrol/policy/v2/types.go index b2b8fddf..a8e1bd85 100644 --- a/hscontrol/policy/v2/types.go +++ b/hscontrol/policy/v2/types.go @@ -1300,10 +1300,8 @@ func (g *Groups) Contains(group *Group) error { return nil } - for defined := range map[Group]Usernames(*g) { - if defined == *group { - return nil - } + if _, ok := (*g)[*group]; ok { + return nil } return fmt.Errorf("%w: %q", ErrGroupNotDefined, group) @@ -1483,10 +1481,8 @@ func (to TagOwners) Contains(tagOwner *Tag) error { return nil } - for defined := range map[Tag]Owners(to) { - if defined == *tagOwner { - return nil - } + if _, ok := to[*tagOwner]; ok { + return nil } return fmt.Errorf("%w: %q", ErrTagNotDefined, tagOwner) diff --git a/hscontrol/state/state.go b/hscontrol/state/state.go index 00077c8d..fc78beb3 100644 --- a/hscontrol/state/state.go +++ b/hscontrol/state/state.go @@ -208,10 +208,7 @@ func (s *State) lockRegistration(machineKey key.MachinePublic) func() { // NewState creates and initializes a new [State] instance, setting up the database, // IP allocator, DERP map, policy manager, and loading existing users and nodes. func NewState(cfg *types.Config) (*State, error) { - cacheExpiration := registerCacheExpiration - if cfg.Tuning.RegisterCacheExpiration != 0 { - cacheExpiration = cfg.Tuning.RegisterCacheExpiration - } + cacheExpiration := cmp.Or(cfg.Tuning.RegisterCacheExpiration, registerCacheExpiration) cacheMaxEntries := defaultRegisterCacheMaxEntries if cfg.Tuning.RegisterCacheMaxEntries > 0 { @@ -264,15 +261,9 @@ func NewState(cfg *types.Config) (*State, error) { // Apply defaults for [NodeStore] batch configuration if not set. // This ensures tests that create Config directly (without viper) still work. - batchSize := cfg.Tuning.NodeStoreBatchSize - if batchSize == 0 { - batchSize = defaultNodeStoreBatchSize - } + batchSize := cmp.Or(cfg.Tuning.NodeStoreBatchSize, defaultNodeStoreBatchSize) - batchTimeout := cfg.Tuning.NodeStoreBatchTimeout - if batchTimeout == 0 { - batchTimeout = defaultNodeStoreBatchTimeout - } + batchTimeout := cmp.Or(cfg.Tuning.NodeStoreBatchTimeout, defaultNodeStoreBatchTimeout) // [policy.PolicyManager.BuildPeerMap] handles both global and per-node filter complexity. // This moves the complex peer relationship logic into the policy package where it belongs. @@ -2588,7 +2579,7 @@ func (s *State) HandleNodeFromPreAuthKey( Expiry: reqExpiry, RegisterMethod: util.RegisterMethodAuthKey, PreAuthKey: pak, - ExistingNodeForNetinfo: cmp.Or(differentUserNode, types.NodeView{}), + ExistingNodeForNetinfo: differentUserNode, }) if err != nil { return types.NodeView{}, change.Change{}, fmt.Errorf("creating new node: %w", err) diff --git a/integration/scenario.go b/integration/scenario.go index 428fcc39..c6d5c419 100644 --- a/integration/scenario.go +++ b/integration/scenario.go @@ -1399,17 +1399,11 @@ func (s *Scenario) GetIPs(user string) ([]netip.Addr, error) { // GetClients returns all [TailscaleClient]s associated with a [User] in a [Scenario]. func (s *Scenario) GetClients(user string) ([]TailscaleClient, error) { - var clients []TailscaleClient - if ns, ok := s.users[user]; ok { - for _, client := range ns.Clients { - clients = append(clients, client) - } - - return clients, nil + return xmaps.Values(ns.Clients), nil } - return clients, fmt.Errorf("getting clients: %w", errNoUserAvailable) + return nil, fmt.Errorf("getting clients: %w", errNoUserAvailable) } // ListTailscaleClients returns a list of [TailscaleClient]s given the [User]s diff --git a/tools/capver/main.go b/tools/capver/main.go index a46ad8ca..368214c8 100644 --- a/tools/capver/main.go +++ b/tools/capver/main.go @@ -10,15 +10,14 @@ import ( "go/format" "io" "log" + "maps" "net/http" "os" "regexp" "slices" - "sort" "strconv" "strings" - xmaps "golang.org/x/exp/maps" "tailscale.com/tailcfg" ) @@ -246,8 +245,7 @@ func getCapabilityVersions(ctx context.Context) (map[string]tailcfg.CapabilityVe func calculateMinSupportedCapabilityVersion(versions map[string]tailcfg.CapabilityVersion) tailcfg.CapabilityVersion { // Since we now store minor versions directly, just sort and take the oldest of the latest N - minorVersions := xmaps.Keys(versions) - sort.Strings(minorVersions) + minorVersions := slices.Sorted(maps.Keys(versions)) supportedCount := min(len(minorVersions), supportedMajorMinorVersions) @@ -264,8 +262,7 @@ func calculateMinSupportedCapabilityVersion(versions map[string]tailcfg.Capabili // firstTailscaleVerPerCapVer inverts versions into a map from each capability // version to the first (lowest-sorted) Tailscale minor version reporting it. func firstTailscaleVerPerCapVer(versions map[string]tailcfg.CapabilityVersion) map[tailcfg.CapabilityVersion]string { - sortedVersions := xmaps.Keys(versions) - sort.Strings(sortedVersions) + sortedVersions := slices.Sorted(maps.Keys(versions)) capVerToTailscaleVer := make(map[tailcfg.CapabilityVersion]string) @@ -288,8 +285,7 @@ func writeCapabilityVersionsToFile(versions map[string]tailcfg.CapabilityVersion content.WriteString("\n\n") content.WriteString("var tailscaleToCapVer = map[string]tailcfg.CapabilityVersion{\n") - sortedVersions := xmaps.Keys(versions) - sort.Strings(sortedVersions) + sortedVersions := slices.Sorted(maps.Keys(versions)) for _, version := range sortedVersions { fmt.Fprintf(&content, "\t\"%s\": %d,\n", version, versions[version]) @@ -302,8 +298,7 @@ func writeCapabilityVersionsToFile(versions map[string]tailcfg.CapabilityVersion capVerToTailscaleVer := firstTailscaleVerPerCapVer(versions) - capsSorted := xmaps.Keys(capVerToTailscaleVer) - slices.Sort(capsSorted) + capsSorted := slices.Sorted(maps.Keys(capVerToTailscaleVer)) for _, capVer := range capsSorted { fmt.Fprintf(&content, "\t%d:\t\t\"%s\",\n", capVer, capVerToTailscaleVer[capVer]) @@ -337,8 +332,7 @@ func writeCapabilityVersionsToFile(versions map[string]tailcfg.CapabilityVersion func writeTestDataFile(versions map[string]tailcfg.CapabilityVersion, minSupportedCapVer tailcfg.CapabilityVersion) error { // Sort minor versions - minorVersions := xmaps.Keys(versions) - sort.Strings(minorVersions) + minorVersions := slices.Sorted(maps.Keys(versions)) // Take latest N supportedCount := min(len(minorVersions), supportedMajorMinorVersions) @@ -416,8 +410,7 @@ func writeTestDataFile(versions map[string]tailcfg.CapabilityVersion, minSupport fmt.Fprintf(&content, "\t{%d, \"%s\"},\n", minSupportedCapVer, minVersionString) // Add a few more test cases - capsSorted := xmaps.Keys(capVerToTailscaleVer) - slices.Sort(capsSorted) + capsSorted := slices.Sorted(maps.Keys(capVerToTailscaleVer)) testCount := 0 for _, capVer := range capsSorted {