From 4f4e95fc804be949e2f9dfa59075c703ecbc5df5 Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Tue, 16 Jun 2026 08:51:58 +0000 Subject: [PATCH] all: adopt strings, errors, and os helpers --- cmd/headscale/cli/mockoidc.go | 19 ++++++++----------- cmd/headscale/cli/nodes.go | 8 +------- cmd/hi/doctor.go | 7 +++---- hscontrol/derp/derp.go | 9 +-------- hscontrol/grpcv1.go | 4 ++-- hscontrol/policy/v2/filter.go | 10 +--------- integration/dockertestutil/auth.go | 6 +++--- 7 files changed, 19 insertions(+), 44 deletions(-) diff --git a/cmd/headscale/cli/mockoidc.go b/cmd/headscale/cli/mockoidc.go index be951b76..255143ba 100644 --- a/cmd/headscale/cli/mockoidc.go +++ b/cmd/headscale/cli/mockoidc.go @@ -3,6 +3,7 @@ package cli import ( "context" "encoding/json" + "errors" "fmt" "net" "net/http" @@ -16,19 +17,15 @@ import ( "github.com/spf13/cobra" ) -// Error is used to compare errors as per https://dave.cheney.net/2016/04/07/constant-errors -type Error string - -func (e Error) Error() string { return string(e) } - -const ( - errMockOidcClientIDNotDefined = Error("MOCKOIDC_CLIENT_ID not defined") - errMockOidcClientSecretNotDefined = Error("MOCKOIDC_CLIENT_SECRET not defined") - errMockOidcPortNotDefined = Error("MOCKOIDC_PORT not defined") - errMockOidcUsersNotDefined = Error("MOCKOIDC_USERS not defined") - refreshTTL = 60 * time.Minute +var ( + errMockOidcClientIDNotDefined = errors.New("MOCKOIDC_CLIENT_ID not defined") + errMockOidcClientSecretNotDefined = errors.New("MOCKOIDC_CLIENT_SECRET not defined") + errMockOidcPortNotDefined = errors.New("MOCKOIDC_PORT not defined") + errMockOidcUsersNotDefined = errors.New("MOCKOIDC_USERS not defined") ) +const refreshTTL = 60 * time.Minute + var accessTTL = 2 * time.Minute func init() { diff --git a/cmd/headscale/cli/nodes.go b/cmd/headscale/cli/nodes.go index 4bfe1fb5..bc081048 100644 --- a/cmd/headscale/cli/nodes.go +++ b/cmd/headscale/cli/nodes.go @@ -384,13 +384,7 @@ func nodesToPtables(nodes []*v1.Node) (pterm.TableData, error) { expired = pterm.LightGreen("no") } - var tagsBuilder strings.Builder - - for _, tag := range node.GetTags() { - tagsBuilder.WriteString("\n" + tag) - } - - tags := strings.TrimLeft(tagsBuilder.String(), "\n") + tags := strings.Join(node.GetTags(), "\n") var user string if node.GetUser() != nil { diff --git a/cmd/hi/doctor.go b/cmd/hi/doctor.go index f09b642e..593e2f37 100644 --- a/cmd/hi/doctor.go +++ b/cmd/hi/doctor.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "log" + "os" "os/exec" "strings" @@ -283,7 +284,7 @@ func checkGitRepository(ctx context.Context) DoctorResult { } // checkRequiredFiles verifies required files exist. -func checkRequiredFiles(ctx context.Context) DoctorResult { +func checkRequiredFiles(_ context.Context) DoctorResult { requiredFiles := []string{ "go.mod", "integration/", @@ -293,9 +294,7 @@ func checkRequiredFiles(ctx context.Context) DoctorResult { var missingFiles []string for _, file := range requiredFiles { - cmd := exec.CommandContext(ctx, "test", "-e", file) - - err := cmd.Run() + _, err := os.Stat(file) if err != nil { missingFiles = append(missingFiles, file) } diff --git a/hscontrol/derp/derp.go b/hscontrol/derp/derp.go index c5701276..909c4cb5 100644 --- a/hscontrol/derp/derp.go +++ b/hscontrol/derp/derp.go @@ -22,19 +22,12 @@ import ( ) func loadDERPMapFromPath(path string) (*tailcfg.DERPMap, error) { - derpFile, err := os.Open(path) + b, err := os.ReadFile(path) if err != nil { return nil, err } - defer derpFile.Close() var derpMap tailcfg.DERPMap - - b, err := io.ReadAll(derpFile) - if err != nil { - return nil, err - } - err = yaml.Unmarshal(b, &derpMap) return &derpMap, err diff --git a/hscontrol/grpcv1.go b/hscontrol/grpcv1.go index 9416c37c..fbb4f591 100644 --- a/hscontrol/grpcv1.go +++ b/hscontrol/grpcv1.go @@ -420,7 +420,7 @@ func (api headscaleV1APIServer) SetApprovedRoutes( } func validateTag(tag string) error { - if strings.Index(tag, "tag:") != 0 { + if !strings.HasPrefix(tag, "tag:") { return errors.New("tag must start with the string 'tag:'") } if strings.ToLower(tag) != tag { @@ -935,7 +935,7 @@ func (api headscaleV1APIServer) AuthReject( } authReq.FinishAuth(types.AuthVerdict{ - Err: fmt.Errorf("auth request rejected"), + Err: errors.New("auth request rejected"), }) return &v1.AuthRejectResponse{}, nil diff --git a/hscontrol/policy/v2/filter.go b/hscontrol/policy/v2/filter.go index 98e6b06c..6eb99707 100644 --- a/hscontrol/policy/v2/filter.go +++ b/hscontrol/policy/v2/filter.go @@ -5,7 +5,6 @@ import ( "fmt" "net/netip" "slices" - "strconv" "strings" "time" @@ -597,14 +596,7 @@ func groupSourcesByUser( // filterRuleKey generates a unique key for merging based on [tailcfg.FilterRule.SrcIPs] // and [tailcfg.FilterRule.IPProto]. func filterRuleKey(rule tailcfg.FilterRule) string { - srcKey := strings.Join(rule.SrcIPs, ",") - - protoStrs := make([]string, len(rule.IPProto)) - for i, p := range rule.IPProto { - protoStrs[i] = strconv.Itoa(p) - } - - return srcKey + "|" + strings.Join(protoStrs, ",") + return fmt.Sprintf("%s|%v", strings.Join(rule.SrcIPs, ","), rule.IPProto) } // mergeFilterRules merges rules with identical [tailcfg.FilterRule.SrcIPs] and diff --git a/integration/dockertestutil/auth.go b/integration/dockertestutil/auth.go index 3962204d..d818783f 100644 --- a/integration/dockertestutil/auth.go +++ b/integration/dockertestutil/auth.go @@ -162,10 +162,10 @@ func credentialsFromConfig() (string, string, bool) { return "", "", false } - parts := strings.SplitN(string(decoded), ":", 2) - if len(parts) != 2 { + user, pass, ok := strings.Cut(string(decoded), ":") + if !ok { return "", "", false } - return parts[0], parts[1], true + return user, pass, true }