diff --git a/.github/workflows/golangci-lint.yml b/.github/workflows/golangci-lint.yml index 73ea0cfd5..2f860f285 100644 --- a/.github/workflows/golangci-lint.yml +++ b/.github/workflows/golangci-lint.yml @@ -21,13 +21,13 @@ jobs: with: go-version: ${{ steps.vars.outputs.go_version }} - name: golangci-lint - uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # tag=v6.5.2 + uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # tag=v7.0.0 with: - version: v1.63.3 + version: v2.0.2 args: --timeout 15m - name: golangci-lint-test - uses: golangci/golangci-lint-action@55c2c1448f86e01eaae002a5a3a9624417608d84 # tag=v6.5.2 + uses: golangci/golangci-lint-action@1481404843c368bc19ca9406f87d6e0fc97bdcfd # tag=v7.0.0 with: - version: v1.63.3 + version: v2.0.2 args: --build-tags e2e --timeout 15m working-directory: test diff --git a/.golangci.yaml b/.golangci.yaml index 58371ac09..a623d4533 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -1,46 +1,34 @@ +version: "2" run: - timeout: 5m go: "1.23" allow-parallel-runners: true - linters: - disable-all: true - # Enable specific linter - # https://golangci-lint.run/usage/linters/#enabled-by-default-linters + default: none enable: - # Default linters - - errcheck - - gosimple - - govet - - ineffassign - - staticcheck - - typecheck - - unused - # Additional linters - asasalint - asciicheck - bidichk - bodyclose - contextcheck + - copyloopvar - dogsled - durationcheck + - errcheck - errname - errorlint - exhaustive - - copyloopvar - forcetypeassert - ginkgolinter - goconst - gocritic - gocyclo - godot - - gofmt - - gofumpt - goheader - - goimports - goprintffuncname - gosec + - govet - importas + - ineffassign - makezero - misspell - nakedret @@ -56,105 +44,137 @@ linters: - reassign - rowserrcheck - sqlclosecheck - - stylecheck + - staticcheck - tagliatelle - - tenv - testableexamples - thelper - tparallel - unconvert - unparam + - unused - usestdlibvars - wastedassign - whitespace - wsl + settings: + goheader: + values: + regexp: + license-year: (202[0-9]|20[3-9][0-9]) + template: |- + Copyright {{license-year}} The Kubernetes Authors. -linters-settings: - goheader: - values: - regexp: - license-year: (202[0-9]|20[3-9][0-9]) - template: |- - Copyright {{license-year}} The Kubernetes Authors. + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - nlreturn: - block-size: 2 - revive: - confidence: 0 + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + importas: + alias: + # Kubernetes + - pkg: k8s.io/api/core/v1 + alias: corev1 + - pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 + alias: apiextensionsv1 + - pkg: k8s.io/apimachinery/pkg/apis/meta/v1 + alias: metav1 + - pkg: k8s.io/apimachinery/pkg/api/errors + alias: apierrors + - pkg: k8s.io/apimachinery/pkg/util/errors + alias: kerrors + - pkg: k8s.io/apimachinery/pkg/util/runtime + alias: utilruntime + # Controller Runtime + - pkg: sigs.k8s.io/controller-runtime + alias: ctrl + # CAPI + - pkg: sigs.k8s.io/cluster-api/api/v1beta1 + alias: clusterv1 + - pkg: sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3 + alias: clusterctlv1 + - pkg: sigs.k8s.io/cluster-api/cmd/clusterctl/client/config + alias: configclient + # CAPI Operator + - pkg: sigs.k8s.io/cluster-api-operator/api/v1alpha1 + alias: operatorv1alpha1 + - pkg: sigs.k8s.io/cluster-api-operator/api/v1alpha2 + alias: operatorv1 + - pkg: sigs.k8s.io/cluster-api-operator/internal/controller + alias: providercontroller + no-unaliased: true + nlreturn: + block-size: 2 + revive: + confidence: 0 + rules: + - name: exported + arguments: + - checkPrivateReceivers + - disableStutteringCheck + severity: warning + disabled: false + staticcheck: + # https://staticcheck.io/docs/options#checks + checks: + - -ST1000 + - -ST1003 + - -ST1016 + - all + dot-import-whitelist: + - github.com/onsi/gomega + exclusions: + generated: lax rules: - - name: exported - severity: warning - disabled: false - arguments: - - "checkPrivateReceivers" - - "disableStutteringCheck" - stylecheck: - # https://staticcheck.io/docs/options#checks - checks: ["all", "-ST1000", "-ST1003", "-ST1016"] - dot-import-whitelist: - - "github.com/onsi/gomega" - importas: - no-unaliased: true - alias: - # Kubernetes - - pkg: k8s.io/api/core/v1 - alias: corev1 - - pkg: k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1 - alias: apiextensionsv1 - - pkg: k8s.io/apimachinery/pkg/apis/meta/v1 - alias: metav1 - - pkg: k8s.io/apimachinery/pkg/api/errors - alias: apierrors - - pkg: k8s.io/apimachinery/pkg/util/errors - alias: kerrors - - pkg: k8s.io/apimachinery/pkg/util/runtime - alias: utilruntime - # Controller Runtime - - pkg: sigs.k8s.io/controller-runtime - alias: ctrl - # CAPI - - pkg: sigs.k8s.io/cluster-api/api/v1beta1 - alias: clusterv1 - - pkg: sigs.k8s.io/cluster-api/cmd/clusterctl/api/v1alpha3 - alias: clusterctlv1 - - pkg: sigs.k8s.io/cluster-api/cmd/clusterctl/client/config - alias: configclient - # CAPI Operator - - pkg: sigs.k8s.io/cluster-api-operator/api/v1alpha1 - alias: operatorv1alpha1 - - pkg: sigs.k8s.io/cluster-api-operator/api/v1alpha2 - alias: operatorv1 - - pkg: sigs.k8s.io/cluster-api-operator/internal/controller - alias: providercontroller -issues: - exclude: - # Not all platforms are supported by this operator, those which aren't - # supported will be caught by the default case in the switches. - - "missing cases in switch of type v1.PlatformType: (\\.*)" - exclude-use-default: false - exclude-files: - - "zz_generated.*\\.go$" - exclude-rules: - - linters: - - staticcheck - text: "SA1019: (\"sigs.k8s.io/controller-runtime/pkg/config/v1alpha1\"|ctrlconfigv1.*) is deprecated: The component config package has been deprecated and will be removed in a future release." - # Exclude some linters from running on tests files. - - path: _test\.go - linters: - - gosec - - path: internal/envtest/environment.go - linters: - - dogsled - - gosec - - wsl + - linters: + - staticcheck + text: 'SA1019: ("sigs.k8s.io/controller-runtime/pkg/config/v1alpha1"|ctrlconfigv1.*) is deprecated: The component config package has been deprecated and will be removed in a future release.' + - linters: + - staticcheck + text: 'ST1016: methods on the same type should have the same receiver name' + path: api/(.+)\.go$ + - linters: + - staticcheck + text: 'ST1003: should not use underscores in Go names;' + path: api/(.+)\.go$ + - linters: + - staticcheck + text: 'QF1008: could remove embedded field' + - linters: + - staticcheck + text: 'ST1000: at least one file in a package should have a package comment' + # Exclude some linters from running on tests files. + - linters: + - gosec + path: _test\.go + - linters: + - dogsled + - gosec + - wsl + path: internal/envtest/environment.go + # Not all platforms are supported by this operator, those which aren't + # supported will be caught by the default case in the switches. + - path: (.+)\.go$ + text: 'missing cases in switch of type v1.PlatformType: (\.*)' + paths: + - zz_generated.*\.go$ + - third_party$ + - builtin$ + - examples$ +formatters: + enable: + - gofmt + - gofumpt + - goimports + exclusions: + generated: lax + paths: + - zz_generated.*\.go$ + - third_party$ + - builtin$ + - examples$ diff --git a/Makefile b/Makefile index 741aff160..dd29592f4 100644 --- a/Makefile +++ b/Makefile @@ -83,7 +83,7 @@ CONTROLLER_GEN_VER := v0.16.1 CONTROLLER_GEN_BIN := controller-gen CONTROLLER_GEN := $(TOOLS_BIN_DIR)/$(CONTROLLER_GEN_BIN)-$(CONTROLLER_GEN_VER) -GOLANGCI_LINT_VER := v1.63.3 +GOLANGCI_LINT_VER := v2.0.2 GOLANGCI_LINT_BIN := golangci-lint GOLANGCI_LINT := $(TOOLS_BIN_DIR)/$(GOLANGCI_LINT_BIN)-$(GOLANGCI_LINT_VER) @@ -235,7 +235,7 @@ $(GOTESTSUM): # Build gotestsum from tools folder. GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) gotest.tools/gotestsum $(GOTESTSUM_BIN) $(GOTESTSUM_VER) $(GOLANGCI_LINT): ## Build golangci-lint from tools folder. - GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) github.com/golangci/golangci-lint/cmd/golangci-lint $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER) + GOBIN=$(TOOLS_BIN_DIR) $(GO_INSTALL) github.com/golangci/golangci-lint/v2/cmd/golangci-lint $(GOLANGCI_LINT_BIN) $(GOLANGCI_LINT_VER) $(HELM): ## Put helm into tools folder. mkdir -p $(TOOLS_BIN_DIR) diff --git a/cmd/plugin/cmd/preload.go b/cmd/plugin/cmd/preload.go index 8bb5315dc..384837b3c 100644 --- a/cmd/plugin/cmd/preload.go +++ b/cmd/plugin/cmd/preload.go @@ -44,7 +44,7 @@ type loadOptions struct { runtimeExtensionProviders []string addonProviders []string targetNamespace string - ociUrl string + ociURL string kubeconfig string existing bool } @@ -119,7 +119,7 @@ func init() { "Add-on providers and versions (e.g. helm:v0.1.0) to add to the management cluster.") loadCmd.Flags().StringVarP(&loadOpts.targetNamespace, "target-namespace", "n", "capi-operator-system", "The target namespace where the operator should be deployed. If unspecified, the 'capi-operator-system' namespace is used.") - loadCmd.Flags().StringVarP(&loadOpts.ociUrl, "artifact-url", "u", "", + loadCmd.Flags().StringVarP(&loadOpts.ociURL, "artifact-url", "u", "", "The URL of the OCI artifact to collect component manifests from.") RootCmd.AddCommand(loadCmd) @@ -128,7 +128,7 @@ func init() { func runPreLoad() error { ctx := context.Background() - if loadOpts.ociUrl == "" { + if loadOpts.ociURL == "" { return fmt.Errorf("missing configMap artifacts url") } @@ -136,7 +136,7 @@ func runPreLoad() error { // Load Core Provider. if loadOpts.coreProvider != "" { - configMap, err := templateConfigMap(ctx, clusterctlv1.CoreProviderType, loadOpts.ociUrl, loadOpts.coreProvider, loadOpts.targetNamespace) + configMap, err := templateConfigMap(ctx, clusterctlv1.CoreProviderType, loadOpts.ociURL, loadOpts.coreProvider, loadOpts.targetNamespace) if err != nil { return fmt.Errorf("cannot prepare manifests config map for core provider: %w", err) @@ -147,7 +147,7 @@ func runPreLoad() error { // Load Bootstrap Providers. for _, bootstrapProvider := range loadOpts.bootstrapProviders { - configMap, err := templateConfigMap(ctx, clusterctlv1.BootstrapProviderType, loadOpts.ociUrl, bootstrapProvider, loadOpts.targetNamespace) + configMap, err := templateConfigMap(ctx, clusterctlv1.BootstrapProviderType, loadOpts.ociURL, bootstrapProvider, loadOpts.targetNamespace) if err != nil { return fmt.Errorf("cannot prepare manifests config map for bootstrap provider: %w", err) } @@ -157,7 +157,7 @@ func runPreLoad() error { // Load Infrastructure Providers. for _, infrastructureProvider := range loadOpts.infrastructureProviders { - configMap, err := templateConfigMap(ctx, clusterctlv1.InfrastructureProviderType, loadOpts.ociUrl, infrastructureProvider, loadOpts.targetNamespace) + configMap, err := templateConfigMap(ctx, clusterctlv1.InfrastructureProviderType, loadOpts.ociURL, infrastructureProvider, loadOpts.targetNamespace) if err != nil { return fmt.Errorf("cannot prepare manifests config map for infrastructure provider: %w", err) } @@ -167,7 +167,7 @@ func runPreLoad() error { // Load Control Plane Providers. for _, controlPlaneProvider := range loadOpts.controlPlaneProviders { - configMap, err := templateConfigMap(ctx, clusterctlv1.ControlPlaneProviderType, loadOpts.ociUrl, controlPlaneProvider, loadOpts.targetNamespace) + configMap, err := templateConfigMap(ctx, clusterctlv1.ControlPlaneProviderType, loadOpts.ociURL, controlPlaneProvider, loadOpts.targetNamespace) if err != nil { return fmt.Errorf("cannot prepare manifests config map for controlplane provider: %w", err) } @@ -177,7 +177,7 @@ func runPreLoad() error { // Load Add-on Providers. for _, addonProvider := range loadOpts.addonProviders { - configMap, err := templateConfigMap(ctx, clusterctlv1.AddonProviderType, loadOpts.ociUrl, addonProvider, loadOpts.targetNamespace) + configMap, err := templateConfigMap(ctx, clusterctlv1.AddonProviderType, loadOpts.ociURL, addonProvider, loadOpts.targetNamespace) if err != nil { return fmt.Errorf("cannot prepare manifests config map for addon provider: %w", err) } @@ -187,7 +187,7 @@ func runPreLoad() error { // Load IPAM Providers. for _, ipamProvider := range loadOpts.ipamProviders { - configMap, err := templateConfigMap(ctx, clusterctlv1.IPAMProviderType, loadOpts.ociUrl, ipamProvider, loadOpts.targetNamespace) + configMap, err := templateConfigMap(ctx, clusterctlv1.IPAMProviderType, loadOpts.ociURL, ipamProvider, loadOpts.targetNamespace) if err != nil { return fmt.Errorf("cannot prepare manifests config map for IPAM provider: %w", err) } @@ -197,7 +197,7 @@ func runPreLoad() error { // Load Runtime Extension Providers. for _, runtimeExtension := range loadOpts.runtimeExtensionProviders { - configMap, err := templateConfigMap(ctx, clusterctlv1.RuntimeExtensionProviderType, loadOpts.ociUrl, runtimeExtension, loadOpts.targetNamespace) + configMap, err := templateConfigMap(ctx, clusterctlv1.RuntimeExtensionProviderType, loadOpts.ociURL, runtimeExtension, loadOpts.targetNamespace) if err != nil { return fmt.Errorf("cannot prepare manifests config map for runtime extension provider: %w", err) } diff --git a/cmd/plugin/cmd/preload_test.go b/cmd/plugin/cmd/preload_test.go index ec9dc5bc7..e2455a677 100644 --- a/cmd/plugin/cmd/preload_test.go +++ b/cmd/plugin/cmd/preload_test.go @@ -42,7 +42,7 @@ type publishProvider struct { } type publishOptions struct { - ociUrl string + ociURL string providers []publishProvider } @@ -62,7 +62,7 @@ func TestPreloadCommand(t *testing.T) { { name: "builtin core provider with OCI override", publishOpts: &publishOptions{ - ociUrl: "ttl.sh/cluster-api-operator-manifests:1m", + ociURL: "ttl.sh/cluster-api-operator-manifests:1m", providers: []publishProvider{{ configMapName: "core-cluster-api-v1.10.0-beta.0", provider: generateGenericProvider(clusterctlv1.CoreProviderType, "cluster-api", "default", "v1.10.0-beta.0", "", ""), @@ -77,7 +77,7 @@ func TestPreloadCommand(t *testing.T) { { name: "multiple providers with OCI override", publishOpts: &publishOptions{ - ociUrl: "ttl.sh/cluster-api-operator-manifests:1m", + ociURL: "ttl.sh/cluster-api-operator-manifests:1m", providers: []publishProvider{{ configMapName: "core-cluster-api-v1.10.0-beta.0", provider: generateGenericProvider(clusterctlv1.CoreProviderType, "cluster-api", "default", "v1.10.0-beta.0", "", ""), @@ -123,7 +123,7 @@ func TestPreloadCommand(t *testing.T) { { name: "OCI override with incorrect metadata key", publishOpts: &publishOptions{ - ociUrl: "ttl.sh/cluster-api-operator-manifests:1m", + ociURL: "ttl.sh/cluster-api-operator-manifests:1m", providers: []publishProvider{{ configMapName: "core-cluster-api-v1.10.0-beta.0", provider: generateGenericProvider(clusterctlv1.InfrastructureProviderType, "metadata-missing", "default", "v1.10.0-beta.0", "", ""), @@ -138,7 +138,7 @@ func TestPreloadCommand(t *testing.T) { { name: "OCI override with incorrect components key", publishOpts: &publishOptions{ - ociUrl: "ttl.sh/cluster-api-operator-manifests:1m", + ociURL: "ttl.sh/cluster-api-operator-manifests:1m", providers: []publishProvider{{ configMapName: "core-cluster-api-v1.10.0-beta.0", provider: generateGenericProvider(clusterctlv1.InfrastructureProviderType, "components-missing", "default", "v1.10.0-beta.0", "", ""), @@ -180,7 +180,7 @@ func TestPreloadCommand(t *testing.T) { g.Expect(err).To(Succeed()) opts := cmp.Or(tt.publishOpts, &publishOptions{}) - if tt.publishOpts != nil && opts.ociUrl != "" { + if tt.publishOpts != nil && opts.ociURL != "" { for _, provider := range opts.providers { err = os.WriteFile(path.Join(dir, provider.metadataKey), provider.metadataData, 0o777) g.Expect(err).To(Succeed()) @@ -188,13 +188,13 @@ func TestPreloadCommand(t *testing.T) { g.Expect(err).To(Succeed()) } - g.Expect(publish(ctx, dir, opts.ociUrl)).To(Succeed()) + g.Expect(publish(ctx, dir, opts.ociURL)).To(Succeed()) for _, data := range opts.providers { spec := data.provider.GetSpec() spec.FetchConfig = &operatorv1.FetchConfiguration{ OCIConfiguration: operatorv1.OCIConfiguration{ - OCI: opts.ociUrl, + OCI: opts.ociURL, }, } data.provider.SetSpec(spec) diff --git a/cmd/plugin/cmd/publish.go b/cmd/plugin/cmd/publish.go index 82a42b858..a6710a7e4 100644 --- a/cmd/plugin/cmd/publish.go +++ b/cmd/plugin/cmd/publish.go @@ -32,7 +32,7 @@ import ( ) type publishManifestsOptions struct { - ociUrl string + ociURL string dir string files []string } @@ -62,7 +62,7 @@ var publishCmd = &cobra.Command{ func init() { publishCmd.PersistentFlags().StringVarP(&publishOpts.dir, "dir", "d", ".", `Directory with provider manifests`) publishCmd.PersistentFlags().StringSliceVarP(&publishOpts.files, "file", "f", []string{}, `Provider manifes file`) - publishCmd.Flags().StringVarP(&publishOpts.ociUrl, "artifact-url", "u", "", + publishCmd.Flags().StringVarP(&publishOpts.ociURL, "artifact-url", "u", "", "The URL of the OCI artifact to collect component manifests from.") RootCmd.AddCommand(publishCmd) @@ -71,10 +71,10 @@ func init() { func runPublish() (err error) { ctx := context.Background() - return publish(ctx, publishOpts.dir, publishOpts.ociUrl, publishOpts.files...) + return publish(ctx, publishOpts.dir, publishOpts.ociURL, publishOpts.files...) } -func publish(ctx context.Context, dir, ociUrl string, files ...string) error { +func publish(ctx context.Context, dir, ociURL string, files ...string) error { // 0. Create a file store fs, err := file.New(dir) if err != nil { @@ -133,16 +133,16 @@ func publish(ctx context.Context, dir, ociUrl string, files ...string) error { fmt.Println("Packaged manifests") - ociUrl, plainHTTP := strings.CutPrefix(ociUrl, "http://") + ociURL, plainHTTP := strings.CutPrefix(ociURL, "http://") version := "" - if parts := strings.SplitN(ociUrl, ":", 3); len(parts) == 2 { - ociUrl = parts[0] + if parts := strings.SplitN(ociURL, ":", 3); len(parts) == 2 { + ociURL = parts[0] version = parts[1] } else if len(parts) == 3 { version = parts[2] - ociUrl, _ = strings.CutSuffix(ociUrl, version) + ociURL, _ = strings.CutSuffix(ociURL, version) } if err = fs.Tag(ctx, manifestDescriptor, version); err != nil { @@ -150,9 +150,9 @@ func publish(ctx context.Context, dir, ociUrl string, files ...string) error { } // 3. Connect to a remote repository - reg := strings.Split(ociUrl, "/")[0] + reg := strings.Split(ociURL, "/")[0] - repo, err := remote.NewRepository(ociUrl) + repo, err := remote.NewRepository(ociURL) if err != nil { return err } diff --git a/test/framework/all_type_helpers.go b/test/framework/all_type_helpers.go index 456fd07a3..f38304509 100644 --- a/test/framework/all_type_helpers.go +++ b/test/framework/all_type_helpers.go @@ -24,7 +24,7 @@ import ( "os/exec" "strings" - . "github.com/onsi/ginkgo/v2" //nolint:stylecheck + . "github.com/onsi/ginkgo/v2" //nolint:staticcheck . "github.com/onsi/gomega" apierrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/klog/v2" diff --git a/test/framework/conditions.go b/test/framework/conditions.go index 312b8f805..43988504a 100644 --- a/test/framework/conditions.go +++ b/test/framework/conditions.go @@ -21,7 +21,7 @@ package framework import ( "fmt" - . "github.com/onsi/ginkgo/v2" //nolint:stylecheck + . "github.com/onsi/ginkgo/v2" //nolint:staticcheck clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" capiconditions "sigs.k8s.io/cluster-api/util/conditions" )