Repository: kubernetes-sigs/apiserver-network-proxy
Pull request #743 (2025-05-22 00:46:25)

Backport to 0.31: Bump golangci/golangci-lint-action from 6 to 8
All lint-actions after 6 require you to use lint version 2+. Pulled the 2.1 version of golangci-lint
Ran 'golangci-lint migrate'
Fixed concerns raised by linter.
Increase lint timeout to 2 minutes.
Move to go lint 2.1.6


Patch:
diff --git a/.github/workflows/golangci-lint.yaml b/.github/workflows/golangci-lint.yaml
index b4a49a5f..d9309825 100644
--- a/.github/workflows/golangci-lint.yaml
+++ b/.github/workflows/golangci-lint.yaml
@@ -11,7 +11,7 @@ permissions:
 
 env:
   GO_VERSION: v1.22
-  GOLANGCI_LINT_VERSION: v1.56
+  GOLANGCI_LINT_VERSION: v2.1.6
 
 jobs:
   golangci:
@@ -23,7 +23,7 @@ jobs:
         with:
           go-version: ${{ env.GO_VERSION }}
       - name: golangci-lint
-        uses: golangci/golangci-lint-action@v6
+        uses: golangci/golangci-lint-action@v8
         with:
           version: ${{ env.GOLANGCI_LINT_VERSION }}
-          args: --verbose
+          args: --verbose --timeout=2m
diff --git a/.golangci.yaml b/.golangci.yaml
index a225e170..9f07886d 100644
--- a/.golangci.yaml
+++ b/.golangci.yaml
@@ -1,20 +1,37 @@
-run:
-  timeout: 5m
+version: "2"
 linters:
-  disable-all: true
+  default: none
   enable:
-  - gofmt
-  - revive
-  - gosec
-  - govet
-  - unused
+    - gosec
+    - govet
+    - revive
+    - unused
+  exclusions:
+    generated: lax
+    presets:
+      - comments
+      - common-false-positives
+      - legacy
+      - std-error-handling
+    rules:
+      - linters:
+          - gosec
+        path: _test\.go
+      - linters:
+          - gosec
+        path: ^tests/
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
 issues:
   fix: true
-  exclude-rules:
-    # Don't run security checks on test files
-    - path: _test\.go
-      linters:
-        - gosec
-    - path: ^tests/
-      linters:
-        - gosec
+formatters:
+  enable:
+    - gofmt
+  exclusions:
+    generated: lax
+    paths:
+      - third_party$
+      - builtin$
+      - examples$
diff --git a/Makefile b/Makefile
index 4013b9bf..5baa35dc 100644
--- a/Makefile
+++ b/Makefile
@@ -33,7 +33,7 @@ endif
 GOOS ?= $(shell go env GOOS)
 GOARCH ?= $(shell go env GOARCH)
 INSTALL_LOCATION:=$(shell go env GOPATH)/bin
-GOLANGCI_LINT_VERSION ?= 1.56.2
+GOLANGCI_LINT_VERSION ?= 2.1.6
 GOSEC_VERSION ?= 2.13.1
 
 REGISTRY ?= gcr.io/$(shell gcloud config get-value project)
diff --git a/cmd/server/app/options/options.go b/cmd/server/app/options/options.go
index a5dbce40..acb2856d 100644
--- a/cmd/server/app/options/options.go
+++ b/cmd/server/app/options/options.go
@@ -74,7 +74,7 @@ type ProxyRunOptions struct {
 	// ID of this proxy server.
 	ServerID string
 	// Number of proxy server instances, should be 1 unless it is a HA proxy server.
-	ServerCount uint
+	ServerCount int
 	// Agent pod's namespace for token-based agent authentication
 	AgentNamespace string
 	// Agent pod's service account for token-based agent authentication
@@ -140,7 +140,7 @@ func (o *ProxyRunOptions) Flags() *pflag.FlagSet {
 	flags.BoolVar(&o.EnableProfiling, "enable-profiling", o.EnableProfiling, "enable pprof at host:admin-port/debug/pprof")
 	flags.BoolVar(&o.EnableContentionProfiling, "enable-contention-profiling", o.EnableContentionProfiling, "enable contention profiling at host:admin-port/debug/pprof/block. \"--enable-profiling\" must also be set.")
 	flags.StringVar(&o.ServerID, "server-id", o.ServerID, "The unique ID of this server. Can also be set by the 'PROXY_SERVER_ID' environment variable.")
-	flags.UintVar(&o.ServerCount, "server-count", o.ServerCount, "The number of proxy server instances, should be 1 unless it is an HA server.")
+	flags.IntVar(&o.ServerCount, "server-count", o.ServerCount, "The number of proxy server instances, should be 1 unless it is an HA server.")
 	flags.StringVar(&o.AgentNamespace, "agent-namespace", o.AgentNamespace, "Expected agent's namespace during agent authentication (used with agent-service-account, authentication-audience, kubeconfig).")
 	flags.StringVar(&o.AgentServiceAccount, "agent-service-account", o.AgentServiceAccount, "Expected agent's service account during agent authentication (used with agent-namespace, authentication-audience, kubeconfig).")
 	flags.StringVar(&o.KubeconfigPath, "kubeconfig", o.KubeconfigPath, "absolute path to the kubeconfig file (used with agent-namespace, agent-service-account, authentication-audience).")
diff --git a/cmd/server/app/server.go b/cmd/server/app/server.go
index 99054957..7e9830cc 100644
--- a/cmd/server/app/server.go
+++ b/cmd/server/app/server.go
@@ -138,7 +138,7 @@ func (p *Proxy) Run(o *options.ProxyRunOptions, stopCh <-chan struct{}) error {
 	if err != nil {
 		return err
 	}
-	p.server = server.NewProxyServer(o.ServerID, ps, int(o.ServerCount), authOpt, o.XfrChannelSize)
+	p.server = server.NewProxyServer(o.ServerID, ps, o.ServerCount, authOpt, o.XfrChannelSize)
 
 	frontendStop, err := p.runFrontendServer(ctx, o, p.server)
 	if err != nil {
@@ -352,7 +352,7 @@ func (p *Proxy) runMTLSFrontendServer(ctx context.Context, o *options.ProxyRunOp
 		}
 		labels := runpprof.Labels(
 			"core", "mtlsGrpcFrontend",
-			"port", strconv.FormatUint(uint64(o.ServerPort), 10),
+			"port", strconv.Itoa(o.ServerPort),
 		)
 		go runpprof.Do(context.Background(), labels, func(context.Context) { grpcServer.Serve(lis) })
 		stop = grpcServer.GracefulStop
@@ -375,7 +375,7 @@ func (p *Proxy) runMTLSFrontendServer(ctx context.Context, o *options.ProxyRunOp
 		}
 		labels := runpprof.Labels(
 			"core", "mtlsHttpFrontend",
-			"port", strconv.FormatUint(uint64(o.ServerPort), 10),
+			"port", strconv.Itoa(o.ServerPort),
 		)
 		go runpprof.Do(context.Background(), labels, func(context.Context) {
 			err := server.ListenAndServeTLS("", "") // empty files defaults to tlsConfig
@@ -412,7 +412,7 @@ func (p *Proxy) runAgentServer(o *options.ProxyRunOptions, server *server.ProxyS
 	}
 	labels := runpprof.Labels(
 		"core", "agentListener",
-		"port", strconv.FormatUint(uint64(o.AgentPort), 10),
+		"port", strconv.Itoa(o.AgentPort),
 	)
 	go runpprof.Do(context.Background(), labels, func(context.Context) { grpcServer.Serve(lis) })
 	p.agentServer = grpcServer
@@ -442,7 +442,7 @@ func (p *Proxy) runAdminServer(o *options.ProxyRunOptions, _ *server.ProxyServer
 
 	labels := runpprof.Labels(
 		"core", "adminListener",
-		"port", strconv.FormatUint(uint64(o.AdminPort), 10),
+		"port", strconv.Itoa(o.AdminPort),
 	)
 	go runpprof.Do(context.Background(), labels, func(context.Context) {
 		err := p.adminServer.ListenAndServe()
@@ -484,7 +484,7 @@ func (p *Proxy) runHealthServer(o *options.ProxyRunOptions, server *server.Proxy
 
 	labels := runpprof.Labels(
 		"core", "healthListener",
-		"port", strconv.FormatUint(uint64(o.HealthPort), 10),
+		"port", strconv.Itoa(o.HealthPort),
 	)
 	go runpprof.Do(context.Background(), labels, func(context.Context) {
 		err := p.healthServer.ListenAndServe()


Test patch:
diff --git a/cmd/server/app/options/options_test.go b/cmd/server/app/options/options_test.go
index 8e85b51d..10b9146b 100644
--- a/cmd/server/app/options/options_test.go
+++ b/cmd/server/app/options/options_test.go
@@ -52,7 +52,7 @@ func TestDefaultServerOptions(t *testing.T) {
 	assertDefaultValue(t, "FrontendKeepaliveTime", defaultServerOptions.FrontendKeepaliveTime, 1*time.Hour)
 	assertDefaultValue(t, "EnableProfiling", defaultServerOptions.EnableProfiling, false)
 	assertDefaultValue(t, "EnableContentionProfiling", defaultServerOptions.EnableContentionProfiling, false)
-	assertDefaultValue(t, "ServerCount", defaultServerOptions.ServerCount, uint(1))
+	assertDefaultValue(t, "ServerCount", defaultServerOptions.ServerCount, 1)
 	assertDefaultValue(t, "AgentNamespace", defaultServerOptions.AgentNamespace, "")
 	assertDefaultValue(t, "AgentServiceAccount", defaultServerOptions.AgentServiceAccount, "")
 	assertDefaultValue(t, "KubeconfigPath", defaultServerOptions.KubeconfigPath, "")
diff --git a/tests/framework/proxy_server.go b/tests/framework/proxy_server.go
index 4ad740b6..4af10bf7 100644
--- a/tests/framework/proxy_server.go
+++ b/tests/framework/proxy_server.go
@@ -139,7 +139,7 @@ func serverOptions(t testing.TB, opts ProxyServerOpts) (*serveropts.ProxyRunOpti
 	t.Helper()
 	o := serveropts.NewProxyRunOptions()
 
-	o.ServerCount = uint(opts.ServerCount)
+	o.ServerCount = opts.ServerCount
 	o.Mode = opts.Mode
 
 	uid := uuid.New().String()
diff --git a/tests/proxy_test.go b/tests/proxy_test.go
index 49adb0c3..aac24700 100644
--- a/tests/proxy_test.go
+++ b/tests/proxy_test.go
@@ -105,11 +105,13 @@ type delayedServer struct {
 	maxWait time.Duration
 }
 
-// randomDuration returns a random duration in the [min, max) interval
-func randomDuration(min, max time.Duration) time.Duration {
-	d := min
-	if max != min {
-		d += time.Duration(rand.Int63n(int64(max - min)))
+// randomDuration returns a random duration in the [lower, upper) interval
+// Cannot use min/max because linter gives the following error.
+// "redefines-builtin-id: redefinition of the built-in function min (revive)"
+func randomDuration(lower, upper time.Duration) time.Duration {
+	d := lower
+	if upper != lower {
+		d += time.Duration(rand.Int63n(int64(upper - lower)))
 	}
 	return d
 }