diff --git a/.github/workflows/validate.yaml b/.github/workflows/validate.yaml new file mode 100644 index 000000000000..9f537b83e939 --- /dev/null +++ b/.github/workflows/validate.yaml @@ -0,0 +1,63 @@ +name: Validate +on: + pull_request: + paths-ignore: + - "**.md" + - "channel.yaml" + - "install.sh" + - "tests/**" + - "!tests/e2e**" + - "!tests/docker**" + - ".github/**" + - "!.github/actions/**" + - "!.github/workflows/validate.yaml" + +permissions: + contents: read + +jobs: + validate: + name: Validate + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + with: + fetch-depth: ${{ github.event.pull_request.commits }} + + - name: Set Go Version + run: | + source ./scripts/version.sh + { + echo "GOTOOLCHAIN=${VERSION_GOLANG/go}" + } >> "$GITHUB_ENV" + + - name: Setup Go + uses: actions/setup-go@v6 + with: + go-version: "${{ env.GOTOOLCHAIN }}" + + - name: Lint + uses: golangci/golangci-lint-action@v9 + with: + version: v2.7 + args: "--new-from-merge-base ${{ github.event.pull_request.base.sha }}" + + - name: Lint (windows) + uses: golangci/golangci-lint-action@v9 + with: + version: v2.7 + args: "--new-from-merge-base ${{ github.event.pull_request.base.sha }} ./pkg/... ./cmd/..." + env: + GOOS: "windows" + + - name: Validate + run: ./scripts/validate + env: + SKIP_LINT: "true" + + - name: Validate (windows) + run: ./scripts/validate + env: + SKIP_LINT: "true" + GOOS: "windows" diff --git a/.golangci.json b/.golangci.json deleted file mode 100644 index 28a4b5daf003..000000000000 --- a/.golangci.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "linters": { - "disable-all": true, - "enable": [ - "govet", - "revive", - "goimports", - "misspell", - "gofmt" - ] - }, - "run": { - "deadline": "5m" - }, - "issues": { - "exclude-dirs": [ - "build", - "contrib", - "manifests", - "package", - "scripts", - "vendor" - ], - "exclude-files": [ - "/zz_generated_" - ], - "exclude-rules": [ - { - "linters": "typecheck", - "text": "imported but not used" - }, - { - "linters": "typecheck", - "text": "build constraints exclude all Go files" - }, - { - "linters": "revive", - "text": "should have comment" - }, - { - "linters": "revive", - "text": "exported" - } - ] - } -} diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 000000000000..31f748c17cea --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,56 @@ +issues: + max-issues-per-linter: 1000 + max-same-issues: 100 +formatters: + enable: + - gofmt + - goimports + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ +linters: + default: none + enable: + - govet + - revive + settings: + revive: + enable-all-rules: true + rules: + - {name: add-constant, disabled: true} + - {name: argument-limit, disabled: true} + - {name: cognitive-complexity, disabled: true} + - {name: confusing-naming, disabled: true} + - {name: confusing-results, disabled: true} + - {name: cyclomatic, disabled: true} + - {name: early-return, disabled: true} + - {name: empty-block, disabled: true} + - {name: enforce-switch-style, disabled: true} + - {name: flag-parameter, disabled: true} + - {name: function-length, disabled: true} + - {name: function-result-limit, disabled: true} + - {name: import-shadowing, disabled: true} + - {name: line-length-limit, disabled: true} + - {name: max-control-nesting, disabled: true} + - {name: max-public-structs, disabled: true} + - {name: redundant-import-alias, disabled: true} + - {name: unsecure-url-scheme, disabled: true} + - {name: unused-parameter, disabled: true} + - {name: unused-receiver, disabled: true} + - {name: var-naming, disabled: true} + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ + - tests/ + presets: + - comments + - common-false-positives + - legacy + - std-error-handling +version: "2" diff --git a/Dockerfile.dapper b/Dockerfile.dapper index 498114f8dd5a..0511b6d6950d 100644 --- a/Dockerfile.dapper +++ b/Dockerfile.dapper @@ -28,14 +28,14 @@ RUN case "$(go env GOARCH)" in \ fi # Install goimports -RUN GOPROXY=direct go install golang.org/x/tools/cmd/goimports@gopls/v0.16.0 +RUN GOPROXY=direct go install golang.org/x/tools/cmd/goimports@gopls/v0.20.0 # Cleanup RUN rm -rf /go/src /go/pkg # Install golangci-lint for amd64 RUN if [ "$(go env GOARCH)" = "amd64" ]; then \ - curl -sL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.55.2; \ + curl -sL https://raw.githubusercontent.com/golangci/golangci-lint/refs/tags/v2.7.2/install.sh | sh -s -- v2.7.2; \ fi # Set SELINUX environment variable diff --git a/Dockerfile.local b/Dockerfile.local index 2ca3e4ed9c59..1a4e242d8608 100644 --- a/Dockerfile.local +++ b/Dockerfile.local @@ -11,11 +11,11 @@ RUN apk -U --no-cache add bash git gcc musl-dev docker vim less file curl wget c fi # Install goimports -RUN GOPROXY=direct go install golang.org/x/tools/cmd/goimports@gopls/v0.16.0 +RUN GOPROXY=direct go install golang.org/x/tools/cmd/goimports@gopls/v0.20.0 RUN rm -rf /go/src /go/pkg RUN if [ "$(go env GOARCH)" = "amd64" ]; then \ - curl -sL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.51.2; \ + curl -sL https://raw.githubusercontent.com/golangci/golangci-lint/refs/tags/v2.7.2/install.sh | sh -s -- v2.7.2; \ fi ARG SELINUX=true diff --git a/cmd/k3s/main_linux.go b/cmd/k3s/main_linux.go index bc427498caef..21247bfb3728 100644 --- a/cmd/k3s/main_linux.go +++ b/cmd/k3s/main_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package main diff --git a/cmd/k3s/main_windows.go b/cmd/k3s/main_windows.go index cefca3c91e67..876b13fe4672 100644 --- a/cmd/k3s/main_windows.go +++ b/cmd/k3s/main_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package main diff --git a/pkg/agent/config/config.go b/pkg/agent/config/config.go index 7268dfdc9d46..75d9d225cd62 100644 --- a/pkg/agent/config/config.go +++ b/pkg/agent/config/config.go @@ -343,7 +343,7 @@ func splitCertKeyPEM(bytes []byte) (certPem []byte, keyPem []byte) { } } - return + return certPem, keyPem } // getKubeletClientCert fills the kubelet client certificate with content returned @@ -392,9 +392,8 @@ func isValidResolvConf(resolvConfFile string) bool { if len(ipMatch) == 2 { if !isValidNameserver(ipMatch[1]) { return false - } else { - foundNameserver = true } + foundNameserver = true } } if err := scanner.Err(); err != nil { @@ -833,7 +832,7 @@ func validateNetworkConfig(nodeConfig *config.Node) error { // Old versions of the server do not send enough information to correctly start the NPC. Users // need to upgrade the server to at least the same version as the agent, or disable the NPC // cluster-wide. - if nodeConfig.AgentConfig.DisableNPC == false && (nodeConfig.AgentConfig.ServiceCIDR == nil || nodeConfig.AgentConfig.ServiceNodePortRange.Size == 0) { + if !nodeConfig.AgentConfig.DisableNPC && (nodeConfig.AgentConfig.ServiceCIDR == nil || nodeConfig.AgentConfig.ServiceNodePortRange.Size == 0) { return fmt.Errorf("incompatible down-level server detected; servers must be upgraded to at least %s, or restarted with --disable-network-policy", version.Version) } diff --git a/pkg/agent/config/config_linux.go b/pkg/agent/config/config_linux.go index 34d8216c033f..4f4a227dd18a 100644 --- a/pkg/agent/config/config_linux.go +++ b/pkg/agent/config/config_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package config diff --git a/pkg/agent/config/config_linux_test.go b/pkg/agent/config/config_linux_test.go index 868304fcb86c..bfb0b4048f53 100644 --- a/pkg/agent/config/config_linux_test.go +++ b/pkg/agent/config/config_linux_test.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package config diff --git a/pkg/agent/config/config_windows.go b/pkg/agent/config/config_windows.go index 03f16f4d654c..65a0cf060f17 100644 --- a/pkg/agent/config/config_windows.go +++ b/pkg/agent/config/config_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package config diff --git a/pkg/agent/containerd/config.go b/pkg/agent/containerd/config.go index b139c4aa725b..077e60b195ba 100644 --- a/pkg/agent/containerd/config.go +++ b/pkg/agent/containerd/config.go @@ -162,17 +162,17 @@ func getHostConfigs(registry *registries.Registry, noDefaultEndpoint bool, mirro // create the default config, if it wasn't explicitly mentioned in the config section config, ok := hosts[host] if !ok { - if c, err := defaultHostConfig(host, mirrorAddr, configForHost(registry.Configs, host)); err != nil { + c, err := defaultHostConfig(host, mirrorAddr, configForHost(registry.Configs, host)) + if err != nil { logrus.Errorf("Failed to generate config for registry %s: %v", host, err) continue - } else { - if noDefaultEndpoint { - c.Default = nil - } else if host == "*" { - c.Default = &templates.RegistryEndpoint{URL: &url.URL{}} - } - config = *c } + if noDefaultEndpoint { + c.Default = nil + } else if host == "*" { + c.Default = &templates.RegistryEndpoint{URL: &url.URL{}} + } + config = *c } // track which endpoints we've already seen to avoid creating duplicates diff --git a/pkg/agent/containerd/config_linux.go b/pkg/agent/containerd/config_linux.go index 0ef89e5e33f7..7a34ad7bb3bd 100644 --- a/pkg/agent/containerd/config_linux.go +++ b/pkg/agent/containerd/config_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package containerd diff --git a/pkg/agent/containerd/config_windows.go b/pkg/agent/containerd/config_windows.go index 5935de31c103..6e5ebcdf6ac8 100644 --- a/pkg/agent/containerd/config_windows.go +++ b/pkg/agent/containerd/config_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package containerd diff --git a/pkg/agent/containerd/runtimes.go b/pkg/agent/containerd/runtimes.go index d0a2be7763a1..c378db281a80 100644 --- a/pkg/agent/containerd/runtimes.go +++ b/pkg/agent/containerd/runtimes.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package containerd diff --git a/pkg/agent/containerd/runtimes_test.go b/pkg/agent/containerd/runtimes_test.go index f388b13f71e4..08dc026293cc 100644 --- a/pkg/agent/containerd/runtimes_test.go +++ b/pkg/agent/containerd/runtimes_test.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package containerd @@ -130,9 +129,5 @@ func createExec(path string) error { return err } - if err := os.Chmod(path, 0755); err != nil { - return err - } - - return nil + return os.Chmod(path, 0755) } diff --git a/pkg/agent/cri/cri_linux.go b/pkg/agent/cri/cri_linux.go index d6e3387d584d..8757ac46aca8 100644 --- a/pkg/agent/cri/cri_linux.go +++ b/pkg/agent/cri/cri_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package cri diff --git a/pkg/agent/cri/cri_windows.go b/pkg/agent/cri/cri_windows.go index 5eaff1c8a84f..0fe294a63538 100644 --- a/pkg/agent/cri/cri_windows.go +++ b/pkg/agent/cri/cri_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package cri diff --git a/pkg/agent/cridockerd/config_linux.go b/pkg/agent/cridockerd/config_linux.go index e50ec3c462a5..b49ed87cd9bc 100644 --- a/pkg/agent/cridockerd/config_linux.go +++ b/pkg/agent/cridockerd/config_linux.go @@ -1,5 +1,4 @@ //go:build linux && !no_cri_dockerd -// +build linux,!no_cri_dockerd package cridockerd diff --git a/pkg/agent/cridockerd/config_windows.go b/pkg/agent/cridockerd/config_windows.go index 3630c26eae15..86b146b3fdd3 100644 --- a/pkg/agent/cridockerd/config_windows.go +++ b/pkg/agent/cridockerd/config_windows.go @@ -1,5 +1,4 @@ //go:build windows && !no_cri_dockerd -// +build windows,!no_cri_dockerd package cridockerd diff --git a/pkg/agent/cridockerd/cridockerd.go b/pkg/agent/cridockerd/cridockerd.go index d528d0c1e8b5..46bb9df29da6 100644 --- a/pkg/agent/cridockerd/cridockerd.go +++ b/pkg/agent/cridockerd/cridockerd.go @@ -1,5 +1,4 @@ //go:build !no_cri_dockerd -// +build !no_cri_dockerd package cridockerd diff --git a/pkg/agent/cridockerd/nocridockerd.go b/pkg/agent/cridockerd/nocridockerd.go index ba244743e3ab..a9cb1b777223 100644 --- a/pkg/agent/cridockerd/nocridockerd.go +++ b/pkg/agent/cridockerd/nocridockerd.go @@ -1,5 +1,4 @@ //go:build no_cri_dockerd -// +build no_cri_dockerd package cridockerd diff --git a/pkg/agent/flannel/flannel.go b/pkg/agent/flannel/flannel.go index 0c6cd311da89..c9cda4834209 100644 --- a/pkg/agent/flannel/flannel.go +++ b/pkg/agent/flannel/flannel.go @@ -100,7 +100,7 @@ func flannel(ctx context.Context, wg *sync.WaitGroup, flannelIface *net.Interfac return errors.New("ipv4 mode requested but no ipv4 network provided") } - //setup masq rules + // setup masq rules prevNetwork := ReadCIDRFromSubnetFile(subnetFile, "FLANNEL_NETWORK") prevSubnet := ReadCIDRFromSubnetFile(subnetFile, "FLANNEL_SUBNET") @@ -109,14 +109,14 @@ func flannel(ctx context.Context, wg *sync.WaitGroup, flannelIface *net.Interfac if flannelIPv6Masq { err = trafficMngr.SetupAndEnsureMasqRules(ctx, config.Network, prevSubnet, prevNetwork, config.IPv6Network, prevIPv6Subnet, prevIPv6Network, bn.Lease(), 60, false) } else { - //set empty flannel ipv6 Network to prevent masquerading + // set empty flannel ipv6 Network to prevent masquerading err = trafficMngr.SetupAndEnsureMasqRules(ctx, config.Network, prevSubnet, prevNetwork, ip.IP6Net{}, prevIPv6Subnet, prevIPv6Network, bn.Lease(), 60, false) } if err != nil { return pkgerrors.WithMessage(err, "failed to setup masq rules") } - //setup forward rules + // setup forward rules trafficMngr.SetupAndEnsureForwardRules(ctx, config.Network, config.IPv6Network, 50) if err := WriteSubnetFile(subnetFile, config.Network, config.IPv6Network, true, bn, nm); err != nil { @@ -219,76 +219,72 @@ func WriteSubnetFile(path string, nw ip.IP4Net, nwv6 ip.IP6Net, ipMasq bool, bn // rename(2) the temporary file to the desired location so that it becomes // atomically visible with the contents return os.Rename(tempFile, path) - //TODO - is this safe? What if it's not on the same FS? + // TODO - is this safe? What if it's not on the same FS? } -// ReadCIDRFromSubnetFile reads the flannel subnet file and extracts the value of IPv4 network CIDRKey -func ReadCIDRFromSubnetFile(path string, CIDRKey string) ip.IP4Net { - prevCIDRs := ReadCIDRsFromSubnetFile(path, CIDRKey) +// ReadCIDRFromSubnetFile reads the flannel subnet file and extracts the value of IPv4 network key +func ReadCIDRFromSubnetFile(path string, key string) ip.IP4Net { + prevCIDRs := ReadCIDRsFromSubnetFile(path, key) if len(prevCIDRs) == 0 { - logrus.Warningf("no subnet found for key: %s in file: %s", CIDRKey, path) + logrus.Warningf("no subnet found for key: %s in file: %s", key, path) return ip.IP4Net{IP: 0, PrefixLen: 0} } else if len(prevCIDRs) > 1 { - logrus.Errorf("error reading subnet: more than 1 entry found for key: %s in file %s: ", CIDRKey, path) + logrus.Errorf("error reading subnet: more than 1 entry found for key: %s in file %s: ", key, path) return ip.IP4Net{IP: 0, PrefixLen: 0} - } else { - return prevCIDRs[0] } + return prevCIDRs[0] } -func ReadCIDRsFromSubnetFile(path string, CIDRKey string) []ip.IP4Net { +func ReadCIDRsFromSubnetFile(path string, key string) []ip.IP4Net { prevCIDRs := make([]ip.IP4Net, 0) if _, err := os.Stat(path); !os.IsNotExist(err) { prevSubnetVals, err := godotenv.Read(path) if err != nil { - logrus.Errorf("Couldn't fetch previous %s from subnet file at %s: %v", CIDRKey, path, err) - } else if prevCIDRString, ok := prevSubnetVals[CIDRKey]; ok { + logrus.Errorf("Couldn't fetch previous %s from subnet file at %s: %v", key, path, err) + } else if prevCIDRString, ok := prevSubnetVals[key]; ok { cidrs := strings.Split(prevCIDRString, ",") prevCIDRs = make([]ip.IP4Net, 0) for i := range cidrs { _, cidr, err := net.ParseCIDR(cidrs[i]) if err != nil { - logrus.Errorf("Couldn't parse previous %s from subnet file at %s: %v", CIDRKey, path, err) + logrus.Errorf("Couldn't parse previous %s from subnet file at %s: %v", key, path, err) } prevCIDRs = append(prevCIDRs, ip.FromIPNet(cidr)) } - } } return prevCIDRs } -// ReadIP6CIDRFromSubnetFile reads the flannel subnet file and extracts the value of IPv6 network CIDRKey -func ReadIP6CIDRFromSubnetFile(path string, CIDRKey string) ip.IP6Net { - prevCIDRs := ReadIP6CIDRsFromSubnetFile(path, CIDRKey) +// ReadIP6CIDRFromSubnetFile reads the flannel subnet file and extracts the value of IPv6 network key +func ReadIP6CIDRFromSubnetFile(path string, key string) ip.IP6Net { + prevCIDRs := ReadIP6CIDRsFromSubnetFile(path, key) if len(prevCIDRs) == 0 { - logrus.Warningf("no subnet found for key: %s in file: %s", CIDRKey, path) + logrus.Warningf("no subnet found for key: %s in file: %s", key, path) return ip.IP6Net{IP: (*ip.IP6)(big.NewInt(0)), PrefixLen: 0} } else if len(prevCIDRs) > 1 { - logrus.Errorf("error reading subnet: more than 1 entry found for key: %s in file %s: ", CIDRKey, path) + logrus.Errorf("error reading subnet: more than 1 entry found for key: %s in file %s: ", key, path) return ip.IP6Net{IP: (*ip.IP6)(big.NewInt(0)), PrefixLen: 0} - } else { - return prevCIDRs[0] } + return prevCIDRs[0] } -func ReadIP6CIDRsFromSubnetFile(path string, CIDRKey string) []ip.IP6Net { +func ReadIP6CIDRsFromSubnetFile(path string, key string) []ip.IP6Net { prevCIDRs := make([]ip.IP6Net, 0) if _, err := os.Stat(path); !os.IsNotExist(err) { prevSubnetVals, err := godotenv.Read(path) if err != nil { - logrus.Errorf("Couldn't fetch previous %s from subnet file at %s: %v", CIDRKey, path, err) - } else if prevCIDRString, ok := prevSubnetVals[CIDRKey]; ok { + logrus.Errorf("Couldn't fetch previous %s from subnet file at %s: %v", key, path, err) + } else if prevCIDRString, ok := prevSubnetVals[key]; ok { cidrs := strings.Split(prevCIDRString, ",") prevCIDRs = make([]ip.IP6Net, 0) for i := range cidrs { _, cidr, err := net.ParseCIDR(cidrs[i]) if err != nil { - logrus.Errorf("Couldn't parse previous %s from subnet file at %s: %v", CIDRKey, path, err) + logrus.Errorf("Couldn't parse previous %s from subnet file at %s: %v", key, path, err) } prevCIDRs = append(prevCIDRs, ip.FromIP6Net(cidr)) } - } } return prevCIDRs diff --git a/pkg/agent/flannel/setup.go b/pkg/agent/flannel/setup.go index b2a16bba9905..27c9b0148a58 100644 --- a/pkg/agent/flannel/setup.go +++ b/pkg/agent/flannel/setup.go @@ -216,18 +216,18 @@ func createFlannelConf(nodeConfig *config.Node) error { confJSON = strings.ReplaceAll(confJSON, "%CIDR_IPV6%", emptyIPv6Network) } - var backendConf string - - // precheck and error out unsupported flannel backends. - switch nodeConfig.Flannel.Backend { - case BackendHostGW: - case BackendTailscale: - case BackendWireguardNative: - if goruntime.GOOS == "windows" { + // precheck and error out unsupported flannel backends for windows. + if goruntime.GOOS == "windows" { + switch nodeConfig.Flannel.Backend { + case BackendVXLAN, BackendNone: + // these are the only supported backends + default: return fmt.Errorf("unsupported flannel backend '%s' for Windows", nodeConfig.Flannel.Backend) } } + var backendConf string + switch nodeConfig.Flannel.Backend { case BackendVXLAN: backendConf = vxlanBackend @@ -242,7 +242,7 @@ func createFlannelConf(nodeConfig *config.Node) error { routes = append(routes, "$IPV6SUBNET") } if len(routes) == 0 { - return fmt.Errorf("incorrect netMode for flannel tailscale backend") + return errors.New("incorrect netMode for flannel tailscale backend") } advertisedRoutes, err := vpn.GetAdvertisedRoutes() if err == nil && advertisedRoutes != nil { diff --git a/pkg/agent/flannel/setup_linux.go b/pkg/agent/flannel/setup_linux.go index 36404a01c68f..6bddf24dd59d 100644 --- a/pkg/agent/flannel/setup_linux.go +++ b/pkg/agent/flannel/setup_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package flannel diff --git a/pkg/agent/flannel/setup_test.go b/pkg/agent/flannel/setup_test.go index 20450deb8cb1..2e1cef697aee 100644 --- a/pkg/agent/flannel/setup_test.go +++ b/pkg/agent/flannel/setup_test.go @@ -35,7 +35,6 @@ func Test_findNetMode(t *testing.T) { {"wrong input", "wrong", false, false, true}, } for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { netCidrs := stringToCIDR(tt.args) got, err := findNetMode(netCidrs) @@ -80,7 +79,7 @@ func Test_createFlannelConf(t *testing.T) { } data, err := os.ReadFile("test_file") if err != nil { - t.Errorf("Something went wrong when reading the flannel config file") + t.Error("Something went wrong when reading the flannel config file") } for _, config := range tt.wantConfig { isExist, _ := regexp.Match(config, data) diff --git a/pkg/agent/flannel/setup_windows.go b/pkg/agent/flannel/setup_windows.go index 7b9c513cd364..83106105c747 100644 --- a/pkg/agent/flannel/setup_windows.go +++ b/pkg/agent/flannel/setup_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package flannel diff --git a/pkg/agent/loadbalancer/httpproxy.go b/pkg/agent/loadbalancer/httpproxy.go index 991db1d56c3f..685060a1c03d 100644 --- a/pkg/agent/loadbalancer/httpproxy.go +++ b/pkg/agent/loadbalancer/httpproxy.go @@ -9,7 +9,7 @@ import ( "time" "github.com/k3s-io/k3s/pkg/version" - http_dialer "github.com/mwitkow/go-http-dialer" + httpdialer "github.com/mwitkow/go-http-dialer" pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" "golang.org/x/net/http/httpproxy" @@ -60,7 +60,7 @@ func SetHTTPProxy(address string) error { func proxyDialer(proxyURL *url.URL, forward proxy.Dialer) (proxy.Dialer, error) { if proxyURL.Scheme == "http" || proxyURL.Scheme == "https" { // Create a new HTTP proxy dialer - httpProxyDialer := http_dialer.New(proxyURL, http_dialer.WithConnectionTimeout(10*time.Second), http_dialer.WithDialer(forward.(*net.Dialer))) + httpProxyDialer := httpdialer.New(proxyURL, httpdialer.WithConnectionTimeout(10*time.Second), httpdialer.WithDialer(forward.(*net.Dialer))) return httpProxyDialer, nil } else if proxyURL.Scheme == "socks5" { // For SOCKS5 proxies, use the proxy package's FromURL diff --git a/pkg/agent/loadbalancer/loadbalancer_test.go b/pkg/agent/loadbalancer/loadbalancer_test.go index 69b4fca10cab..213105782663 100644 --- a/pkg/agent/loadbalancer/loadbalancer_test.go +++ b/pkg/agent/loadbalancer/loadbalancer_test.go @@ -10,8 +10,10 @@ import ( "testing" "time" + //revive:disable:dot-imports . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + "github.com/sirupsen/logrus" ) @@ -82,7 +84,7 @@ func (s *testServer) echo(conn net.Conn) { } func ping(conn net.Conn) (string, error) { - fmt.Fprintf(conn, "ping\n") + fmt.Fprint(conn, "ping\n") result, err := bufio.NewReader(conn).ReadString('\n') if err != nil { return "", err @@ -261,7 +263,6 @@ var _ = Describe("LoadBalancer", func() { // confirm that the default is still listed as default Expect(lb.servers.getDefaultAddress()).To(Equal(defaultServer.address), "default server is not default") - }) It("does not return the default server in the address list after removing it", func() { diff --git a/pkg/agent/loadbalancer/servers.go b/pkg/agent/loadbalancer/servers.go index 13334ea881dc..c965e97ba48e 100644 --- a/pkg/agent/loadbalancer/servers.go +++ b/pkg/agent/loadbalancer/servers.go @@ -249,16 +249,19 @@ func (sl *serverList) recordSuccess(srv *server, r reason) { switch s.state { case stateFailed, stateStandby, stateRecovering, stateHealthy: // close connections to other non-active servers whenever we have a new active server + //revive:disable-next-line:defer defer s.closeAll() case stateActive: if len(s.connections) > len(srv.connections) { // if there is a currently active server that has more connections than we do, // close our connections and go to preferred instead new_state = statePreferred + //revive:disable-next-line:defer defer srv.closeAll() } else { // otherwise, close its connections and demote it to preferred s.state = statePreferred + //revive:disable-next-line:defer defer s.closeAll() } } diff --git a/pkg/agent/loadbalancer/utility_windows.go b/pkg/agent/loadbalancer/utility_windows.go index 60fe130434e4..8e3d18027a6d 100644 --- a/pkg/agent/loadbalancer/utility_windows.go +++ b/pkg/agent/loadbalancer/utility_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package loadbalancer diff --git a/pkg/agent/netpol/netpol.go b/pkg/agent/netpol/netpol.go index d057c0cc0dfd..f8b1f0f3a921 100644 --- a/pkg/agent/netpol/netpol.go +++ b/pkg/agent/netpol/netpol.go @@ -2,7 +2,6 @@ // - modified from https://github.com/cloudnativelabs/kube-router/blob/73b1b03b32c5755b240f6c077bb097abe3888314/pkg/controllers/netpol.go //go:build !windows -// +build !windows package netpol @@ -30,7 +29,6 @@ import ( pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" v1 "k8s.io/api/core/v1" - v1core "k8s.io/api/core/v1" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" ) @@ -126,21 +124,21 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error informerFactory.Start(stopCh) informerFactory.WaitForCacheSync(stopCh) - iptablesCmdHandlers := make(map[v1core.IPFamily]utils.IPTablesHandler, 2) - ipSetHandlers := make(map[v1core.IPFamily]utils.IPSetHandler, 2) + iptablesCmdHandlers := make(map[v1.IPFamily]utils.IPTablesHandler, 2) + ipSetHandlers := make(map[v1.IPFamily]utils.IPSetHandler, 2) if nodeConfig.AgentConfig.EnableIPv4 { iptHandler, err := iptables.NewWithProtocol(iptables.ProtocolIPv4) if err != nil { return pkgerrors.WithMessage(err, "failed to create iptables handler") } - iptablesCmdHandlers[v1core.IPv4Protocol] = iptHandler + iptablesCmdHandlers[v1.IPv4Protocol] = iptHandler ipset, err := utils.NewIPSet(false) if err != nil { return pkgerrors.WithMessage(err, "failed to create ipset handler") } - ipSetHandlers[v1core.IPv4Protocol] = ipset + ipSetHandlers[v1.IPv4Protocol] = ipset } if nodeConfig.AgentConfig.EnableIPv6 { @@ -148,13 +146,13 @@ func Run(ctx context.Context, wg *sync.WaitGroup, nodeConfig *config.Node) error if err != nil { return pkgerrors.WithMessage(err, "failed to create iptables handler") } - iptablesCmdHandlers[v1core.IPv6Protocol] = ipt6Handler + iptablesCmdHandlers[v1.IPv6Protocol] = ipt6Handler ipset, err := utils.NewIPSet(true) if err != nil { return pkgerrors.WithMessage(err, "failed to create ipset handler") } - ipSetHandlers[v1core.IPv6Protocol] = ipset + ipSetHandlers[v1.IPv6Protocol] = ipset } // Start kube-router healthcheck controller; netpol requires it diff --git a/pkg/agent/proxy/apiproxy.go b/pkg/agent/proxy/apiproxy.go index c291a59799cb..3f521ae4bab7 100644 --- a/pkg/agent/proxy/apiproxy.go +++ b/pkg/agent/proxy/apiproxy.go @@ -3,7 +3,6 @@ package proxy import ( "context" "net" - sysnet "net" "net/url" "strconv" @@ -117,12 +116,12 @@ func (p *proxy) SetHealthCheck(address string, healthCheck loadbalancer.HealthCh func (p *proxy) setSupervisorPort(addresses []string) []string { var newAddresses []string for _, address := range addresses { - h, _, err := sysnet.SplitHostPort(address) + h, _, err := net.SplitHostPort(address) if err != nil { logrus.Errorf("Failed to parse address %s, dropping: %v", address, err) continue } - newAddresses = append(newAddresses, sysnet.JoinHostPort(h, p.supervisorPort)) + newAddresses = append(newAddresses, net.JoinHostPort(h, p.supervisorPort)) } return newAddresses } @@ -143,7 +142,7 @@ func (p *proxy) SetAPIServerPort(port int, isIPv6 bool) error { return pkgerrors.WithMessagef(err, "failed to parse server URL %s", p.initialSupervisorURL) } p.apiServerPort = strconv.Itoa(port) - u.Host = sysnet.JoinHostPort(u.Hostname(), p.apiServerPort) + u.Host = net.JoinHostPort(u.Hostname(), p.apiServerPort) if p.lbEnabled && p.apiServerLB == nil { lbServerPort := p.lbServerPort @@ -170,14 +169,14 @@ func (p *proxy) SetAPIServerPort(port int, isIPv6 bool) error { // supervisor must be used to bootstrap the agent config, but then switched over to // another node running an apiserver once one is available. func (p *proxy) SetSupervisorDefault(address string) { - host, port, err := sysnet.SplitHostPort(address) + host, port, err := net.SplitHostPort(address) if err != nil { logrus.Errorf("Failed to parse address %s, dropping: %v", address, err) return } if p.apiServerEnabled { port = p.supervisorPort - address = sysnet.JoinHostPort(host, port) + address = net.JoinHostPort(host, port) } p.fallbackSupervisorAddress = address if p.supervisorLB == nil { diff --git a/pkg/agent/run.go b/pkg/agent/run.go index 25a122402752..4c0347b20a13 100644 --- a/pkg/agent/run.go +++ b/pkg/agent/run.go @@ -93,7 +93,7 @@ func run(ctx context.Context, cfg cmds.Agent, proxy proxy.Proxy) error { // dualStack or IPv6 are not supported on Windows node if (goruntime.GOOS == "windows") && enableIPv6 { - return fmt.Errorf("dual-stack or IPv6 are not supported on Windows node") + return errors.New("dual-stack or IPv6 are not supported on Windows node") } conntrackConfig, err := getConntrackConfig(nodeConfig) @@ -180,9 +180,8 @@ func startCRI(ctx context.Context, nodeConfig *daemonconfig.Node) error { return err } return executor.Containerd(ctx, nodeConfig) - } else { - return executor.CRI(ctx, nodeConfig) } + return executor.CRI(ctx, nodeConfig) } // startNetwork updates the network annotations on the node and starts the CNI @@ -226,11 +225,11 @@ func getConntrackConfig(nodeConfig *daemonconfig.Node) (*kubeproxyconfig.KubePro return nil, err } ctConfig.MaxPerCore = &maxPerCore - min, err := cmd.Flags().GetInt32("conntrack-min") + ctMin, err := cmd.Flags().GetInt32("conntrack-min") if err != nil { return nil, err } - ctConfig.Min = &min + ctConfig.Min = &ctMin establishedTimeout, err := cmd.Flags().GetDuration("conntrack-tcp-timeout-established") if err != nil { return nil, err diff --git a/pkg/agent/run_linux.go b/pkg/agent/run_linux.go index 32aa9dd92c52..5858cecd74c9 100644 --- a/pkg/agent/run_linux.go +++ b/pkg/agent/run_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package agent diff --git a/pkg/agent/run_windows.go b/pkg/agent/run_windows.go index e2ff62298394..686b76857239 100644 --- a/pkg/agent/run_windows.go +++ b/pkg/agent/run_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package agent diff --git a/pkg/agent/templates/templates.go b/pkg/agent/templates/templates.go index 78260fb895d4..aadf6c0112eb 100644 --- a/pkg/agent/templates/templates.go +++ b/pkg/agent/templates/templates.go @@ -326,7 +326,7 @@ skip_verify = true {{ end -}} ` -func ParseTemplateFromConfig(userTemplate, baseTemplate string, config interface{}) (string, error) { +func ParseTemplateFromConfig(userTemplate, baseTemplate string, config any) (string, error) { out := new(bytes.Buffer) t := template.Must(template.New("compiled_template").Funcs(templateFuncs).Parse(userTemplate)) template.Must(t.New("base").Parse(baseTemplate)) @@ -336,7 +336,7 @@ func ParseTemplateFromConfig(userTemplate, baseTemplate string, config interface return trimEmpty(out) } -func ParseHostsTemplateFromConfig(userTemplate string, config interface{}) (string, error) { +func ParseHostsTemplateFromConfig(userTemplate string, config any) (string, error) { out := new(bytes.Buffer) t := template.Must(template.New("compiled_template").Funcs(templateFuncs).Parse(userTemplate)) if err := t.Execute(out, config); err != nil { diff --git a/pkg/agent/templates/templates_linux.go b/pkg/agent/templates/templates_linux.go index 912d12d7023a..bf302be6f5e4 100644 --- a/pkg/agent/templates/templates_linux.go +++ b/pkg/agent/templates/templates_linux.go @@ -12,7 +12,7 @@ var templateFuncs = template.FuncMap{ "deschemify": func(s string) string { return s }, - "toJson": func(v interface{}) string { + "toJson": func(v any) string { output, _ := json.Marshal(v) return string(output) }, diff --git a/pkg/agent/templates/templates_windows.go b/pkg/agent/templates/templates_windows.go index d3338a983add..300df300e3e6 100644 --- a/pkg/agent/templates/templates_windows.go +++ b/pkg/agent/templates/templates_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package templates @@ -22,7 +21,7 @@ var templateFuncs = template.FuncMap{ } return s }, - "toJson": func(v interface{}) string { + "toJson": func(v any) string { output, _ := json.Marshal(v) return string(output) }, diff --git a/pkg/authenticator/passwordfile/passwordfile_test.go b/pkg/authenticator/passwordfile/passwordfile_test.go index ff65da69c1a7..633c1c2d52a3 100644 --- a/pkg/authenticator/passwordfile/passwordfile_test.go +++ b/pkg/authenticator/passwordfile/passwordfile_test.go @@ -134,13 +134,13 @@ password2,user2,uid2 password3,user3 password4 `); err == nil { - t.Fatalf("unexpected non error") + t.Fatal("unexpected non error") } } func Test_UnitInsufficientColumnsPasswordFile(t *testing.T) { if _, err := newWithContents(t, "password4\n"); err == nil { - t.Fatalf("unexpected non error") + t.Fatal("unexpected non error") } } diff --git a/pkg/bootstrap/bootstrap.go b/pkg/bootstrap/bootstrap.go index 756e0df80d3e..40b2a95dc28b 100644 --- a/pkg/bootstrap/bootstrap.go +++ b/pkg/bootstrap/bootstrap.go @@ -84,7 +84,7 @@ func WriteToDiskFromStorage(files PathsDataformat, bootstrap *config.ControlRunt return nil } -func ObjToMap(obj interface{}) (map[string]string, error) { +func ObjToMap(obj any) (map[string]string, error) { bytes, err := json.Marshal(obj) if err != nil { return nil, err diff --git a/pkg/bootstrap/bootstrap_test.go b/pkg/bootstrap/bootstrap_test.go index 96c66aee0179..ca0245ce6c03 100644 --- a/pkg/bootstrap/bootstrap_test.go +++ b/pkg/bootstrap/bootstrap_test.go @@ -8,7 +8,7 @@ import ( func TestObjToMap(t *testing.T) { type args struct { - obj interface{} + obj any } tests := []struct { name string diff --git a/pkg/certmonitor/certmonitor.go b/pkg/certmonitor/certmonitor.go index 38b97edbf223..63b82b3e4e60 100644 --- a/pkg/certmonitor/certmonitor.go +++ b/pkg/certmonitor/certmonitor.go @@ -107,7 +107,6 @@ func Setup(ctx context.Context, nodeConfig *daemonconfig.Node, dataDir string) e recorder.Event(nodeRef, corev1.EventTypeNormal, "CertificateExpirationOK", message) } }) - }, certCheckInterval, ctx.Done()) return nil diff --git a/pkg/cgroups/cgroups_linux.go b/pkg/cgroups/cgroups_linux.go index 5b2f684b6584..7e582f6175c2 100644 --- a/pkg/cgroups/cgroups_linux.go +++ b/pkg/cgroups/cgroups_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package cgroups @@ -83,11 +82,11 @@ func CheckCgroups() (kubeletRoot, runtimeRoot string, controllers map[string]boo if cgroupsModeV2 { m, err := cgroupsv2.NewManager("/sys/fs/cgroup", "/", &cgroupsv2.Resources{}) if err != nil { - return + return kubeletRoot, runtimeRoot, controllers } enabledControllers, err := m.Controllers() if err != nil { - return + return kubeletRoot, runtimeRoot, controllers } // Intentionally using an expressionless switch to match the logic below for _, controller := range enabledControllers { @@ -97,7 +96,7 @@ func CheckCgroups() (kubeletRoot, runtimeRoot string, controllers map[string]boo f, err := os.Open("/proc/self/cgroup") if err != nil { - return + return kubeletRoot, runtimeRoot, controllers } defer f.Close() @@ -151,7 +150,7 @@ func CheckCgroups() (kubeletRoot, runtimeRoot string, controllers map[string]boo // a host PID scenario but we don't support this. g, err := os.Open("/proc/1/cgroup") if err != nil { - return + return kubeletRoot, runtimeRoot, controllers } defer g.Close() scan = bufio.NewScanner(g) @@ -164,8 +163,7 @@ func CheckCgroups() (kubeletRoot, runtimeRoot string, controllers map[string]boo // For v1 or hybrid, controller can be a single value {"blkio"}, or a comounted set {"cpu","cpuacct"} // For v2, controllers = {""} (only contains a single empty string) for _, controller := range controllers { - switch { - case controller == "name=systemd" || cgroupsModeV2: + if controller == "name=systemd" || cgroupsModeV2 { last := parts[len(parts)-1] if last != "/" && last != "/init.scope" { kubeletRoot = "/" + version.Program @@ -175,5 +173,5 @@ func CheckCgroups() (kubeletRoot, runtimeRoot string, controllers map[string]boo } } } - return + return kubeletRoot, runtimeRoot, controllers } diff --git a/pkg/cgroups/cgroups_windows.go b/pkg/cgroups/cgroups_windows.go index b38ba9fb6a3a..154dd7ef662d 100644 --- a/pkg/cgroups/cgroups_windows.go +++ b/pkg/cgroups/cgroups_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package cgroups @@ -8,5 +7,5 @@ func Validate() error { } func CheckCgroups() (kubeletRoot, runtimeRoot string, controllers map[string]bool) { - return + return kubeletRoot, runtimeRoot, controllers } diff --git a/pkg/cli/agent/agent.go b/pkg/cli/agent/agent.go index d88a82d041e0..7fd2ef06a3a5 100644 --- a/pkg/cli/agent/agent.go +++ b/pkg/cli/agent/agent.go @@ -3,7 +3,7 @@ package agent import ( "context" "crypto/tls" - "fmt" + "errors" "os" "path/filepath" "sync" @@ -82,11 +82,11 @@ func Run(clx *cli.Context) (rerr error) { _, err := tls.LoadX509KeyPair(clientKubeletCert, clientKubeletKey) if err != nil && cmds.AgentConfig.Token == "" { - return fmt.Errorf("--token is required") + return errors.New("--token is required") } if cmds.AgentConfig.ServerURL == "" { - return fmt.Errorf("--server is required") + return errors.New("--server is required") } if cmds.AgentConfig.FlannelIface != "" && len(cmds.AgentConfig.NodeIP.Value()) == 0 { @@ -145,9 +145,5 @@ func Run(clx *cli.Context) (rerr error) { return https.Start(ctx, nodeConfig, nil) } - if err := agent.Run(ctx, wg, cfg); err != nil { - return err - } - - return nil + return agent.Run(ctx, wg, cfg) } diff --git a/pkg/cli/cert/cert.go b/pkg/cli/cert/cert.go index d353bc93dcbe..8e2a840ce5a0 100644 --- a/pkg/cli/cert/cert.go +++ b/pkg/cli/cert/cert.go @@ -51,12 +51,12 @@ type CertificateInfo struct { } // collectCertInfo collects information about certificates -func collectCertInfo(controlConfig config.Control, ServicesList []string) (*CertificateInfo, error) { +func collectCertInfo(controlConfig config.Control, servicesList []string) (*CertificateInfo, error) { result := &CertificateInfo{} now := time.Now() warn := now.Add(time.Hour * 24 * config.CertificateRenewDays) - fileMap, err := services.FilesForServices(controlConfig, ServicesList) + fileMap, err := services.FilesForServices(controlConfig, servicesList) if err != nil { return nil, err } @@ -70,7 +70,6 @@ func collectCertInfo(controlConfig config.Control, ServicesList []string) (*Cert } for _, cert := range certs { - expiration := cert.NotAfter status := k3sutil.GetCertStatus(cert, now, warn) if status == k3sutil.CertStatusNotYetValid { @@ -93,8 +92,8 @@ func collectCertInfo(controlConfig config.Control, ServicesList []string) (*Cert return result, nil } -// CertFormatter defines the interface for formatting certificate information -type CertFormatter interface { +// Formatter defines the interface for formatting certificate information +type Formatter interface { Format(*CertificateInfo) error } @@ -134,8 +133,8 @@ func (f *TableFormatter) Format(certInfo *CertificateInfo) error { now := certInfo.ReferenceTime defer w.Flush() - fmt.Fprintf(w, "\nFILENAME\tSUBJECT\tUSAGES\tEXPIRES\tRESIDUAL TIME\tSTATUS\n") - fmt.Fprintf(w, "--------\t-------\t------\t-------\t-------------\t------\n") + fmt.Fprint(w, "\nFILENAME\tSUBJECT\tUSAGES\tEXPIRES\tRESIDUAL TIME\tSTATUS\n") + fmt.Fprint(w, "--------\t-------\t------\t-------\t-------------\t------\n") for _, cert := range certInfo.Certificates { fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%s\n", @@ -233,7 +232,7 @@ func check(app *cli.Context, cfg *cmds.Server) error { } outFmt := app.String("output") - var formatter CertFormatter + var formatter Formatter switch outFmt { case "text": formatter = &TextFormatter{Writer: os.Stdout} diff --git a/pkg/cli/cmds/const_windows.go b/pkg/cli/cmds/const_windows.go index 2d05392cdd42..dffdd63e80c5 100644 --- a/pkg/cli/cmds/const_windows.go +++ b/pkg/cli/cmds/const_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package cmds diff --git a/pkg/cli/cmds/etcd_snapshot.go b/pkg/cli/cmds/etcd_snapshot.go index bd9176e19db7..57a4b4aa6786 100644 --- a/pkg/cli/cmds/etcd_snapshot.go +++ b/pkg/cli/cmds/etcd_snapshot.go @@ -164,7 +164,7 @@ var EtcdSnapshotFlags = []cli.Flag{ }, } -func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) error) *cli.Command { +func NewEtcdSnapshotCommands(deleteFunc, listFunc, pruneFunc, saveFunc func(ctx *cli.Context) error) *cli.Command { return &cli.Command{ Name: EtcdSnapshotCommand, Usage: "Manage etcd snapshots", @@ -174,14 +174,14 @@ func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) er Name: "save", Usage: "Trigger an immediate etcd snapshot", SkipFlagParsing: false, - Action: save, + Action: saveFunc, Flags: EtcdSnapshotFlags, }, { Name: "delete", Usage: "Delete given snapshot(s)", SkipFlagParsing: false, - Action: delete, + Action: deleteFunc, Flags: EtcdSnapshotFlags, }, { @@ -189,7 +189,7 @@ func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) er Aliases: []string{"list", "l"}, Usage: "List snapshots", SkipFlagParsing: false, - Action: list, + Action: listFunc, Flags: append(EtcdSnapshotFlags, &cli.StringFlag{ Name: "output", Aliases: []string{"o"}, @@ -201,7 +201,7 @@ func NewEtcdSnapshotCommands(delete, list, prune, save func(ctx *cli.Context) er Name: "prune", Usage: "Remove snapshots that match the name prefix that exceed the configured retention count", SkipFlagParsing: false, - Action: prune, + Action: pruneFunc, Flags: EtcdSnapshotFlags, }, }, diff --git a/pkg/cli/cmds/init_default.go b/pkg/cli/cmds/init_default.go index 283e18b960e0..3e793079d9ff 100644 --- a/pkg/cli/cmds/init_default.go +++ b/pkg/cli/cmds/init_default.go @@ -1,5 +1,4 @@ //go:build !linux || !cgo -// +build !linux !cgo package cmds diff --git a/pkg/cli/cmds/log_default.go b/pkg/cli/cmds/log_default.go index bafcda915699..abe58425bc21 100644 --- a/pkg/cli/cmds/log_default.go +++ b/pkg/cli/cmds/log_default.go @@ -1,5 +1,4 @@ //go:build !linux || !cgo -// +build !linux !cgo package cmds diff --git a/pkg/cli/cmds/log_linux.go b/pkg/cli/cmds/log_linux.go index 8a6bcb027b84..cd742b729f50 100644 --- a/pkg/cli/cmds/log_linux.go +++ b/pkg/cli/cmds/log_linux.go @@ -1,5 +1,4 @@ //go:build linux && cgo -// +build linux,cgo package cmds @@ -78,6 +77,8 @@ func forkIfLoggingOrReaping() error { systemd.SdNotify(true, "READY=1\n") cmd.Wait() + + //revive:disable-next-line:deep-exit os.Exit(cmd.ProcessState.ExitCode()) } return nil diff --git a/pkg/cli/cmds/nostage.go b/pkg/cli/cmds/nostage.go index bb9f1b9f0884..d6899e86f703 100644 --- a/pkg/cli/cmds/nostage.go +++ b/pkg/cli/cmds/nostage.go @@ -1,5 +1,4 @@ //go:build no_stage -// +build no_stage package cmds diff --git a/pkg/cli/cmds/token.go b/pkg/cli/cmds/token.go index a0ace8e6338a..6b57257c21d6 100644 --- a/pkg/cli/cmds/token.go +++ b/pkg/cli/cmds/token.go @@ -35,7 +35,7 @@ var ( } ) -func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Context) error) *cli.Command { +func NewTokenCommands(createFunc, deleteFunc, generateFunc, listFunc, rotateFunc func(ctx *cli.Context) error) *cli.Command { return &cli.Command{ Name: TokenCommand, Usage: "Manage tokens", @@ -63,21 +63,21 @@ func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Conte Destination: &TokenConfig.Usages, }), SkipFlagParsing: false, - Action: create, + Action: createFunc, }, { Name: "delete", Usage: "Delete bootstrap tokens on the server", Flags: TokenFlags, SkipFlagParsing: false, - Action: delete, + Action: deleteFunc, }, { Name: "generate", Usage: "Generate and print a bootstrap token, but do not create it on the server", Flags: TokenFlags, SkipFlagParsing: false, - Action: generate, + Action: generateFunc, }, { Name: "list", @@ -89,7 +89,7 @@ func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Conte Destination: &TokenConfig.Output, }), SkipFlagParsing: false, - Action: list, + Action: listFunc, }, { Name: "rotate", @@ -116,7 +116,7 @@ func NewTokenCommands(create, delete, generate, list, rotate func(ctx *cli.Conte Destination: &TokenConfig.NewToken, }), SkipFlagParsing: false, - Action: rotate, + Action: rotateFunc, }, }, } diff --git a/pkg/cli/etcdsnapshot/etcd_snapshot.go b/pkg/cli/etcdsnapshot/etcd_snapshot.go index 1f20a06f23d8..2bcca5923674 100644 --- a/pkg/cli/etcdsnapshot/etcd_snapshot.go +++ b/pkg/cli/etcdsnapshot/etcd_snapshot.go @@ -147,10 +147,10 @@ func Delete(app *cli.Context) error { if err := cmds.InitLogging(); err != nil { return err } - return delete(app, &cmds.ServerConfig) + return deleteSnapshot(app, &cmds.ServerConfig) } -func delete(app *cli.Context, cfg *cmds.Server) error { +func deleteSnapshot(app *cli.Context, cfg *cmds.Server) error { snapshots := app.Args() if snapshots.Len() == 0 { return errors.New("no snapshots given for removal") diff --git a/pkg/cli/secretsencrypt/secrets_encrypt.go b/pkg/cli/secretsencrypt/secrets_encrypt.go index d3b611cfec60..bdc2a96ec66a 100644 --- a/pkg/cli/secretsencrypt/secrets_encrypt.go +++ b/pkg/cli/secretsencrypt/secrets_encrypt.go @@ -132,9 +132,9 @@ func Status(app *cli.Context) error { var tabBuffer bytes.Buffer w := tabwriter.NewWriter(&tabBuffer, 0, 0, 2, ' ', 0) - fmt.Fprintf(w, "\n") - fmt.Fprintf(w, "Active\tKey Type\tName\n") - fmt.Fprintf(w, "------\t--------\t----\n") + fmt.Fprint(w, "\n") + fmt.Fprint(w, "Active\tKey Type\tName\n") + fmt.Fprint(w, "------\t--------\t----\n") if status.ActiveKey != "" { ak := strings.Split(status.ActiveKey, " ") fmt.Fprintf(w, " *\t%s\t%s\n", ak[0], ak[1]) diff --git a/pkg/cli/server/server.go b/pkg/cli/server/server.go index b61f23c6642b..edb3de0f8d94 100644 --- a/pkg/cli/server/server.go +++ b/pkg/cli/server/server.go @@ -38,6 +38,7 @@ import ( "github.com/urfave/cli/v2" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" utilnet "k8s.io/apimachinery/pkg/util/net" + "k8s.io/apimachinery/pkg/util/wait" kubeapiserverflag "k8s.io/component-base/cli/flag" "k8s.io/kubernetes/pkg/controlplane/apiserver/options" utilsnet "k8s.io/utils/net" @@ -296,7 +297,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont // if not set, try setting advertise-ip from agent VPN if cmds.AgentConfig.VPNAuth != "" { - vpnInfo, err := vpn.GetVPNInfo(cmds.AgentConfig.VPNAuth) + vpnInfo, err := vpn.GetInfo(cmds.AgentConfig.VPNAuth) if err != nil { return err } @@ -326,7 +327,6 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont } logrus.Warn("Etcd IP (PrivateIP) remains the local IP. Running etcd traffic over VPN is not recommended due to performance issues") } else { - // if not set, try setting advertise-ip from agent node-external-ip if serverConfig.ControlConfig.AdvertiseIP == "" && len(cmds.AgentConfig.NodeExternalIP.Value()) != 0 { serverConfig.ControlConfig.AdvertiseIP = util.GetFirstValidIPString(cmds.AgentConfig.NodeExternalIP.Value()) @@ -340,7 +340,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont // if we ended up with any advertise-ips, ensure they're added to the SAN list; // note that kube-apiserver does not support dual-stack advertise-ip as of 1.21.0: - /// https://github.com/kubernetes/kubeadm/issues/1612#issuecomment-772583989 + // https://github.com/kubernetes/kubeadm/issues/1612#issuecomment-772583989 if serverConfig.ControlConfig.AdvertiseIP != "" { serverConfig.ControlConfig.SANs = append(serverConfig.ControlConfig.SANs, serverConfig.ControlConfig.AdvertiseIP) } @@ -567,7 +567,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont // initialize the apiAddress Channel for receiving the api address from etcd agentConfig.APIAddressCh = make(chan []string) - go getAPIAddressFromEtcd(ctx, serverConfig, agentConfig) + go pollAPIAddressFromEtcd(ctx, serverConfig, agentConfig) } // Until the agent is run and retrieves config from the server, we won't know @@ -626,11 +626,7 @@ func run(app *cli.Context, cfg *cmds.Server, leaderControllers server.CustomCont systemd.SdNotify(true, "READY=1\n") }() - if err := server.StartServer(ctx, wg, &serverConfig, cfg); err != nil { - return err - } - - return nil + return server.StartServer(ctx, wg, &serverConfig, cfg) } // validateNetworkConfig ensures that the network configuration values make sense. @@ -648,23 +644,20 @@ func validateNetworkConfiguration(serverConfig server.Config) error { return nil } -func getAPIAddressFromEtcd(ctx context.Context, serverConfig server.Config, agentConfig cmds.Agent) { +func pollAPIAddressFromEtcd(ctx context.Context, serverConfig server.Config, agentConfig cmds.Agent) { defer close(agentConfig.APIAddressCh) - for { - toCtx, cancel := context.WithTimeout(ctx, 5*time.Second) + pollDuration := time.Second * 5 + wait.PollUntilContextCancel(ctx, pollDuration, true, func(ctx context.Context) (bool, error) { + ctx, cancel := context.WithTimeout(ctx, pollDuration) defer cancel() - serverAddresses, err := etcd.GetAPIServerURLsFromETCD(toCtx, &serverConfig.ControlConfig) + serverAddresses, err := etcd.GetAPIServerURLsFromETCD(ctx, &serverConfig.ControlConfig) if err == nil && len(serverAddresses) > 0 { agentConfig.APIAddressCh <- serverAddresses - return + return true, nil } if !errors.Is(err, etcd.ErrAddressNotSet) { logrus.Warnf("Failed to get apiserver address from etcd: %v", err) } - select { - case <-toCtx.Done(): - case <-ctx.Done(): - return - } - } + return false, nil + }) } diff --git a/pkg/cli/token/token.go b/pkg/cli/token/token.go index 8957a93a928d..4be197b537b3 100644 --- a/pkg/cli/token/token.go +++ b/pkg/cli/token/token.go @@ -97,10 +97,10 @@ func Delete(app *cli.Context) error { if err := cmds.InitLogging(); err != nil { return err } - return delete(app, &cmds.TokenConfig) + return deleteToken(app, &cmds.TokenConfig) } -func delete(app *cli.Context, cfg *cmds.Token) error { +func deleteToken(app *cli.Context, cfg *cmds.Token) error { args := app.Args() if args.Len() < 1 { return errors.New("missing argument; 'token delete' is missing token") diff --git a/pkg/clientaccess/token_linux_test.go b/pkg/clientaccess/token_linux_test.go index 9334e89bb16a..cc4ff0e2d294 100644 --- a/pkg/clientaccess/token_linux_test.go +++ b/pkg/clientaccess/token_linux_test.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package clientaccess @@ -42,7 +41,7 @@ func Test_UnitTrustedCA(t *testing.T) { // as it is cached for the duration of the process lifetime. // Ref: https://github.com/golang/go/issues/41888 path := t.TempDir() + "/ca.crt" - writeServerCA(server, path) + _ = writeServerCA(server, path) os.Setenv("SSL_CERT_FILE", path) for _, testCase := range testCases { diff --git a/pkg/clientaccess/token_test.go b/pkg/clientaccess/token_test.go index fd392223df1b..7fd84ab86591 100644 --- a/pkg/clientaccess/token_test.go +++ b/pkg/clientaccess/token_test.go @@ -296,7 +296,7 @@ func newTLSServer(t *testing.T, username, password string, sendWrongCA bool) *ht var server *httptest.Server server = httptest.NewUnstartedServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/v1-k3s/server-bootstrap" { - if authUsername, authPassword, ok := r.BasicAuth(); ok != true || authPassword != password || authUsername != username { + if authUsername, authPassword, ok := r.BasicAuth(); !ok || authPassword != password || authUsername != username { http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) return } diff --git a/pkg/cloudprovider/cloudprovider.go b/pkg/cloudprovider/cloudprovider.go index 5900b9ac8544..54ec3134bd92 100644 --- a/pkg/cloudprovider/cloudprovider.go +++ b/pkg/cloudprovider/cloudprovider.go @@ -2,7 +2,7 @@ package cloudprovider import ( "encoding/json" - "fmt" + "errors" "io" "github.com/k3s-io/k3s/pkg/util" @@ -74,7 +74,7 @@ func init() { } if !k.LBEnabled && !k.NodeEnabled { - return nil, fmt.Errorf("all cloud-provider functionality disabled by config") + return nil, errors.New("all cloud-provider functionality disabled by config") } return &k, err diff --git a/pkg/cloudprovider/servicelb.go b/pkg/cloudprovider/servicelb.go index cd574eacbbb2..18a5d96f6100 100644 --- a/pkg/cloudprovider/servicelb.go +++ b/pkg/cloudprovider/servicelb.go @@ -3,6 +3,7 @@ package cloudprovider import ( "context" "encoding/json" + "errors" "fmt" "sort" "strconv" @@ -201,7 +202,7 @@ func (k *k3s) processNextWorkItem() bool { // processSingleItem processes a single item from the work queue, // requeueing it if the handler fails. -func (k *k3s) processSingleItem(obj interface{}) error { +func (k *k3s) processSingleItem(obj any) error { var ( key string ok bool @@ -222,7 +223,6 @@ func (k *k3s) processSingleItem(obj interface{}) error { k.workqueue.Forget(obj) return nil - } // updateServiceStatus updates the load balancer status for the matching service, if it exists and is a @@ -735,11 +735,11 @@ func validateToleration(toleration *core.Toleration) error { } if toleration.Key == "" && toleration.Operator != core.TolerationOpExists { - return fmt.Errorf("toleration with empty key must have operator 'Exists'") + return errors.New("toleration with empty key must have operator 'Exists'") } if toleration.Operator == core.TolerationOpExists && toleration.Value != "" { - return fmt.Errorf("toleration with operator 'Exists' must have an empty value") + return errors.New("toleration with operator 'Exists' must have an empty value") } return nil diff --git a/pkg/cluster/bootstrap.go b/pkg/cluster/bootstrap.go index b20837fd3dfb..7b55276afb27 100644 --- a/pkg/cluster/bootstrap.go +++ b/pkg/cluster/bootstrap.go @@ -29,6 +29,7 @@ import ( "github.com/otiai10/copy" pkgerrors "github.com/pkg/errors" "github.com/sirupsen/logrus" + "k8s.io/apimachinery/pkg/util/wait" ) // Bootstrap attempts to load a managed database driver, if one has been initialized or should be created/joined. @@ -114,26 +115,26 @@ func (c *Cluster) shouldBootstrapLoad(ctx context.Context) (bool, bool, error) { // Not initialized, not joining - must be initializing (cluster-init) logrus.Infof("Managed %s cluster initializing", c.managedDB.EndpointName()) return false, false, nil - } else { - // Not initialized, but have a Join URL - fail if there's no token; if there is then validate it. - // Note that this is the path taken by control-plane-only nodes every startup, as they have a non-nil managedDB that is never initialized. - if c.config.Token == "" { - return false, false, errors.New("token is required to join a cluster") - } + } - // Fail if the token isn't syntactically valid, or if the CA hash on the remote server doesn't match - // the hash in the token. The password isn't actually checked until later when actually bootstrapping. - info, err := clientaccess.ParseAndValidateToken(c.config.JoinURL, c.config.Token, opts...) - if err != nil { - return false, false, pkgerrors.WithMessage(err, "failed to validate token") - } - c.clientAccessInfo = info + // Not initialized, but have a Join URL - fail if there's no token; if there is then validate it. + // Note that this is the path taken by control-plane-only nodes every startup, as they have a non-nil managedDB that is never initialized. + if c.config.Token == "" { + return false, false, errors.New("token is required to join a cluster") + } - if c.config.DisableETCD { - logrus.Infof("Managed %s disabled on this node", c.managedDB.EndpointName()) - } else { - logrus.Infof("Managed %s cluster not yet initialized", c.managedDB.EndpointName()) - } + // Fail if the token isn't syntactically valid, or if the CA hash on the remote server doesn't match + // the hash in the token. The password isn't actually checked until later when actually bootstrapping. + info, err := clientaccess.ParseAndValidateToken(c.config.JoinURL, c.config.Token, opts...) + if err != nil { + return false, false, pkgerrors.WithMessage(err, "failed to validate token") + } + c.clientAccessInfo = info + + if c.config.DisableETCD { + logrus.Infof("Managed %s disabled on this node", c.managedDB.EndpointName()) + } else { + logrus.Infof("Managed %s cluster not yet initialized", c.managedDB.EndpointName()) } } @@ -563,19 +564,15 @@ func (c *Cluster) reconcileEtcd(ctx context.Context) error { return err } - for { - if err := e.Test(reconcileCtx, true); err != nil && !errors.Is(err, etcd.ErrNotMember) { + if err := wait.PollUntilContextCancel(reconcileCtx, time.Second*5, true, func(ctx context.Context) (bool, error) { + if err := e.Test(ctx, true); err != nil && !errors.Is(err, etcd.ErrNotMember) { logrus.Infof("Failed to test temporary data store connection: %v", err) - } else { - logrus.Info(e.EndpointName() + " temporary data store connection OK") - break - } - - select { - case <-time.After(5 * time.Second): - case <-reconcileCtx.Done(): - break + return false, nil } + logrus.Info(e.EndpointName() + " temporary data store connection OK") + return true, nil + }); err != nil { + return err } data, err := c.readBootstrapFromDisk() diff --git a/pkg/cluster/encrypt.go b/pkg/cluster/encrypt.go index b39fdc151370..75ed6f26392d 100644 --- a/pkg/cluster/encrypt.go +++ b/pkg/cluster/encrypt.go @@ -6,7 +6,7 @@ import ( "crypto/rand" "crypto/sha1" "encoding/base64" - "fmt" + "errors" "io" "strings" @@ -54,7 +54,7 @@ func encrypt(passphrase string, plaintext []byte) ([]byte, error) { func decrypt(passphrase string, ciphertext []byte) ([]byte, error) { parts := strings.SplitN(string(ciphertext), ":", 2) if len(parts) != 2 { - return nil, fmt.Errorf("invalid cipher text, not : delimited") + return nil, errors.New("invalid cipher text, not : delimited") } clearKey := pbkdf2.Key([]byte(passphrase), []byte(parts[0]), 4096, 32, sha1.New) diff --git a/pkg/cluster/https.go b/pkg/cluster/https.go index df5446b98a75..332a2e8b0666 100644 --- a/pkg/cluster/https.go +++ b/pkg/cluster/https.go @@ -4,7 +4,6 @@ import ( "context" "crypto/tls" "errors" - "fmt" "io" "log" "net" @@ -105,7 +104,7 @@ func (c *Cluster) initClusterAndHTTPS(ctx context.Context) error { if c.config.Runtime.Handler != nil { c.config.Runtime.Handler.ServeHTTP(rw, req) } else { - util.SendError(fmt.Errorf("starting"), rw, req, http.StatusServiceUnavailable) + util.SendError(errors.New("starting"), rw, req, http.StatusServiceUnavailable) } }) diff --git a/pkg/cluster/storage.go b/pkg/cluster/storage.go index da0c77692a33..8ffdc8264337 100644 --- a/pkg/cluster/storage.go +++ b/pkg/cluster/storage.go @@ -54,11 +54,7 @@ func RotateBootstrapToken(ctx context.Context, config *config.Control, oldToken return err } // reuse the existing migration function to reencrypt bootstrap data with new token - if err := migrateTokens(ctx, bootstrapList, storageClient, "", tokenKey, normalizedToken, normalizedOldToken); err != nil { - return err - } - - return nil + return migrateTokens(ctx, bootstrapList, storageClient, "", tokenKey, normalizedToken, normalizedOldToken) } // Save writes the current ControlRuntimeBootstrap data to the datastore. This contains a complete diff --git a/pkg/configfilearg/parser.go b/pkg/configfilearg/parser.go index 6d86f2c0c71e..a1a4b5d61edc 100644 --- a/pkg/configfilearg/parser.go +++ b/pkg/configfilearg/parser.go @@ -75,7 +75,7 @@ func (p *Parser) stripInvalidFlags(command string, args []string) ([]string, err } validFlags := make(map[string]bool, len(cmdFlags)) for _, f := range cmdFlags { - //split flags with aliases into 2 entries + // split flags with aliases into 2 entries for _, s := range f.Names() { validFlags[s] = true } @@ -237,7 +237,7 @@ func dotDFiles(basefile string) (result []string, _ error) { } result = append(result, filepath.Join(basefile+".d", file.Name())) } - return + return result, nil } // readConfigFile returns a flattened arg list generated from the specified config @@ -263,7 +263,7 @@ func readConfigFile(file string) (result []string, _ error) { var ( keySeen = map[string]bool{} keyOrder []string - values = map[string]interface{}{} + values = map[string]any{} ) for _, file := range files { bytes, err := readConfigFileData(file) @@ -302,7 +302,7 @@ func readConfigFile(file string) (result []string, _ error) { prefix = "-" } - if slice, ok := v.([]interface{}); ok { + if slice, ok := v.([]any); ok { for _, v := range slice { result = append(result, prefix+k+"="+convert.ToString(v)) } @@ -312,21 +312,21 @@ func readConfigFile(file string) (result []string, _ error) { } } - return + return result, nil } -func toSlice(v interface{}) []interface{} { +func toSlice(v any) []any { switch k := v.(type) { case string: - return []interface{}{k} - case []interface{}: + return []any{k} + case []any: return k default: str := strings.TrimSpace(convert.ToString(v)) if str == "" { return nil } - return []interface{}{str} + return []any{str} } } diff --git a/pkg/containerd/builtins.go b/pkg/containerd/builtins.go index bbad23a0aa84..24d83f3b448e 100644 --- a/pkg/containerd/builtins.go +++ b/pkg/containerd/builtins.go @@ -1,5 +1,4 @@ //go:build ctrd -// +build ctrd /* Copyright The containerd Authors. diff --git a/pkg/containerd/builtins_cri.go b/pkg/containerd/builtins_cri.go index 1bbe3bf74c38..a28e4ba25553 100644 --- a/pkg/containerd/builtins_cri.go +++ b/pkg/containerd/builtins_cri.go @@ -1,5 +1,4 @@ //go:build ctrd -// +build ctrd /* Copyright The containerd Authors. diff --git a/pkg/containerd/builtins_linux.go b/pkg/containerd/builtins_linux.go index ff31fa41e1d2..c238899a884a 100644 --- a/pkg/containerd/builtins_linux.go +++ b/pkg/containerd/builtins_linux.go @@ -1,5 +1,4 @@ //go:build ctrd -// +build ctrd /* Copyright The containerd Authors. diff --git a/pkg/containerd/builtins_windows.go b/pkg/containerd/builtins_windows.go index 401993f216a5..c2a2947f375a 100644 --- a/pkg/containerd/builtins_windows.go +++ b/pkg/containerd/builtins_windows.go @@ -1,5 +1,4 @@ //go:build ctrd -// +build ctrd /* Copyright The containerd Authors. diff --git a/pkg/containerd/main.go b/pkg/containerd/main.go index eff2e865c73d..762ec98ee4df 100644 --- a/pkg/containerd/main.go +++ b/pkg/containerd/main.go @@ -1,5 +1,4 @@ //go:build ctrd -// +build ctrd package containerd diff --git a/pkg/containerd/utility_windows.go b/pkg/containerd/utility_windows.go index ecb741b98fa8..3c26e2295a00 100644 --- a/pkg/containerd/utility_windows.go +++ b/pkg/containerd/utility_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package containerd diff --git a/pkg/daemons/agent/agent.go b/pkg/daemons/agent/agent.go index c905e8cfc0f0..88aed28f2112 100644 --- a/pkg/daemons/agent/agent.go +++ b/pkg/daemons/agent/agent.go @@ -22,7 +22,6 @@ import ( "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/component-base/logs" - logsapi "k8s.io/component-base/logs/api/v1" logsv1 "k8s.io/component-base/logs/api/v1" _ "k8s.io/component-base/metrics/prometheus/restclient" // for client metric registration _ "k8s.io/component-base/metrics/prometheus/version" // for version metric registration @@ -34,7 +33,7 @@ import ( ) func Agent(ctx context.Context, nodeConfig *daemonconfig.Node, proxy proxy.Proxy) error { - logsapi.ReapplyHandling = logsapi.ReapplyHandlingIgnoreUnchanged + logsv1.ReapplyHandling = logsv1.ReapplyHandlingIgnoreUnchanged logs.InitLogs() defer logs.FlushLogs() @@ -252,12 +251,12 @@ func defaultKubeletConfig(cfg *daemonconfig.Agent) (*kubeletconfig.KubeletConfig return nil, pkgerrors.WithMessagef(err, "failed to create static pod manifest dir %s", defaultConfig.StaticPodPath) } - if t, _, err := taints.ParseTaints(cfg.NodeTaints); err != nil { + t, _, err := taints.ParseTaints(cfg.NodeTaints) + if err != nil { return nil, pkgerrors.WithMessage(err, "failed to parse node taints") - } else { - defaultConfig.RegisterWithTaints = t } + defaultConfig.RegisterWithTaints = t logsv1.VModuleConfigurationPflag(&defaultConfig.Logging.VModule).Set(cfg.VModule) return defaultConfig, nil diff --git a/pkg/daemons/agent/agent_linux.go b/pkg/daemons/agent/agent_linux.go index 560ae28ca882..0c6dadc75607 100644 --- a/pkg/daemons/agent/agent_linux.go +++ b/pkg/daemons/agent/agent_linux.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package agent diff --git a/pkg/daemons/agent/agent_windows.go b/pkg/daemons/agent/agent_windows.go index ec0f0d9f571c..ff2fa4856ca7 100644 --- a/pkg/daemons/agent/agent_windows.go +++ b/pkg/daemons/agent/agent_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package agent diff --git a/pkg/daemons/control/deps/deps.go b/pkg/daemons/control/deps/deps.go index 09c93cea384c..c96dfa0b9b66 100644 --- a/pkg/daemons/control/deps/deps.go +++ b/pkg/daemons/control/deps/deps.go @@ -538,15 +538,15 @@ type signedCertFactory = func(commonName string, organization []string, certFile func createServerSigningCertKey(config *config.Control) (bool, error) { runtime := config.Runtime - TokenCA := filepath.Join(config.DataDir, "tls", "token-ca.crt") - TokenCAKey := filepath.Join(config.DataDir, "tls", "token-ca.key") + tokenCA := filepath.Join(config.DataDir, "tls", "token-ca.crt") + tokenCAKey := filepath.Join(config.DataDir, "tls", "token-ca.key") - if exists(TokenCA, TokenCAKey) && !exists(runtime.ServerCA) && !exists(runtime.ServerCAKey) { + if exists(tokenCA, tokenCAKey) && !exists(runtime.ServerCA) && !exists(runtime.ServerCAKey) { logrus.Infof("Upgrading token-ca files to server-ca") - if err := os.Link(TokenCA, runtime.ServerCA); err != nil { + if err := os.Link(tokenCA, runtime.ServerCA); err != nil { return false, err } - if err := os.Link(TokenCAKey, runtime.ServerCAKey); err != nil { + if err := os.Link(tokenCAKey, runtime.ServerCAKey); err != nil { return false, err } return true, nil diff --git a/pkg/daemons/control/proxy/proxy.go b/pkg/daemons/control/proxy/proxy.go index ae6d3c7d5dc1..76665bed6ba6 100644 --- a/pkg/daemons/control/proxy/proxy.go +++ b/pkg/daemons/control/proxy/proxy.go @@ -53,5 +53,4 @@ func (p *proxy) pipe(src, dst io.ReadWriter) { return } } - } diff --git a/pkg/daemons/control/server.go b/pkg/daemons/control/server.go index 22f529a93390..41a482069175 100644 --- a/pkg/daemons/control/server.go +++ b/pkg/daemons/control/server.go @@ -311,12 +311,12 @@ func prepare(ctx context.Context, wg *sync.WaitGroup, config *config.Control) er return err } - if dataDir, err := filepath.Abs(config.DataDir); err != nil { + dataDir, err := filepath.Abs(config.DataDir) + if err != nil { return err - } else { - config.DataDir = dataDir } + config.DataDir = dataDir os.MkdirAll(filepath.Join(config.DataDir, "etc"), 0700) os.MkdirAll(filepath.Join(config.DataDir, "tls"), 0700) os.MkdirAll(filepath.Join(config.DataDir, "cred"), 0700) diff --git a/pkg/daemons/control/server_test.go b/pkg/daemons/control/server_test.go index 7bcb483ad8e8..4c248a0153ba 100644 --- a/pkg/daemons/control/server_test.go +++ b/pkg/daemons/control/server_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + //revive:disable:dot-imports . "github.com/onsi/gomega" "github.com/k3s-io/k3s/pkg/cli/cmds" diff --git a/pkg/daemons/control/tunnel.go b/pkg/daemons/control/tunnel.go index 1a4a959dc6d6..8cd111ff4e51 100644 --- a/pkg/daemons/control/tunnel.go +++ b/pkg/daemons/control/tunnel.go @@ -297,5 +297,5 @@ func (crw *connReadWriteCloser) Write(b []byte) (n int, err error) { func (crw *connReadWriteCloser) Close() (err error) { crw.once.Do(func() { err = crw.conn.Close() }) - return + return err } diff --git a/pkg/daemons/executor/executor.go b/pkg/daemons/executor/executor.go index 7d092e744d59..7b95dbf1b2cf 100644 --- a/pkg/daemons/executor/executor.go +++ b/pkg/daemons/executor/executor.go @@ -54,6 +54,7 @@ type ETCDSocketOpts struct { ReusePort bool `json:"reuse-port,omitempty"` } +//revive:disable:struct-tag type ETCDConfig struct { InitialOptions `json:",inline"` Name string `json:"name,omitempty"` @@ -105,7 +106,7 @@ func (e ETCDConfig) ToConfigFile(extraArgs []string) (string, error) { } if len(extraArgs) > 0 { - var s map[string]interface{} + var s map[string]any if err := yaml2.Unmarshal(bytes, &s); err != nil { return "", err } diff --git a/pkg/deploy/controller.go b/pkg/deploy/controller.go index b99da9930691..6dcbd4cce323 100644 --- a/pkg/deploy/controller.go +++ b/pkg/deploy/controller.go @@ -31,7 +31,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - yamlDecoder "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/apimachinery/pkg/util/yaml" "k8s.io/client-go/discovery" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/record" @@ -419,7 +419,7 @@ func isEmptyYaml(yaml []byte) bool { // yamlToObjects returns an object slice yielded from documents in a chunk of YAML func yamlToObjects(in io.Reader) ([]runtime.Object, error) { var result []runtime.Object - reader := yamlDecoder.NewYAMLReader(bufio.NewReaderSize(in, 4096)) + reader := yaml.NewYAMLReader(bufio.NewReaderSize(in, 4096)) for { raw, err := reader.Read() if err == io.EOF { @@ -444,7 +444,7 @@ func yamlToObjects(in io.Reader) ([]runtime.Object, error) { // Returns one or more objects from a single YAML document func toObjects(bytes []byte) ([]runtime.Object, error) { - bytes, err := yamlDecoder.ToJSON(bytes) + bytes, err := yaml.ToJSON(bytes) if err != nil { return nil, err } @@ -457,8 +457,8 @@ func toObjects(bytes []byte) ([]runtime.Object, error) { if l, ok := obj.(*unstructured.UnstructuredList); ok { var result []runtime.Object for _, obj := range l.Items { - copy := obj - result = append(result, ©) + newObj := obj + result = append(result, &newObj) } return result, nil } diff --git a/pkg/deploy/nostage.go b/pkg/deploy/nostage.go index 553d624c77f2..6542040b4bd0 100644 --- a/pkg/deploy/nostage.go +++ b/pkg/deploy/nostage.go @@ -1,5 +1,4 @@ //go:build no_stage -// +build no_stage package deploy diff --git a/pkg/deploy/stage.go b/pkg/deploy/stage.go index c7b458ccb9a1..937190a7ca9e 100644 --- a/pkg/deploy/stage.go +++ b/pkg/deploy/stage.go @@ -1,5 +1,4 @@ //go:build !no_stage -// +build !no_stage package deploy diff --git a/pkg/etcd/etcd.go b/pkg/etcd/etcd.go index 51fc2f5847a4..94146cc61277 100644 --- a/pkg/etcd/etcd.go +++ b/pkg/etcd/etcd.go @@ -143,11 +143,7 @@ func (e *membershipError) Error() string { } func (e *membershipError) Is(target error) bool { - switch target { - case ErrNotMember: - return true - } - return false + return target == ErrNotMember } func errNotMember() error { return &membershipError{} } @@ -161,11 +157,7 @@ func (e *memberListError) Error() string { } func (e *memberListError) Is(target error) bool { - switch target { - case ErrMemberListFailed: - return true - } - return false + return target == ErrMemberListFailed } func errMemberListFailed() error { return &memberListError{} } @@ -336,13 +328,13 @@ func (e *ETCD) IsInitialized() (bool, error) { } dir := walDir(e.config) - if s, err := os.Stat(dir); err == nil && s.IsDir() { + s, err := os.Stat(dir) + if err == nil && s.IsDir() { return true, nil } else if os.IsNotExist(err) { return false, nil - } else { - return false, pkgerrors.WithMessage(err, "invalid state for wal directory "+dir) } + return false, pkgerrors.WithMessage(err, "invalid state for wal directory "+dir) } // Reset resets an etcd node to a single node cluster. @@ -421,9 +413,8 @@ func (e *ETCD) Reset(ctx context.Context, wg *sync.WaitGroup, rebootstrap func() if err != nil { if errors.Is(err, s3.ErrNoConfigSecret) { return errors.New("cannot use S3 config secret when restoring snapshot; configuration must be set in CLI or config file") - } else { - return pkgerrors.WithMessage(err, "failed to initialize S3 client") } + return pkgerrors.WithMessage(err, "failed to initialize S3 client") } dir, err := snapshotDir(e.config, true) if err != nil { @@ -767,7 +758,7 @@ func (e *ETCD) handler(next http.Handler) http.Handler { func (e *ETCD) infoHandler() http.Handler { return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { if req.Method != http.MethodGet { - util.SendError(fmt.Errorf("method not allowed"), rw, req, http.StatusMethodNotAllowed) + util.SendError(errors.New("method not allowed"), rw, req, http.StatusMethodNotAllowed) return } @@ -1435,7 +1426,6 @@ func (e *ETCD) setEtcdStatusCondition(node *v1.Node, memberName string, memberSt } if find, condition := util.GetNodeCondition(&node.Status, etcdStatusType); find >= 0 { - // if the condition is not changing, we only want to update the last heartbeat time if condition.Status == newCondition.Status && condition.Reason == newCondition.Reason && condition.Message == newCondition.Message { logrus.Debugf("Node %s is not changing etcd status condition", memberName) diff --git a/pkg/etcd/etcd_linux_test.go b/pkg/etcd/etcd_linux_test.go index cea07e4c7335..661d4d7750e1 100644 --- a/pkg/etcd/etcd_linux_test.go +++ b/pkg/etcd/etcd_linux_test.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package etcd diff --git a/pkg/etcd/metadata_controller.go b/pkg/etcd/metadata_controller.go index 3186f63f6dcb..cac9943070a3 100644 --- a/pkg/etcd/metadata_controller.go +++ b/pkg/etcd/metadata_controller.go @@ -38,7 +38,6 @@ type metadataHandler struct { } func (m *metadataHandler) sync(key string, node *v1.Node) (*v1.Node, error) { - if node == nil { return nil, nil } diff --git a/pkg/etcd/resolver.go b/pkg/etcd/resolver.go index 09b366e76c03..85df17faa044 100644 --- a/pkg/etcd/resolver.go +++ b/pkg/etcd/resolver.go @@ -11,7 +11,7 @@ import ( const scheme = "etcd-endpoint" -type EtcdSimpleResolver struct { +type SimpleResolver struct { *manual.Resolver endpoint string } @@ -19,12 +19,12 @@ type EtcdSimpleResolver struct { // Cribbed from https://github.com/etcd-io/etcd/blob/v3.6.4/client/v3/internal/resolver/resolver.go // but only supports a single fixed endpoint. We use this instead of the internal etcd client resolver // because the agent loadbalancer handles failover and we don't want etcd or grpc's special behavior. -func NewSimpleResolver(endpoint string) *EtcdSimpleResolver { +func NewSimpleResolver(endpoint string) *SimpleResolver { r := manual.NewBuilderWithScheme(scheme) - return &EtcdSimpleResolver{Resolver: r, endpoint: endpoint} + return &SimpleResolver{Resolver: r, endpoint: endpoint} } -func (r *EtcdSimpleResolver) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { +func (r *SimpleResolver) Build(target resolver.Target, cc resolver.ClientConn, opts resolver.BuildOptions) (resolver.Resolver, error) { res, err := r.Resolver.Build(target, cc, opts) if err != nil { return nil, err diff --git a/pkg/etcd/s3/config_secret.go b/pkg/etcd/s3/config_secret.go index e7c8462c23d0..a54600f93a54 100644 --- a/pkg/etcd/s3/config_secret.go +++ b/pkg/etcd/s3/config_secret.go @@ -24,11 +24,7 @@ func (e *secretError) Error() string { } func (e *secretError) Is(target error) bool { - switch target { - case ErrNoConfigSecret: - return true - } - return false + return target == ErrNoConfigSecret } func errNoConfigSecret() error { return &secretError{} } diff --git a/pkg/etcd/s3/s3.go b/pkg/etcd/s3/s3.go index f1aa7aa1cbe3..e659b226deec 100644 --- a/pkg/etcd/s3/s3.go +++ b/pkg/etcd/s3/s3.go @@ -33,7 +33,6 @@ import ( v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - "k8s.io/utils/lru" ) var ( @@ -65,7 +64,7 @@ type Controller struct { tokenHash string nodeName string core core.Interface - clientCache *lru.Cache + clientCache *util.Cache[*Client] } // Client holds state for a given configuration - a preconfigured minio client, @@ -83,7 +82,7 @@ type Client struct { func Start(ctx context.Context, config *config.Control) (*Controller, error) { once.Do(func() { c := &Controller{ - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), nodeName: os.Getenv("NODE_NAME"), } @@ -161,7 +160,7 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli // print the endpoint and bucket name to avoid leaking creds into the logs. if client, ok := c.clientCache.Get(*etcdS3); ok { logrus.Infof("Reusing cached S3 client for endpoint=%q bucket=%q folder=%q", scheme+etcdS3.Endpoint, etcdS3.Bucket, etcdS3.Folder) - return client.(*Client), nil + return client, nil } logrus.Infof("Attempting to create new S3 client for endpoint=%q bucket=%q folder=%q", scheme+etcdS3.Endpoint, etcdS3.Bucket, etcdS3.Folder) @@ -201,7 +200,7 @@ func (c *Controller) GetClient(ctx context.Context, etcdS3 *config.EtcdS3) (*Cli return nil, pkgerrors.WithMessage(err, "failed to parse etcd-s3-proxy value as URL") } if u.Scheme == "" || u.Host == "" { - return nil, fmt.Errorf("proxy URL must include scheme and host") + return nil, errors.New("proxy URL must include scheme and host") } } tr.Proxy = http.ProxyURL(u) diff --git a/pkg/etcd/s3/s3_test.go b/pkg/etcd/s3/s3_test.go index b48ba20b01ec..131757ced05a 100644 --- a/pkg/etcd/s3/s3_test.go +++ b/pkg/etcd/s3/s3_test.go @@ -17,6 +17,7 @@ import ( "github.com/gorilla/mux" "github.com/k3s-io/k3s/pkg/daemons/config" "github.com/k3s-io/k3s/pkg/etcd/snapshot" + "github.com/k3s-io/k3s/pkg/util" "github.com/k3s-io/k3s/tests/mock" "github.com/rancher/dynamiclistener/cert" "github.com/rancher/wrangler/v3/pkg/generated/controllers/core" @@ -24,7 +25,6 @@ import ( "go.uber.org/mock/gomock" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/utils/lru" ) var gmt = time.FixedZone("GMT", 0) @@ -65,7 +65,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID string tokenHash string nodeName string - clientCache *lru.Cache + clientCache *util.Cache[*Client] } type args struct { ctx context.Context @@ -88,7 +88,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, wantErr: true, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -113,7 +113,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, wantErr: true, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -139,7 +139,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, wantErr: true, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -163,7 +163,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, wantErr: true, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -190,7 +190,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { coreMock := mock.NewCore(gomock.NewController(t)) @@ -231,7 +231,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { coreMock := mock.NewCore(gomock.NewController(t)) @@ -287,7 +287,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, wantErr: true, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -338,7 +338,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { coreMock := mock.NewCore(gomock.NewController(t)) @@ -364,7 +364,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { coreMock := mock.NewCore(gomock.NewController(t)) @@ -389,7 +389,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { coreMock := mock.NewCore(gomock.NewController(t)) @@ -412,7 +412,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, want: &Client{}, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -465,7 +465,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, want: &Client{}, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -495,7 +495,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { coreMock := mock.NewCore(gomock.NewController(t)) @@ -522,7 +522,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, wantErr: true, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -550,7 +550,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, wantErr: true, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -577,7 +577,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { coreMock := mock.NewCore(gomock.NewController(t)) @@ -603,7 +603,7 @@ func Test_UnitControllerGetClient(t *testing.T) { clusterID: "1234", tokenHash: "abcd", nodeName: "server01", - clientCache: lru.New(5), + clientCache: util.NewCache[*Client](5), }, wantErr: true, setup: func(t *testing.T, a args, f fields, c *Client) (core.Interface, error) { @@ -1558,8 +1558,7 @@ func s3Router(t *testing.T) http.Handler { // HeadBucket router.Path("/{bucket}/").Methods(http.MethodHead).HandlerFunc(func(rw http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - switch vars["bucket"] { - case "badbucket": + if vars["bucket"] == "badbucket" { rw.WriteHeader(http.StatusNotFound) } }) diff --git a/pkg/etcd/snapshot.go b/pkg/etcd/snapshot.go index f5343c92aa5c..475af3e268c0 100644 --- a/pkg/etcd/snapshot.go +++ b/pkg/etcd/snapshot.go @@ -169,12 +169,16 @@ func (e *ETCD) decompressSnapshot(snapshotDir, snapshotFile string) (string, err if err != nil { return "", err } + + //revive:disable-next-line:defer defer decompressed.Close() ss, err := sf.Open() if err != nil { return "", err } + + //revive:disable-next-line:defer defer ss.Close() if _, err := io.Copy(decompressed, ss); err != nil { diff --git a/pkg/etcd/snapshot/types.go b/pkg/etcd/snapshot/types.go index 362a1e0ea198..ff25f6d0b7d5 100644 --- a/pkg/etcd/snapshot/types.go +++ b/pkg/etcd/snapshot/types.go @@ -23,11 +23,11 @@ import ( "k8s.io/utils/ptr" ) -type SnapshotStatus string +type Status string const ( - SuccessfulStatus SnapshotStatus = "successful" - FailedStatus SnapshotStatus = "failed" + SuccessfulStatus Status = "successful" + FailedStatus Status = "failed" CompressedExtension = ".zip" MetadataDir = ".metadata" @@ -59,15 +59,15 @@ type File struct { Name string `json:"name"` // Location contains the full path of the snapshot. For // local paths, the location will be prefixed with "file://". - Location string `json:"location,omitempty"` - Metadata string `json:"metadata,omitempty"` - Message string `json:"message,omitempty"` - NodeName string `json:"nodeName,omitempty"` - CreatedAt *metav1.Time `json:"createdAt,omitempty"` - Size int64 `json:"size,omitempty"` - Status SnapshotStatus `json:"status,omitempty"` - S3 *S3Config `json:"s3Config,omitempty"` - Compressed bool `json:"compressed"` + Location string `json:"location,omitempty"` + Metadata string `json:"metadata,omitempty"` + Message string `json:"message,omitempty"` + NodeName string `json:"nodeName,omitempty"` + CreatedAt *metav1.Time `json:"createdAt,omitempty"` + Size int64 `json:"size,omitempty"` + Status Status `json:"status,omitempty"` + S3 *S3Config `json:"s3Config,omitempty"` + Compressed bool `json:"compressed"` // these fields are used for the internal representation of the snapshot // to populate other fields before serialization to the legacy configmap. diff --git a/pkg/etcd/snapshot_controller.go b/pkg/etcd/snapshot_controller.go index 09af0d1a12ff..9c9ef7cde7a1 100644 --- a/pkg/etcd/snapshot_controller.go +++ b/pkg/etcd/snapshot_controller.go @@ -9,7 +9,6 @@ import ( "strings" "time" - apisv1 "github.com/k3s-io/api/k3s.cattle.io/v1" k3s "github.com/k3s-io/api/k3s.cattle.io/v1" controllersv1 "github.com/k3s-io/api/pkg/generated/controllers/k3s.cattle.io/v1" "github.com/k3s-io/k3s/pkg/etcd/snapshot" @@ -70,7 +69,7 @@ func registerSnapshotHandlers(ctx context.Context, etcd *ETCD) { go wait.JitterUntil(func() { snapshots.Enqueue(reconcileKey) }, reconcileInterval, 0.04, false, ctx.Done()) } -func (e *etcdSnapshotHandler) sync(key string, esf *apisv1.ETCDSnapshotFile) (*apisv1.ETCDSnapshotFile, error) { +func (e *etcdSnapshotHandler) sync(key string, esf *k3s.ETCDSnapshotFile) (*k3s.ETCDSnapshotFile, error) { if key == reconcileKey { err := e.reconcile() if err == errNotReconciled { @@ -149,7 +148,7 @@ func (e *etcdSnapshotHandler) sync(key string, esf *apisv1.ETCDSnapshotFile) (*a return nil, err } -func (e *etcdSnapshotHandler) onRemove(key string, esf *apisv1.ETCDSnapshotFile) (*apisv1.ETCDSnapshotFile, error) { +func (e *etcdSnapshotHandler) onRemove(key string, esf *k3s.ETCDSnapshotFile) (*k3s.ETCDSnapshotFile, error) { if esf == nil { return nil, nil } @@ -220,7 +219,7 @@ func (e *etcdSnapshotHandler) reconcile() error { logrus.Infof("Reconciling snapshot ConfigMap data") // Get a list of existing snapshots - snapshots := map[string]*apisv1.ETCDSnapshotFile{} + snapshots := map[string]*k3s.ETCDSnapshotFile{} snapshotPager := pager.New(pager.SimplePageFunc(func(opts metav1.ListOptions) (k8sruntime.Object, error) { return e.snapshots.List(opts) })) snapshotPager.PageSize = snapshotListPageSize diff --git a/pkg/etcd/snapshot_handler.go b/pkg/etcd/snapshot_handler.go index 5d591d9832c2..1d156bcdcdec 100644 --- a/pkg/etcd/snapshot_handler.go +++ b/pkg/etcd/snapshot_handler.go @@ -3,7 +3,7 @@ package etcd import ( "context" "encoding/json" - "fmt" + "errors" "io" "net/http" @@ -136,7 +136,7 @@ func (e *ETCD) handleDelete(rw http.ResponseWriter, req *http.Request, snapshots } func (e *ETCD) handleInvalid(rw http.ResponseWriter, req *http.Request) error { - util.SendErrorWithID(fmt.Errorf("invalid snapshot operation"), "etcd-snapshot", rw, req, http.StatusBadRequest) + util.SendErrorWithID(errors.New("invalid snapshot operation"), "etcd-snapshot", rw, req, http.StatusBadRequest) return nil } diff --git a/pkg/executor/embed/embed.go b/pkg/executor/embed/embed.go index df6557541860..08b85842c87e 100644 --- a/pkg/executor/embed/embed.go +++ b/pkg/executor/embed/embed.go @@ -1,5 +1,4 @@ //go:build !no_embedded_executor -// +build !no_embedded_executor package embed @@ -103,9 +102,9 @@ func (e *Embedded) Bootstrap(ctx context.Context, nodeConfig *daemonconfig.Node, } // If there is a VPN, we must overwrite NodeIP and flannel interface - var vpnInfo vpn.VPNInfo + var vpnInfo *vpn.Info if cfg.VPNAuth != "" { - vpnInfo, err = vpn.GetVPNInfo(cfg.VPNAuth) + vpnInfo, err = vpn.GetInfo(cfg.VPNAuth) if err != nil { return err } @@ -137,9 +136,9 @@ func (e *Embedded) Bootstrap(ctx context.Context, nodeConfig *daemonconfig.Node, logrus.Warn("VPN provider overrides node-external-ip parameter") } nodeIPs = vpnIPs - nodeConfig.Flannel.Iface, err = net.InterfaceByName(vpnInfo.VPNInterface) + nodeConfig.Flannel.Iface, err = net.InterfaceByName(vpnInfo.Interface) if err != nil { - return pkgerrors.WithMessagef(err, "unable to find vpn interface: %s", vpnInfo.VPNInterface) + return pkgerrors.WithMessagef(err, "unable to find vpn interface: %s", vpnInfo.Interface) } } } diff --git a/pkg/executor/embed/embed_linux.go b/pkg/executor/embed/embed_linux.go index a41449e32a19..4deeb1133ef0 100644 --- a/pkg/executor/embed/embed_linux.go +++ b/pkg/executor/embed/embed_linux.go @@ -1,5 +1,4 @@ //go:build linux && !no_embedded_executor -// +build linux,!no_embedded_executor package embed diff --git a/pkg/executor/embed/embed_windows.go b/pkg/executor/embed/embed_windows.go index cdd5e09d3238..bd75b9405291 100644 --- a/pkg/executor/embed/embed_windows.go +++ b/pkg/executor/embed/embed_windows.go @@ -1,5 +1,4 @@ //go:build windows && !no_embedded_executor -// +build windows,!no_embedded_executor package embed @@ -19,10 +18,12 @@ const ( networkName = "flannel.4096" ) +type IP4 struct { + IP string `json:"ip"` +} + type SourceVipResponse struct { - IP4 struct { - IP string `json:"ip"` - } `json:"ip4"` + IP4 IP4 `json:"ip4"` } func platformKubeProxyArgs(nodeConfig *daemonconfig.Node) map[string]string { diff --git a/pkg/flock/flock_other.go b/pkg/flock/flock_other.go index dfb7d03a6e3b..ac2af4a15f94 100644 --- a/pkg/flock/flock_other.go +++ b/pkg/flock/flock_other.go @@ -1,5 +1,4 @@ //go:build !linux && !darwin && !freebsd && !openbsd && !netbsd && !dragonfly -// +build !linux,!darwin,!freebsd,!openbsd,!netbsd,!dragonfly /* Copyright 2016 The Kubernetes Authors. diff --git a/pkg/kubeadm/utils.go b/pkg/kubeadm/utils.go index f3181d9a041a..18bd4d437ed7 100644 --- a/pkg/kubeadm/utils.go +++ b/pkg/kubeadm/utils.go @@ -78,7 +78,6 @@ func encodeTokenSecretData(token *BootstrapToken, now time.Time) map[string][]by // TODO: This maybe should be a helper function in bootstraputil? expirationString := token.Expires.Time.UTC().Format(time.RFC3339) data[bootstrapapi.BootstrapTokenExpirationKey] = []byte(expirationString) - } else if token.TTL != nil && token.TTL.Duration > 0 { // Only if .Expires is unset, TTL might have an effect // Get the current time, add the specified duration, and format it accordingly diff --git a/pkg/nodepassword/nodepassword.go b/pkg/nodepassword/nodepassword.go index e1421ffb3b7a..577cfbcc82f7 100644 --- a/pkg/nodepassword/nodepassword.go +++ b/pkg/nodepassword/nodepassword.go @@ -34,11 +34,7 @@ func (e *passwordError) Error() string { } func (e *passwordError) Is(target error) bool { - switch target { - case ErrVerifyFailed: - return true - } - return false + return target == ErrVerifyFailed } func (e *passwordError) Unwrap() error { diff --git a/pkg/nodepassword/nodepassword_test.go b/pkg/nodepassword/nodepassword_test.go index 360990cc7af5..57606aafbac2 100644 --- a/pkg/nodepassword/nodepassword_test.go +++ b/pkg/nodepassword/nodepassword_test.go @@ -15,28 +15,30 @@ import ( const migrateNumNodes = 10 const createNumNodes = 3 +//revive:disable:deep-exit + func Test_UnitAsserts(t *testing.T) { assertEqual(t, 1, 1) assertNotEqual(t, 1, 0) } func Test_PasswordError(t *testing.T) { - err := &passwordError{node: "test", err: fmt.Errorf("inner error")} + err := &passwordError{node: "test", err: errors.New("inner error")} assertEqual(t, errors.Is(err, ErrVerifyFailed), true) - assertEqual(t, errors.Is(err, fmt.Errorf("different error")), false) + assertEqual(t, errors.Is(err, errors.New("different error")), false) assertNotEqual(t, errors.Unwrap(err), nil) } // -------------------------- // utility functions -func assertEqual(t *testing.T, a interface{}, b interface{}) { +func assertEqual(t *testing.T, a any, b any) { if a != b { t.Fatalf("[ %v != %v ]", a, b) } } -func assertNotEqual(t *testing.T, a interface{}, b interface{}) { +func assertNotEqual(t *testing.T, a any, b any) { if a == b { t.Fatalf("[ %v == %v ]", a, b) } diff --git a/pkg/nodepassword/validate.go b/pkg/nodepassword/validate.go index ab7102eeaa01..598822448729 100644 --- a/pkg/nodepassword/validate.go +++ b/pkg/nodepassword/validate.go @@ -67,10 +67,9 @@ func GetNodeAuthValidator(ctx context.Context, control *config.Control) NodeAuth // If we're running on an etcd-only node, and the request didn't use Node Identity auth, // defer node password verification until an apiserver joins the cluster. return verifyRemotePassword(ctx, control, &mu, deferredNodes, node) - } else { - // Otherwise, reject the request until the controller is ready. - return "", http.StatusServiceUnavailable, util.ErrCoreNotReady } + // Otherwise, reject the request until the controller is ready. + return "", http.StatusServiceUnavailable, util.ErrCoreNotReady } // verify that the node exists, if using Node Identity auth diff --git a/pkg/proctitle/proctile.go b/pkg/proctitle/proctile.go index 178dfa9ef069..43cec6e232c4 100644 --- a/pkg/proctitle/proctile.go +++ b/pkg/proctitle/proctile.go @@ -1,5 +1,4 @@ //go:build linux -// +build linux package proctitle diff --git a/pkg/proctitle/proctile_windows.go b/pkg/proctitle/proctile_windows.go index 9ade88241c7c..f34722c28775 100644 --- a/pkg/proctitle/proctile_windows.go +++ b/pkg/proctitle/proctile_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package proctitle diff --git a/pkg/rootless/mounts.go b/pkg/rootless/mounts.go index 3dfcd6ed91a7..d17d1263efb8 100644 --- a/pkg/rootless/mounts.go +++ b/pkg/rootless/mounts.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package rootless diff --git a/pkg/rootless/portdriver.go b/pkg/rootless/portdriver.go index 9736ad878c43..5c4d95b5f7ee 100644 --- a/pkg/rootless/portdriver.go +++ b/pkg/rootless/portdriver.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package rootless diff --git a/pkg/rootless/rootless.go b/pkg/rootless/rootless.go index e4abb37c413e..a59b3bda7727 100644 --- a/pkg/rootless/rootless.go +++ b/pkg/rootless/rootless.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package rootless @@ -81,6 +80,8 @@ func Rootless(stateDir string, enableIPv6 bool) error { if err := parent.Parent(*parentOpt); err != nil { logrus.Fatal(err) } + + //revive:disable-next-line:deep-exit os.Exit(0) return nil diff --git a/pkg/rootlessports/controller.go b/pkg/rootlessports/controller.go index f779f32069e3..784ae288d6d0 100644 --- a/pkg/rootlessports/controller.go +++ b/pkg/rootlessports/controller.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package rootlessports @@ -9,7 +8,7 @@ import ( "time" "github.com/k3s-io/k3s/pkg/rootless" - coreClients "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + corev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" "github.com/rootless-containers/rootlesskit/pkg/api/client" "github.com/rootless-containers/rootlesskit/pkg/port" "github.com/sirupsen/logrus" @@ -21,7 +20,7 @@ var ( all = "_all_" ) -func Register(ctx context.Context, serviceController coreClients.ServiceController, enabled bool, httpsPort int) error { +func Register(ctx context.Context, serviceController corev1.ServiceController, enabled bool, httpsPort int) error { var ( err error rootlessClient client.Client @@ -35,11 +34,11 @@ func Register(ctx context.Context, serviceController coreClients.ServiceControll rootlessClient, err = client.New(rootless.Sock) if err == nil { break - } else { - logrus.Infof("Waiting for rootless API socket %s: %v", rootless.Sock, err) - time.Sleep(1 * time.Second) } + logrus.Infof("Waiting for rootless API socket %s: %v", rootless.Sock, err) + time.Sleep(1 * time.Second) } + if err != nil { return err } @@ -61,8 +60,8 @@ func Register(ctx context.Context, serviceController coreClients.ServiceControll type handler struct { enabled bool rootlessClient client.Client - serviceClient coreClients.ServiceController - serviceCache coreClients.ServiceCache + serviceClient corev1.ServiceController + serviceCache corev1.ServiceCache httpsPort int ctx context.Context } diff --git a/pkg/rootlessports/controller_windows.go b/pkg/rootlessports/controller_windows.go index 0a5126923341..3e179696352e 100644 --- a/pkg/rootlessports/controller_windows.go +++ b/pkg/rootlessports/controller_windows.go @@ -3,9 +3,9 @@ package rootlessports import ( "context" - coreClients "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" + corev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1" ) -func Register(ctx context.Context, serviceController coreClients.ServiceController, enabled bool, httpsPort int) error { +func Register(ctx context.Context, serviceController corev1.ServiceController, enabled bool, httpsPort int) error { panic("Rootless is not supported on windows") } diff --git a/pkg/secretsencrypt/config.go b/pkg/secretsencrypt/config.go index d6a8dd9d37e9..0bb361048a6b 100644 --- a/pkg/secretsencrypt/config.go +++ b/pkg/secretsencrypt/config.go @@ -6,6 +6,7 @@ import ( "crypto/sha256" "encoding/hex" "encoding/json" + "errors" "fmt" "os" "time" @@ -69,7 +70,6 @@ func GetEncryptionProviders(runtime *config.ControlRuntime) ([]apiserverconfigv1 // GetEncryptionKeys returns a list of encryption keys from the current encryption configuration. func GetEncryptionKeys(runtime *config.ControlRuntime) (*EncryptionKeys, error) { - currentKeys := &EncryptionKeys{} providers, err := GetEncryptionProviders(runtime) if err != nil { @@ -92,7 +92,7 @@ func GetEncryptionKeys(runtime *config.ControlRuntime) (*EncryptionKeys, error) currentKeys.SBKeys = append(currentKeys.SBKeys, p.Secretbox.Keys...) } if p.AESGCM != nil || p.KMS != nil { - return nil, fmt.Errorf("unsupported encryption keys found") + return nil, errors.New("unsupported encryption keys found") } } return currentKeys, nil @@ -101,7 +101,6 @@ func GetEncryptionKeys(runtime *config.ControlRuntime) (*EncryptionKeys, error) // WriteEncryptionConfig writes the encryption configuration to the file system. // The provider arg will be placed first, and is used to encrypt new secrets. func WriteEncryptionConfig(runtime *config.ControlRuntime, keys *EncryptionKeys, provider string, enable bool) error { - var providers []apiserverconfigv1.ProviderConfiguration var primary apiserverconfigv1.ProviderConfiguration var secondary *apiserverconfigv1.ProviderConfiguration @@ -186,7 +185,6 @@ func GenEncryptionConfigHash(runtime *config.ControlRuntime) (string, error) { // GenReencryptHash generates a sha256 hash from the existing secrets keys and // any identity providers plus a new key based on the input arguments. func GenReencryptHash(runtime *config.ControlRuntime, keyName string) (string, error) { - // To retain compatibility with the older encryption hash format, // we contruct the hash as: aescbc + secretbox + identity + newkey currentKeys, err := GetEncryptionKeys(runtime) @@ -335,7 +333,7 @@ func GetEncryptionConfigMetrics(runtime *config.ControlRuntime, initialMetrics b unixUpdateTime = int64(tsMetric.GetMetric()[0].GetGauge().GetValue()) if time.Now().Unix() < unixUpdateTime { - return true, fmt.Errorf("encryption reload time is incorrectly ahead of current time") + return true, errors.New("encryption reload time is incorrectly ahead of current time") } for _, totalMetric := range totalMetrics.GetMetric() { diff --git a/pkg/server/handlers/cert.go b/pkg/server/handlers/cert.go index e1cd6be1e115..82e748e32f3f 100644 --- a/pkg/server/handlers/cert.go +++ b/pkg/server/handlers/cert.go @@ -33,7 +33,7 @@ import ( func CACertReplace(control *config.Control) http.HandlerFunc { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { if req.Method != http.MethodPut { - util.SendError(fmt.Errorf("method not allowed"), resp, req, http.StatusMethodNotAllowed) + util.SendError(errors.New("method not allowed"), resp, req, http.StatusMethodNotAllowed) return } force, _ := strconv.ParseBool(req.FormValue("force")) diff --git a/pkg/server/handlers/handlers.go b/pkg/server/handlers/handlers.go index 4c2650699a8c..ca2371e1def9 100644 --- a/pkg/server/handlers/handlers.go +++ b/pkg/server/handlers/handlers.go @@ -257,7 +257,12 @@ func signAndSend(resp http.ResponseWriter, req *http.Request, caCertFile, caKeyF util.SendError(err, resp, req) return } - key = pk.(crypto.Signer) + k, ok := pk.(crypto.Signer) + if !ok { + util.SendError(errors.New("type assertion failed"), resp, req) + return + } + key = k } // create the signed cert using dynamiclistener cert utils @@ -298,7 +303,12 @@ func getCACertAndKey(caCertFile, caKeyFile string) ([]*x509.Certificate, crypto. return nil, nil, err } - return caCert, caKey.(crypto.Signer), nil + k, ok := caKey.(crypto.Signer) + if !ok { + return nil, nil, errors.New("type assertion failed") + } + + return caCert, k, nil } // getCSR decodes a x509.CertificateRequest from a POST request body. diff --git a/pkg/server/handlers/handlers_test.go b/pkg/server/handlers/handlers_test.go index 0589bbe27918..85ab74e215d2 100644 --- a/pkg/server/handlers/handlers_test.go +++ b/pkg/server/handlers/handlers_test.go @@ -18,6 +18,9 @@ import ( "path/filepath" "testing" + //revive:disable:dot-imports + . "github.com/onsi/gomega" + "github.com/k3s-io/k3s/pkg/authenticator" "github.com/k3s-io/k3s/pkg/cli/cmds" "github.com/k3s-io/k3s/pkg/daemons/config" @@ -27,7 +30,6 @@ import ( "github.com/k3s-io/k3s/pkg/version" testutil "github.com/k3s-io/k3s/tests" "github.com/k3s-io/k3s/tests/mock" - . "github.com/onsi/gomega" "github.com/onsi/gomega/types" certutil "github.com/rancher/dynamiclistener/cert" "github.com/sirupsen/logrus" @@ -105,11 +107,11 @@ func Test_UnitHandlers(t *testing.T) { paths []pathTest }{ { - //*** tests with runtime core not ready *** + // *** tests with runtime core not ready *** name: "no runtime core", controlFunc: getCorelessControl, paths: []pathTest{ - //** paths accessible with node cert or agent token, and specific headers ** + // ** paths accessible with node cert or agent token, and specific headers ** { method: http.MethodGet, path: "/v1-k3s/serving-kubelet.crt", @@ -356,7 +358,7 @@ func Test_UnitHandlers(t *testing.T) { }, }, { - //*** tests with runtime core not ready and bind address set *** + // *** tests with runtime core not ready and bind address set *** name: "no runtime core with bind-address", controlFunc: func(t *testing.T) (*config.Control, context.CancelFunc) { control, cancel := getCorelessControl(t) @@ -364,7 +366,7 @@ func Test_UnitHandlers(t *testing.T) { return control, cancel }, paths: []pathTest{ - //** paths accessible with node cert or agent token, and specific headers ** + // ** paths accessible with node cert or agent token, and specific headers ** { method: http.MethodGet, path: "/v1-k3s/serving-kubelet.crt", @@ -611,11 +613,11 @@ func Test_UnitHandlers(t *testing.T) { }, }, { - //*** tests with no agent and runtime core not ready *** + // *** tests with no agent and runtime core not ready *** name: "agentless no runtime core", controlFunc: getCorelessAgentlessControl, paths: []pathTest{ - //** paths accessible with node cert or agent token, and specific headers ** + // ** paths accessible with node cert or agent token, and specific headers ** { method: http.MethodGet, path: "/v1-k3s/serving-kubelet.crt", @@ -874,11 +876,11 @@ func Test_UnitHandlers(t *testing.T) { }, }, { - //*** tests with mocked core controllers *** + // *** tests with mocked core controllers *** name: "mocked", controlFunc: getMockedControl, paths: []pathTest{ - //** paths accessible with node cert or agent token, and specific headers ** + // ** paths accessible with node cert or agent token, and specific headers ** { method: http.MethodGet, path: "/v1-k3s/serving-kubelet.crt", @@ -1133,7 +1135,7 @@ func Test_UnitHandlers(t *testing.T) { }, ), }, - //** paths accessible with node cert or agent token ** + // ** paths accessible with node cert or agent token ** { method: http.MethodGet, path: "/v1-k3s/client-kube-proxy.crt", @@ -1440,7 +1442,7 @@ func Test_UnitHandlers(t *testing.T) { }, ), }, - //** paths accessible with node cert ** + // ** paths accessible with node cert ** { method: http.MethodGet, path: "/v1-k3s/connect", @@ -1460,7 +1462,7 @@ func Test_UnitHandlers(t *testing.T) { }, ), }, - //** paths accessible with server token ** + // ** paths accessible with server token ** { method: http.MethodGet, path: "/v1-k3s/encrypt/status", @@ -1535,7 +1537,7 @@ func Test_UnitHandlers(t *testing.T) { }, ), }, - //** paths accessible with apiserver cert ** + // ** paths accessible with apiserver cert ** { method: http.MethodConnect, path: "/", @@ -1551,7 +1553,7 @@ func Test_UnitHandlers(t *testing.T) { }, ), }, - //** paths accessible anonymously ** + // ** paths accessible anonymously ** { method: http.MethodGet, path: "/ping", diff --git a/pkg/server/handlers/secrets-encrypt.go b/pkg/server/handlers/secrets-encrypt.go index eadaa2da6256..2cca9819c220 100644 --- a/pkg/server/handlers/secrets-encrypt.go +++ b/pkg/server/handlers/secrets-encrypt.go @@ -177,7 +177,7 @@ func encryptionEnable(ctx context.Context, control *config.Control, enable bool) logrus.Infoln("Secrets encryption already enabled") return nil } else { - return fmt.Errorf("unable to enable/disable secrets encryption, unknown configuration") + return errors.New("unable to enable/disable secrets encryption, unknown configuration") } if err := cluster.Save(ctx, control, true); err != nil { return err @@ -188,7 +188,7 @@ func encryptionEnable(ctx context.Context, control *config.Control, enable bool) func EncryptionConfig(ctx context.Context, control *config.Control) http.Handler { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { if req.Method != http.MethodPut { - util.SendError(fmt.Errorf("method not allowed"), resp, req, http.StatusMethodNotAllowed) + util.SendError(errors.New("method not allowed"), resp, req, http.StatusMethodNotAllowed) return } @@ -237,7 +237,7 @@ func encryptionPrepare(ctx context.Context, control *config.Control, force bool) return err } if control.EncryptProvider == secretsencrypt.SecretBoxProvider { - return fmt.Errorf("prepare does not support secretbox key type, use rotate-keys instead") + return errors.New("prepare does not support secretbox key type, use rotate-keys instead") } curKeys, err := secretsencrypt.GetEncryptionKeys(control.Runtime) @@ -265,7 +265,7 @@ func encryptionRotate(ctx context.Context, control *config.Control, force bool) return err } if control.EncryptProvider == secretsencrypt.SecretBoxProvider { - return fmt.Errorf("rotate does not support secretbox key type, use rotate-keys instead") + return errors.New("rotate does not support secretbox key type, use rotate-keys instead") } curKeys, err := secretsencrypt.GetEncryptionKeys(control.Runtime) @@ -301,7 +301,7 @@ func encryptionReencrypt(ctx context.Context, control *config.Control, force boo return err } if control.EncryptProvider == secretsencrypt.SecretBoxProvider { - return fmt.Errorf("reencrypt does not support secretbox key type, use rotate-keys instead") + return errors.New("reencrypt does not support secretbox key type, use rotate-keys instead") } // Set the reencrypt-active annotation so other nodes know we are in the process of reencrypting. diff --git a/pkg/server/handlers/token.go b/pkg/server/handlers/token.go index fd782d2b4758..8203351f7a77 100644 --- a/pkg/server/handlers/token.go +++ b/pkg/server/handlers/token.go @@ -3,7 +3,7 @@ package handlers import ( "context" "encoding/json" - "fmt" + "errors" "io" "net/http" "os" @@ -35,7 +35,7 @@ func getServerTokenRequest(req *http.Request) (TokenRotateRequest, error) { func TokenRequest(ctx context.Context, control *config.Control) http.Handler { return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) { if req.Method != http.MethodPut { - util.SendError(fmt.Errorf("method not allowed"), resp, req, http.StatusMethodNotAllowed) + util.SendError(errors.New("method not allowed"), resp, req, http.StatusMethodNotAllowed) return } var err error @@ -73,7 +73,7 @@ func tokenRotate(ctx context.Context, control *config.Control, newToken string) oldToken, found := passwd.Pass("server") if !found { - return fmt.Errorf("server token not found") + return errors.New("server token not found") } if newToken == "" { newToken, err = util.Random(16) diff --git a/pkg/signals/signals.go b/pkg/signals/signals.go index 6bc55a9c6b5c..fe6b02999d22 100644 --- a/pkg/signals/signals.go +++ b/pkg/signals/signals.go @@ -37,6 +37,8 @@ func SetupSignalContext() context.Context { cancel() s := <-signalHandler logrus.Infof("Second shutdown signal received: %s, exiting...", s) + + //revive:disable-next-line:deep-exit os.Exit(1) }() diff --git a/pkg/signals/signals_posix.go b/pkg/signals/signals_posix.go index 489dfc0423a9..33cfbd233093 100644 --- a/pkg/signals/signals_posix.go +++ b/pkg/signals/signals_posix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package signals diff --git a/pkg/signals/signals_windows.go b/pkg/signals/signals_windows.go index 027dc49d60b7..29ab33f0c5db 100644 --- a/pkg/signals/signals_windows.go +++ b/pkg/signals/signals_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package signals diff --git a/pkg/static/nostage.go b/pkg/static/nostage.go index f3fc60490124..7c086e34d396 100644 --- a/pkg/static/nostage.go +++ b/pkg/static/nostage.go @@ -1,5 +1,4 @@ //go:build no_stage -// +build no_stage package static diff --git a/pkg/static/stage.go b/pkg/static/stage.go index 7f0836390806..303c4f6c7e38 100644 --- a/pkg/static/stage.go +++ b/pkg/static/stage.go @@ -1,5 +1,4 @@ //go:build !no_stage -// +build !no_stage package static diff --git a/pkg/util/api.go b/pkg/util/api.go index c0400202316f..80f857e5ca18 100644 --- a/pkg/util/api.go +++ b/pkg/util/api.go @@ -65,7 +65,7 @@ func GetAddressesFromSlices(slices ...discoveryv1.EndpointSlice) []string { port = "443" } for _, endpoint := range slice.Endpoints { - if endpoint.Conditions.Ready == nil || *endpoint.Conditions.Ready == true { + if endpoint.Conditions.Ready == nil || *endpoint.Conditions.Ready { for _, address := range endpoint.Addresses { serverAddresses = append(serverAddresses, net.JoinHostPort(address, port)) } diff --git a/pkg/util/args.go b/pkg/util/args.go index 02838dd95dfe..b39de6fd1755 100644 --- a/pkg/util/args.go +++ b/pkg/util/args.go @@ -25,7 +25,6 @@ func ArgValue(searchArg string, extraArgs []string) string { // GetArgs appends extra arguments to existing arguments with logic to override any default // arguments whilst also allowing to prefix and suffix default string slice arguments. func GetArgs(initialArgs map[string]string, extraArgs []string) []string { - multiArgs := make(map[string][]string) for _, unsplitArg := range extraArgs { @@ -51,7 +50,6 @@ func GetArgs(initialArgs map[string]string, extraArgs []string) []string { newValues = append(newValues, existingValues...) } newValues = append(newValues, value) - } else if strings.HasSuffix(arg, "-") { // Prepend value to initial args newValues = append(newValues, value) if initialValueExists { @@ -69,7 +67,6 @@ func GetArgs(initialArgs map[string]string, extraArgs []string) []string { delete(initialArgs, cleanedArg) multiArgs[cleanedArg] = newValues - } // Add any remaining initial args to the map @@ -98,9 +95,9 @@ func GetArgs(initialArgs map[string]string, extraArgs []string) []string { } // AddFeatureGate correctly appends a feature gate key pair to the feature gates CLI switch. -func AddFeatureGate(current, new string) string { +func AddFeatureGate(current, toAdd string) string { if current == "" { - return new + return toAdd } - return current + "," + new + return current + "," + toAdd } diff --git a/pkg/util/condition.go b/pkg/util/condition.go index 4aa7c7e7454f..2ad9ebc60a35 100644 --- a/pkg/util/condition.go +++ b/pkg/util/condition.go @@ -30,8 +30,8 @@ func SetNodeCondition(core config.CoreFactory, nodeName string, condition corev1 return ErrCoreNotReady } condition.LastHeartbeatTime = metav1.NewTime(time.Now()) - patch, err := json.Marshal(map[string]interface{}{ - "status": map[string]interface{}{ + patch, err := json.Marshal(map[string]any{ + "status": map[string]any{ "conditions": []corev1.NodeCondition{condition}, }, }) diff --git a/pkg/util/logger/logger.go b/pkg/util/logger/logger.go index cc60dbb7c4c1..3adcaa875ef6 100644 --- a/pkg/util/logger/logger.go +++ b/pkg/util/logger/logger.go @@ -8,7 +8,7 @@ import ( ) // implicit interface check -var _ logr.LogSink = &logrusSink{} +var _ logr.LogSink = &LogrusSink{} // mapLevel maps logr log verbosities to logrus log levels // logr does not have "log levels", but Info prints at verbosity 0 @@ -28,7 +28,10 @@ func mapLevel(level int) logrus.Level { func mapKV(kvs []any) logrus.Fields { fields := logrus.Fields{} for i := 0; i < len(kvs); i += 2 { - k := kvs[i].(string) + k, ok := kvs[i].(string) + if !ok { + k = fmt.Sprint(kvs[i]) + } if len(kvs) > i+1 { fields[k] = kvs[i+1] } else { @@ -39,46 +42,46 @@ func mapKV(kvs []any) logrus.Fields { } // LogrusSink wraps logrus the Logger/Entry types for use as a logr LogSink. -type logrusSink struct { +type LogrusSink struct { e *logrus.Entry ri logr.RuntimeInfo } -func NewLogrusSink(l *logrus.Logger) *logrusSink { +func NewLogrusSink(l *logrus.Logger) *LogrusSink { if l == nil { l = logrus.StandardLogger() } - return &logrusSink{e: logrus.NewEntry(l)} + return &LogrusSink{e: logrus.NewEntry(l)} } -func (ls *logrusSink) AsLogr() logr.Logger { +func (ls *LogrusSink) AsLogr() logr.Logger { return logr.New(ls) } -func (ls *logrusSink) Init(ri logr.RuntimeInfo) { +func (ls *LogrusSink) Init(ri logr.RuntimeInfo) { ls.ri = ri } -func (ls *logrusSink) Enabled(level int) bool { +func (ls *LogrusSink) Enabled(level int) bool { return ls.e.Logger.IsLevelEnabled(mapLevel(level)) } -func (ls *logrusSink) Info(level int, msg string, kvs ...any) { +func (ls *LogrusSink) Info(level int, msg string, kvs ...any) { ls.e.WithFields(mapKV(kvs)).Log(mapLevel(level), msg) } -func (ls *logrusSink) Error(err error, msg string, kvs ...any) { +func (ls *LogrusSink) Error(err error, msg string, kvs ...any) { ls.e.WithError(err).WithFields(mapKV(kvs)).Error(msg) } -func (ls *logrusSink) WithValues(kvs ...any) logr.LogSink { - return &logrusSink{ +func (ls *LogrusSink) WithValues(kvs ...any) logr.LogSink { + return &LogrusSink{ e: ls.e.WithFields(mapKV(kvs)), ri: ls.ri, } } -func (ls *logrusSink) WithName(name string) logr.LogSink { +func (ls *LogrusSink) WithName(name string) logr.LogSink { if base, ok := ls.e.Data["logger"]; ok { name = fmt.Sprintf("%s/%s", base, name) } diff --git a/pkg/util/lru.go b/pkg/util/lru.go new file mode 100644 index 000000000000..c81e022a8780 --- /dev/null +++ b/pkg/util/lru.go @@ -0,0 +1,54 @@ +package util + +import "k8s.io/utils/lru" + +// Cache is a generic wrapper around lru.Cache that handles type assertions when +// retrieving cached entries. +type Cache[T any] struct { + cache *lru.Cache +} + +func NewCache[T any](size int) *Cache[T] { + return &Cache[T]{ + cache: lru.New(size), + } +} + +func NewCacheWithEvictionFunc[T any](size int, f lru.EvictionFunc) *Cache[T] { + return &Cache[T]{ + cache: lru.NewWithEvictionFunc(size, f), + } +} + +func (c *Cache[T]) Add(key lru.Key, value T) { + c.cache.Add(key, value) +} + +func (c *Cache[T]) Clear() { + c.cache.Clear() +} + +func (c *Cache[T]) Get(key lru.Key) (value T, ok bool) { + v, ok := c.cache.Get(key) + if !ok { + return value, ok + } + value, ok = v.(T) + return value, ok +} + +func (c *Cache[T]) Len() int { + return c.cache.Len() +} + +func (c *Cache[T]) Remove(key lru.Key) { + c.cache.Remove(key) +} + +func (c *Cache[T]) RemoveOldest() { + c.cache.RemoveOldest() +} + +func (c *Cache[T]) SetEvictionFunc(f lru.EvictionFunc) { + c.cache.SetEvictionFunc(f) +} diff --git a/pkg/util/net.go b/pkg/util/net.go index 05fd2180b15d..4123493537e5 100644 --- a/pkg/util/net.go +++ b/pkg/util/net.go @@ -206,21 +206,12 @@ func GetFirstValidIPString(s []string) string { // GetFirstIP checks what is the IPFamily of the first item. Based on that, returns a set of values func GetDefaultAddresses(nodeIP net.IP) (string, string, string, error) { - if netutils.IsIPv4(nodeIP) { - ListenAddress := "0.0.0.0" - clusterCIDR := "10.42.0.0/16" - serviceCIDR := "10.43.0.0/16" - - return ListenAddress, clusterCIDR, serviceCIDR, nil + return "0.0.0.0", "10.42.0.0/16", "10.43.0.0/16", nil } if netutils.IsIPv6(nodeIP) { - ListenAddress := "::" - clusterCIDR := "fd00:42::/56" - serviceCIDR := "fd00:43::/112" - - return ListenAddress, clusterCIDR, serviceCIDR, nil + return "::", "fd00:42::/56", "fd00:43::/112", nil } return "", "", "", fmt.Errorf("ip: %v is not ipv4 or ipv6", nodeIP) @@ -231,15 +222,15 @@ func GetDefaultAddresses(nodeIP net.IP) (string, string, string, error) { // if neither of IPv4 or IPv6 are found an error is raised. func GetFirstString(elems []string) (string, bool, error) { ip, err := GetFirst4String(elems) - IPv6only := false + v6only := false if err != nil { ip, err = GetFirst6String(elems) if err != nil { return "", false, err } - IPv6only = true + v6only = true } - return ip, IPv6only, nil + return ip, v6only, nil } // IPToIPNet converts an IP to an IPNet, using a fully filled mask appropriate for the address family. @@ -405,9 +396,9 @@ func (ml *multiListener) Accept() (net.Conn, error) { if ok { return res.conn, res.err } - return nil, fmt.Errorf("connection channel closed") + return nil, errors.New("connection channel closed") case <-ml.closing: - return nil, fmt.Errorf("listener closed") + return nil, errors.New("listener closed") } } diff --git a/pkg/util/net_unix.go b/pkg/util/net_unix.go index 521e577cd15c..cf3b35cb9140 100644 --- a/pkg/util/net_unix.go +++ b/pkg/util/net_unix.go @@ -1,5 +1,4 @@ //go:build !windows -// +build !windows package util diff --git a/pkg/util/net_windows.go b/pkg/util/net_windows.go index bb895c095a77..281cf6a3f4c1 100644 --- a/pkg/util/net_windows.go +++ b/pkg/util/net_windows.go @@ -1,5 +1,4 @@ //go:build windows -// +build windows package util diff --git a/pkg/util/patch.go b/pkg/util/patch.go index 26f9b98fd79b..64a6afdd207c 100644 --- a/pkg/util/patch.go +++ b/pkg/util/patch.go @@ -21,21 +21,21 @@ type clientPatcher[T runtime.Object] interface { Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (T, error) } -// patchWrapper wraps the Patch functions provided by either wrangler or client-go -type patchWrapper[T runtime.Object] struct { - patcher any +// Patcher wraps the Patch functions provided by either wrangler or client-go +type Patcher[T runtime.Object] struct { + impl any } // NewPatcher wraps the provided controller or client for use as a generic patcher // note that the patcher is not validated for use until `Patch` is called -func NewPatcher[T runtime.Object](patcher any) *patchWrapper[T] { - return &patchWrapper[T]{ - patcher: patcher, +func NewPatcher[T runtime.Object](patcher any) *Patcher[T] { + return &Patcher[T]{ + impl: patcher, } } // Patch applies the provided PatchList to the specified resource -func (p *patchWrapper[T]) Patch(ctx context.Context, pl *PatchList, name string, subresources ...string) (T, error) { +func (p *Patcher[T]) Patch(ctx context.Context, pl *PatchList, name string, subresources ...string) (T, error) { var t T if pl == nil { pl = NewPatchList() @@ -44,13 +44,13 @@ func (p *patchWrapper[T]) Patch(ctx context.Context, pl *PatchList, name string, if err != nil { return t, err } - if patch, ok := p.patcher.(clientPatcher[T]); ok { + if patch, ok := p.impl.(clientPatcher[T]); ok { return patch.Patch(ctx, name, types.JSONPatchType, b, metav1.PatchOptions{}, subresources...) } - if patch, ok := p.patcher.(controllerPatcher[T]); ok { + if patch, ok := p.impl.(controllerPatcher[T]); ok { return patch.Patch(name, types.JSONPatchType, b, subresources...) } - return t, fmt.Errorf("unable to patch %T with %T", t, p.patcher) + return t, fmt.Errorf("unable to patch %T with %T", t, p.impl) } // PatchList is a generic list of JSONPatch operations to apply to a resource diff --git a/pkg/util/permissions/permissions_others.go b/pkg/util/permissions/permissions_others.go index 3d43c323244a..e25605ea7468 100644 --- a/pkg/util/permissions/permissions_others.go +++ b/pkg/util/permissions/permissions_others.go @@ -1,10 +1,9 @@ //go:build !windows -// +build !windows package permissions import ( - "fmt" + "errors" "os" ) @@ -12,7 +11,7 @@ import ( // Ref: https://github.com/kubernetes/kubernetes/pull/96616 func IsPrivileged() error { if os.Getuid() != 0 { - return fmt.Errorf("not running as root") + return errors.New("not running as root") } return nil } diff --git a/pkg/util/permissions/permissions_windows.go b/pkg/util/permissions/permissions_windows.go index df0e6988139f..0b4a9109198c 100644 --- a/pkg/util/permissions/permissions_windows.go +++ b/pkg/util/permissions/permissions_windows.go @@ -1,10 +1,9 @@ //go:build windows -// +build windows package permissions import ( - "fmt" + "errors" pkgerrors "github.com/pkg/errors" "golang.org/x/sys/windows" @@ -40,7 +39,7 @@ func IsPrivileged() error { } if !member { - return fmt.Errorf("not running as member of BUILTIN\\Administrators group") + return errors.New("not running as member of BUILTIN\\Administrators group") } return nil diff --git a/pkg/util/reflect.go b/pkg/util/reflect.go index 9530f02e9b46..758707e26664 100644 --- a/pkg/util/reflect.go +++ b/pkg/util/reflect.go @@ -5,6 +5,6 @@ import ( "runtime" ) -func GetFunctionName(i interface{}) string { +func GetFunctionName(i any) string { return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() } diff --git a/pkg/vpn/vpn.go b/pkg/vpn/vpn.go index 39d2611bf6b8..9580f8bc42c7 100644 --- a/pkg/vpn/vpn.go +++ b/pkg/vpn/vpn.go @@ -21,21 +21,21 @@ const ( type TailscaleOutput struct { TailscaleIPs []string `json:"TailscaleIPs"` - BackendState string `json:"BackendState"` + BackendState string `json:"BackendState"` } type TailscalePrefsOutput struct { AdvertiseRoutes []netip.Prefix `json:"AdvertiseRoutes"` } -// VPNInfo includes node information of the VPN. It is a general struct in case we want to add more vpn integrations -type VPNInfo struct { +// Info includes node information of the VPN. It is a general struct in case we want to add more vpn integrations +type Info struct { BackendState string IPv4Address net.IP IPv6Address net.IP NodeID string ProviderName string - VPNInterface string + Interface string } // vpnCliAuthInfo includes auth information of the VPN. It is a general struct in case we want to add more vpn integrations @@ -82,17 +82,17 @@ func StartVPN(vpnAuthConfigFile string) error { } } -// GetVPNInfo returns a VPNInfo object with details about the VPN. General function in case we want to add more vpn integrations -func GetVPNInfo(vpnAuth string) (VPNInfo, error) { +// GetInfo returns an Info object with details about the VPN. General function in case we want to add more vpn integrations +func GetInfo(vpnAuth string) (*Info, error) { authInfo, err := getVPNAuthInfo(vpnAuth) if err != nil { - return VPNInfo{}, err + return nil, err } if authInfo.Name == "tailscale" { return getTailscaleInfo() } - return VPNInfo{}, nil + return nil, nil } // getVPNAuthInfo returns the required authInfo object @@ -142,10 +142,10 @@ func isVPNConfigOK(authInfo vpnCliAuthInfo) error { } // getTailscaleInfo returns the IPs of the interface -func getTailscaleInfo() (VPNInfo, error) { +func getTailscaleInfo() (*Info, error) { output, err := util.ExecCommand("tailscale", []string{"status", "--json"}) if err != nil { - return VPNInfo{}, fmt.Errorf("failed to run tailscale status --json: %v", err) + return nil, fmt.Errorf("failed to run tailscale status --json: %v", err) } logrus.Debugf("Output from tailscale status --json: %v", output) @@ -153,14 +153,14 @@ func getTailscaleInfo() (VPNInfo, error) { var tailscaleOutput TailscaleOutput err = json.Unmarshal([]byte(output), &tailscaleOutput) if err != nil { - return VPNInfo{}, fmt.Errorf("failed to unmarshal tailscale output: %v", err) + return nil, fmt.Errorf("failed to unmarshal tailscale output: %v", err) } // Errors are ignored because the interface might not have ipv4 or ipv6 addresses (that's the only possible error) ipv4Address, _ := util.GetFirst4String(tailscaleOutput.TailscaleIPs) ipv6Address, _ := util.GetFirst6String(tailscaleOutput.TailscaleIPs) - return VPNInfo{BackendState: tailscaleOutput.BackendState, IPv4Address: net.ParseIP(ipv4Address), IPv6Address: net.ParseIP(ipv6Address), NodeID: "", ProviderName: "tailscale", VPNInterface: tailscaleIf}, nil + return &Info{BackendState: tailscaleOutput.BackendState, IPv4Address: net.ParseIP(ipv4Address), IPv6Address: net.ParseIP(ipv6Address), NodeID: "", ProviderName: "tailscale", Interface: tailscaleIf}, nil } // get Tailscale advertised route list @@ -179,7 +179,6 @@ func GetAdvertisedRoutes() ([]netip.Prefix, error) { } return tailscaleOutput.AdvertiseRoutes, nil - } // processCLIArgs separates the extraArgs part from the command. diff --git a/scripts/validate b/scripts/validate index b879db309d04..d5708d5f9b08 100755 --- a/scripts/validate +++ b/scripts/validate @@ -1,6 +1,8 @@ #!/bin/bash set -e +export GIT_PAGER=cat + if [ -n "$SKIP_VALIDATE" ]; then echo Skipping validation exit @@ -38,11 +40,7 @@ if [ ! -e build/data ];then mkdir -p build/data fi -if ! command -v golangci-lint; then - echo Skipping validation: no golangci-lint available - exit +if [ -z "$SKIP_LINT" ] && command -v golangci-lint; then + echo Running: golangci-lint + golangci-lint run --timeout=5m fi - -#echo Running: golangci-lint -## https://github.com/golangci/golangci-lint/issues/2788 -#CGO_ENABLED=0 golangci-lint run -v