Files
2026-10-21 12:23:00 +00:00

802 lines
47 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# golangci-lint is used in Kubernetes with different configurations that
# enable an increasing amount of checks:
# - golangci.yaml is the most permissive configuration. All existing code
# passed.
# - golangci-hints.yaml adds checks for code patterns where developer
# and reviewer may decide whether findings should get addressed before
# merging. Beware that the golangci-lint output includes also the
# issues that must be fixed and doesn't indicate how severe each issue
# is (https://gophers.slack.com/archives/CS0TBRKPC/p1685721815275349).
#
# All three flavors are generated from golangci.yaml.in with
# hack/update-golangci-lint-config.sh.
run:
timeout: 30m
# The default is relative to the configuration, which is confusing because
# then all paths start with ../ to move out of the "hack" directory.
# `gomod` mirrors the current behavior of `golangci-lint.sh` changing into
# the root of the repository. Because we are operating in a workspace,
# the module picked by `gomod` is the main one
relative-path-mode: gomod
version: "2"
formatters:
exclusions:
paths:
- third_party
output:
formats:
text:
path: stderr
issues:
max-issues-per-linter: 0
max-same-issues: 0
linters:
exclusions:
paths:
- third_party
# Log a warning if an exclusion rule is unused.
#
# Uncomment when investigating whether the configuration can be simplified,
# but beware that golangci-lint then needs to be invoked for the entire
# repository. Invoking it for individual packages may trigger these warning
# when the rules are only needed elsewhere.
#
# warn-unused: true
# Excluding configuration per-path, per-linter, per-text and per-source.
rules:
# hack/testdata/golangci-lint contains test cases which intentionally
# trigger linter issues. Ignored during normal linting, checked during
# `go test ./test/integration/golangci-lint`.
- path: hack/testdata/golangci-lint/
text: .
# https://github.com/kubernetes/kubernetes/issues/117288#issuecomment-1507012435
- linters:
- gocritic
text: "ifElseChain: rewrite if-else to switch statement"
# The CRD "deprecated" field documents itself; gocritic reads "deprecated in..." as a malformed notice.
- linters:
- gocritic
text: "deprecatedComment:"
source: "// deprecated indicates this version of the custom resource API is deprecated"
# Only packages listed here opt into the strict "exported symbols must be documented".
#
# Exclude texts from https://github.com/golangci/golangci-lint/blob/ab3c3cd69e602ff53bb4c3e2c188f0caeb80305d/pkg/config/issues.go#L11-L103
- linters:
- revive
- staticcheck
text: comment on exported (method|function|type|const)|should have( a package)? comment|comment should be of the form|comment on exported (method|function|type|const)|should have( a package)? comment|comment should be of the form|exported (.+) should have comment( \(or a comment on this block\))? or be unexported|package comment should be of the form "(.+)...|comment on exported (.+) should be of the form "(.+)...|should have a package comment
path-except: cmd/kubeadm
# SSA Extract calls are allowed in tests.
- linters:
- forbidigo
text: should not be used because managedFields was removed
path: _test.go$
# Adding unversioned feature gates is allowed in tests
- linters:
- forbidigo
text: should not use Add, use AddVersioned instead
path: _test.go$
# Tests can and have to use testing.T.
#
# Test helper packages like ktesting are also exempt:
# this is rather broad because there are several normal
# packages which implement tests via t.Run. We need to
# be careful here to not exclude the top-level test directory
# because test helper code should not depend on testing.T
# unnecessarily (limits usability).
- linters:
- forbidigo
text: should not depend on the testing package
path: /([^/]*testing|[^/]*test|test[^/]*)/|test/declarative_validation/|_test.go$
# The Kubernetes naming convention for conversion functions uses underscores
# and intentionally deviates from normal Go conventions to make those function
# names more readable. Same for SetDefaults_* and ValidateCustom_*.
#
# https://github.com/kubernetes/kubernetes/issues/117288#issuecomment-1507028627
# https://github.com/kubernetes/kubernetes/issues/117288#issuecomment-1514201592
- linters:
- staticcheck
- revive
text: "(ST1003: should not use underscores in Go names; func ([cC]onvert_.*_To_.*|[sS]etDefaults_|ValidateCustom_)|exported: exported function (Convert|SetDefaults|ValidateCustom)_.* should be of the form)"
# The generated swagger docs also don't follow the naming convention.
- linters:
- staticcheck
text: "ST1003: should not use underscores in Go names"
path: types_swagger_doc_generated.go$
# TODO(https://github.com/kubernetes/kubernetes/issues/131475): Remove these excluded directories and fix findings. Due to large amount of findings in different components
# with different owners it's hard to fix everything in a single pr. This will therefore be done in multiple prs.
- path: (pkg/volume/*|test/*|azure/*|pkg/cmd/wait*|request/bearertoken/*|metrics/*|filters/*)
linters:
- gocritic
- linters:
- govet
# This could be fixed automatically via `go fix`, but isn't worth a tree-wide PR.
# The check remains enabled for other future inline opportunities where that decision
# might turn out differently.
text: "Call of \\(resource.Quantity\\).DeepCopy should be inlined"
# Some of these seem legitimate, maybe better fix code (https://github.com/kubernetes/kubernetes/issues/130449).
- linters:
- govet
text: "lostcancel"
- linters:
- ginkgolinter
text: "wrong error assertion. Consider using `gomega.(Eventually|Consistently)|wrong comparison assertion|wrong length assertion"
- linters:
- ginkgolinter
text: "Success matcher only support a single error value, or function with Gomega as its first parameter"
- linters:
- gocritic
text: "wrapperFunc: use strings.ReplaceAll|should rewrite switch statement to if statement"
# Kube-API-Linter should only be run on the API definitions
- linters:
- kubeapilinter
path-except: staging/src/k8s.io/api/.*
# Exceptions for kube-api-linter.
# Exceptions are used for kube-api-linter to ignore existing issues that cannot be fixed without breaking changes.
# Pre-existing issues from the conditions linter
# Conditions generally should be a metav1.Condition, and should not use custom condition types.
- text: "Conditions field in StorageVersionStatus|StatefulSetStatus|DeploymentStatus|DaemonSetStatus|ReplicaSetStatus|HorizontalPodAutoscalerStatus|JobStatus|CertificateSigningRequestStatus|PersistentVolumeClaimStatus|ReplicationControllerStatus|ServiceStatus|NodeStatus|NamespaceStatus|ComponentStatus|PodStatus|FlowSchemaStatus|PriorityLevelConfigurationStatus|FlowSchemaStatus|PriorityLevelConfigurationStatus|PodDisruptionBudgetStatus|AllocatedDeviceStatus|Endpoint|StatefulSetStatus|DeploymentStatus|DaemonSetStatus|ReplicaSetStatus|HorizontalPodAutoscalerStatus|JobStatus|CertificateSigningRequestStatus|PersistentVolumeClaimStatus|ReplicationControllerStatus|ServiceStatus|NodeStatus|NamespaceStatus|ComponentStatus|PodStatus|FlowSchemaStatus|PriorityLevelConfigurationStatus|FlowSchemaStatus|PriorityLevelConfigurationStatus|PodDisruptionBudgetStatus|AllocatedDeviceStatus|Endpoint|StorageVersionMigrationStatus must be a slice of metav1.Condition"
path: "staging/src/k8s.io/api/"
# Conditions should have patch strategy markers, but changing these after shipping a client is a breaking change.
# Clients would treat these as atomic, when the patch strategy should be merge.
- text: "Conditions field in ValidatingAdmissionPolicyStatus is missing the following markers: patchStrategy=merge, patchMergeKey=type"
path: "staging/src/k8s.io/api/admissionregistration/"
- text: "Conditions field in ValidatingAdmissionPolicyStatus has incorrect tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,3,rep,name=conditions\"`"
path: "staging/src/k8s.io/api/admissionregistration/"
- text: "Conditions field in PodDisruptionBudgetStatus has incorrect tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`"
path: "staging/src/k8s.io/api/policy/"
- text: "Conditions field in AllocatedDeviceStatus is missing the following markers: patchStrategy=merge, patchMergeKey=type"
path: "staging/src/k8s.io/api/resource/"
- text: "Conditions field in AllocatedDeviceStatus has incorrect tags, should be: `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,5,rep,name=conditions\"`"
path: "staging/src/k8s.io/api/resource/"
# notimestamp: Legacy 'Timestamp' fields retained for backward compatibility
- text: 'notimestamp: naming convention "notimestamp": field TokenRequestStatus.ExpirationTimestamp: prefer use of the term ''time'' over ''timestamp'''
path: "staging/src/k8s.io/api/authentication/v1/types.go"
- text: 'notimestamp: naming convention "notimestamp": field (PodLogOptions.Timestamps|Event.FirstTimestamp|Event.LastTimestamp): prefer use of the term ''time'' over ''timestamp'''
path: "staging/src/k8s.io/api/core/v1/types.go"
- text: 'notimestamp: naming convention "notimestamp": field Event.Deprecated(FirstTimestamp|LastTimestamp): prefer use of the term ''time'' over ''timestamp'''
path: "staging/src/k8s.io/api/events/(v1|v1beta1)/types.go"
- text: 'notimestamp: naming convention "notimestamp": field AllocationResult.AllocationTimestamp: prefer use of the term ''time'' over ''timestamp'''
path: "staging/src/k8s.io/api/resource/(v1|v1beta1|v1beta2)/types.go"
# optionalfields - Ignore optionalfields issues for existing API group
# TODO: For each existing API group, we aim to remove it over time.
- text: "optionalfields: field .* should (?:be a pointer|have the omitempty tag)\\."
path: "staging/src/k8s.io/api/(admission|admissionregistration|apidiscovery|apps|authentication|authorization|autoscaling|batch|certificates|core|events|extensions|flowcontrol|imagepolicy|networking|policy|rbac|resource|scheduling|storage)"
# optionalfields - Ignore existing issues for node API group
- text: "optionalfields: field RuntimeClass.Handler should be a pointer."
path: "staging/src/k8s.io/api/node/(v1|v1beta1)/types.go"
# optionalfields - Ignore existing issues for apiserverinternal API group
- text: "optionalfields: field StorageVersionCondition.(ObservedGeneration|LastTransitionTime) should be a pointer."
path: "staging/src/k8s.io/api/apiserverinternal/v1alpha1/types.go"
- text: "optionalfields: field StorageVersion.(Spec|Status) should (?:be a pointer|have the omitempty tag)\\."
path: "staging/src/k8s.io/api/apiserverinternal/v1alpha1/types.go"
# optionalfields - Ignore existing issues for coordination API group
- text: "optionalfields: field Lease.Spec should be a pointer."
path: "staging/src/k8s.io/api/coordination/(v1|v1beta1)/types.go"
- text: "optionalfields: field LeaseCandidateSpec.EmulationVersion should be a pointer."
path: "staging/src/k8s.io/api/coordination/(v1beta1|v1alpha2)/types.go"
# Pre-existing issues from the conflictmarkers linter
# The Error field in some older API types is marked as both optional and required.
# This is incorrect, but cannot be changed without breaking changes.
- text: "field PortStatus.Error has conflicting markers: optional_vs_required: {\\[optional\\], \\[kubebuilder:validation:Required\\]}. fields cannot be both optional and required"
path: "staging/src/k8s.io/api/core/v1/types.go"
- text: "field IngressPortStatus.Error has conflicting markers: optional_vs_required: {\\[optional\\], \\[kubebuilder:validation:Required\\]}. fields cannot be both optional and required"
path: "staging/src/k8s.io/api/extensions/v1beta1/types.go"
- text: "field IngressPortStatus.Error has conflicting markers: optional_vs_required: {\\[optional\\], \\[kubebuilder:validation:Required\\]}. fields cannot be both optional and required"
path: "staging/src/k8s.io/api/networking/v1/types.go"
- text: "field IngressPortStatus.Error has conflicting markers: optional_vs_required: {\\[optional\\], \\[kubebuilder:validation:Required\\]}. fields cannot be both optional and required"
path: "staging/src/k8s.io/api/networking/v1beta1/types.go"
# The following exceptions are for fields in stable or deprecated APIs that cannot be
# changed due to backward compatibility constraints. Each rule is scoped to the
# specific field to avoid hiding new violations.
## For the "Extra" field, which is common across several auth-related APIs.
- text: "field UserInfo.Extra should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/authentication/(v1|v1beta1)/types.go"
- text: "field SubjectAccessReviewSpec.Extra should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/authorization/(v1|v1beta1)/types.go"
- text: "field CertificateSigningRequestSpec.Extra should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/certificates/(v1|v1beta1)/types.go"
## For ResourceList fields in the core API.
- text: "field (PersistentVolumeSpec.Capacity|ContainerStatus.AllocatedResources|PodSpec.Overhead|ResourceQuotaSpec.Hard) type ResourceList should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/core/v1/types.go"
- text: "field (ResourceRequirements|VolumeResourceRequirements).(Limits|Requests) type ResourceList should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/core/v1/types.go"
- text: "field LimitRangeItem.(Max|Min|Default|DefaultRequest|MaxLimitRequestRatio) type ResourceList should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/core/v1/types.go"
- text: "field ResourceQuotaStatus.(Hard|Used) type ResourceList should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/core/v1/types.go"
- text: "type ResourceList should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/core/v1/types.go"
## For the Secret.Data and ConfigMap.BinaryData fields in the core API.
- text: "field (Secret.Data|ConfigMap.BinaryData) should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/core/v1/types.go"
## For map fields in the resource API (across all versions).
- text: "field (CounterSet|CounterSetStatus|DeviceCounterConsumption).Counters should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/resource/(v1|v1alpha3|v1beta1|v1beta2)/types.go"
- text: "field BasicDevice.(Attributes|Capacity) should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/resource/v1beta1/types.go"
- text: "field Device.(Attributes|Capacity) should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/resource/(v1|v1beta2)/types.go"
- text: "field (CapacityRequirements.Requests|DeviceRequestAllocationResult.ConsumedCapacity) should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/resource/(v1|v1beta1|v1beta2)/types.go"
- text: "nomaps: field Device.NodeAllocatableResources should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/resource/(v1|v1beta2)/types.go"
- text: "nomaps: field BasicDevice.NodeAllocatableResources should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/resource/v1beta1/types.go"
- text: "nomaps: field TokenRequestSpec.Attestations should not use a map type, use a list type with a unique name/identifier instead"
path: "staging/src/k8s.io/api/authentication/v1/types.go"
# OptionalOrRequired is being enabled over time. For now, each API group should be added to this list until we comb through each group and fix the missing tags.
# The nonpointerstructs linter is included here as well as these two should be enabled hand-in-hand on each API group.
- text: "must be marked as optional or required|is a non-pointer struct with no required fields."
path: "staging/src/k8s.io/api/(admissionregistration|certificates|core|extensions)"
# nonpointerstructs/optionalorrequired - IngressBackend and ServiceBackendPort are "oneOf"-shaped
# structs (validation requires exactly one of Resource/Service, or Name/Number, to be set) but
# neither individual field is itself marked required, so the linter can't see the real cross-field
# constraint and would force the container to be marked +optional - which is misleading, since an
# empty value does fail validation. Suppressing rather than mismarking (per danwinship's review on
# #141944).
- text: "field HTTPIngressPath.Backend (is a non-pointer struct with no required fields. It must be marked as optional.|must be marked as optional or required)"
path: "staging/src/k8s.io/api/networking/"
- text: "field IngressServiceBackend.Port (is a non-pointer struct with no required fields. It must be marked as optional.|must be marked as optional or required)"
path: "staging/src/k8s.io/api/networking/v1/types.go"
# OptionalOrRequired - Existing fields that are marked as both optional and required (based on standard optional vs kubebuilder:validation:Required) and should not be fixed.
- text: "field (PortStatus|IngressPortStatus)\\.Error must not be marked as both optional and required"
path: "staging/src/k8s.io/api/(core/v1|extensions/v1beta1|networking/(v1|v1beta1))"
# jsontags: 'Port' must be capitalized for backward compatibility
- text: 'jsontags: field DaemonEndpoint.Port json tag does not match'
path: "staging/src/k8s.io/api/core/v1/types.go"
# NonPointerStructs - Existing fields that are non-pointer structs but where the current rules are incorrect.
# The (PodGroupSpec|PodGroupTemplate|CompositePodGroupSpec|CompositePodGroupTemplate).SchedulingPolicy field is a union type, but nonpointerstructs does not understand unions today.
# Validation makes this require at least one of the fields within to be set.
- text: "nonpointerstructs: field (PodGroupSpec|PodGroupTemplate|CompositePodGroupSpec|CompositePodGroupTemplate)\\.SchedulingPolicy is a non-pointer struct with no required fields\\..*"
path: "staging/src/k8s.io/api/scheduling/(v1alpha3|v1beta1)/types\\.go"
# Workload.Spec no longer has any strictly required fields due to the introduction of the
# CompositePodGroup API. The template fields have been refactored into a union where either
# podGroupTemplates or compositePodGroupTemplates must be provided (enforced via validation).
- text: "nonpointerstructs: field Workload\\.Spec is a non-pointer struct with no required fields\\..*"
path: "staging/src/k8s.io/api/scheduling/(v1alpha3|v1beta1)/types\\.go"
# WorkloadSpec.CompositePodGroupTemplates is a union member that is conditionally optional (+k8s:ifEnabled("CompositePodGroup")=+k8s:optional), but the linter requires a static +k8s:optional tag.
- text: "dependenttags: field WorkloadSpec\\.CompositePodGroupTemplates with marker \\+k8s:unionMember is missing required marker.*"
path: "staging/src/k8s.io/api/scheduling/(v1alpha3|v1beta1)/types\\.go"
# The (SubjectAccessReview|SelfSubjectAccessReview|LocalSubjectAccessReview).Spec fields hold a union type, but nonpointerstructs does not understand unions today.
# Validation requires exactly one of spec.resourceAttributes or spec.nonResourceAttributes, so an empty spec is always rejected and the field is required in practice.
- text: "nonpointerstructs: field (SubjectAccessReview|SelfSubjectAccessReview|LocalSubjectAccessReview)\\.Spec is a non-pointer struct with no required fields\\..*"
path: "staging/src/k8s.io/api/authorization/(v1|v1beta1)/types\\.go"
# NoReferences - Existing fields that use Reference/References suffixes instead of Ref/Refs.
# These fields use the Reference suffix, but renaming them would be a breaking change, so they are allowlisted.
- text: 'noreferences: naming convention "reference-to-ref": field (SerializedReference|ImageVolumeSource)\.Reference:'
path: "staging/src/k8s.io/api/core/v1/types.go"
# The EvictionRequest.Spec.Target and Eviction.Spec.Target fields are of a union type and nonpointerstructs does not understand unions today.
# Validation makes this require at least one of the fields within to be set.
- text: "nonpointerstructs: field EvictionRequestSpec.Target is a non-pointer struct with no required fields."
path: "staging/src/k8s.io/api/lifecycle/v1alpha1/types.go"
- text: "nonpointerstructs: field EvictionSpec.Target is a non-pointer struct with no required fields."
path: "staging/src/k8s.io/api/lifecycle/v1alpha1/types.go"
# Status is conventionally a non-pointer.
- text: "optionalfields: field EvictionRequest.Status should be a pointer."
path: "staging/src/k8s.io/api/lifecycle/v1alpha1/types.go"
- text: "optionalfields: field Eviction.Status should be a pointer."
path: "staging/src/k8s.io/api/lifecycle/v1alpha1/types.go"
# VolumeAttachmentSpec.Source is a union type. Validation requires one of its child fields to be set,
# but nonpointerstructs does not understand that invariant.
- text: "nonpointerstructs: field VolumeAttachmentSpec.Source is a non-pointer struct with no required fields."
path: "staging/src/k8s.io/api/storage/(v1|v1alpha1|v1beta1)/types.go"
# Scale.Status must remain optional to preserve existing API semantics, while ScaleStatus.Replicas
# remains required to preserve client-side validation behavior.
- text: "nonpointerstructs: field Scale.Status is a non-pointer struct with required fields. It must be marked as required."
path: "staging/src/k8s.io/api/autoscaling/v1/types.go"
# These status fields are non-pointer structs whose inner fields are required, but the status structs themselves
# have no validation, so the fields must be marked optional rather than required.
- text: "nonpointerstructs: field ObjectMetricStatus.Target is a non-pointer struct with required fields. It must be marked as required."
path: "staging/src/k8s.io/api/autoscaling/v1/types.go"
- text: "nonpointerstructs: field ObjectMetricStatus.(Metric|DescribedObject) is a non-pointer struct with required fields. It must be marked as required."
path: "staging/src/k8s.io/api/autoscaling/v2/types.go"
- text: "nonpointerstructs: field PodsMetricStatus.Metric is a non-pointer struct with required fields. It must be marked as required."
path: "staging/src/k8s.io/api/autoscaling/v2/types.go"
- text: "nonpointerstructs: field ExternalMetricStatus.Metric is a non-pointer struct with required fields. It must be marked as required."
path: "staging/src/k8s.io/api/autoscaling/v2/types.go"
- linters:
- forbidigo
path: test/e2e/e2e_test\.go|test/e2e/framework/internal/.*|test/e2e/framework/[^/]*\.go|test/e2e/invariants/.*
default: none
enable: # Please keep this alphabetized. Add positive and (where appropriate) negative test cases to hack/testdata/golangci-lint/golangcilint.go
- depguard
- forbidigo
- ginkgolinter
- gocritic
- govet
- ineffassign
- kubeapilinter
- logcheck
- modernize
- revive
- sorted
- staticcheck
- testifylint
- unused
settings: # please keep this alphabetized
custom:
logcheck:
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: structured logging checker
original-url: k8s.io/logtools/logcheck
settings:
config: |
# hack/logcheck.conf contains regular expressions that are matched against <pkg>/<file>,
# for example k8s.io/cmd/kube-scheduler/app/config/config.go.
#
# By default, structured logging call parameters are checked, but usage of
# those calls is not required. That is changed on a per-file basis.
#
# Remember to clean the golangci-lint cache when changing the configuration and
# running the verify-golangci-lint.sh script multiple times, otherwise
# golangci-lint will report stale results:
# _output/local/bin/golangci-lint cache clean
# At this point we don't enforce the usage structured logging calls except in
# those packages that were migrated. This disables the check for other files.
-structured .*
# Now enable it again for migrated packages.
structured k8s.io/kubernetes/pkg/kubelet/.*
structured k8s.io/kubernetes/pkg/proxy/.*
structured k8s.io/kms/.*
structured k8s.io/apiserver/pkg/storage/value/.*
structured k8s.io/apiserver/pkg/server/options/encryptionconfig/.*
structured k8s.io/kubernetes/pkg/credentialprovider/plugin/.*
# The following packages have been migrated to contextual logging.
# Packages matched here do not have to be listed above because
# "contextual" implies "structured".
contextual k8s.io/api/.*
contextual k8s.io/apimachinery/.*
contextual k8s.io/client-go/.*
contextual k8s.io/component-base/featuregate/*
contextual k8s.io/component-helpers/.*
contextual k8s.io/cri-api/.*
contextual k8s.io/cri-client/.*
contextual k8s.io/csi-translation-lib/.*
contextual k8s.io/dynamic-resource-allocation/.*
contextual k8s.io/endpointslice/.*
contextual k8s.io/kms/.*
contextual k8s.io/kube-controller-manager/.*
contextual k8s.io/kube-proxy/.*
contextual k8s.io/kube-scheduler/.*
contextual k8s.io/sample-apiserver/.*
contextual k8s.io/sample-cli-plugin/.*
contextual k8s.io/sample-controller/.*
contextual k8s.io/kubernetes/cmd/kube-apiserver/.*
contextual k8s.io/kubernetes/cmd/kube-controller-manager/.*
contextual k8s.io/kubernetes/cmd/kube-proxy/.*
contextual k8s.io/kubernetes/cmd/kube-scheduler/.*
contextual k8s.io/kubernetes/cmd/kubelet/.*
contextual k8s.io/kubernetes/pkg/api/.*
contextual k8s.io/kubernetes/pkg/apis/.*
contextual k8s.io/kubernetes/pkg/capabilities/.*
contextual k8s.io/kubernetes/pkg/client/.*
contextual k8s.io/kubernetes/pkg/cluster/.*
contextual k8s.io/kubernetes/pkg/controller/.*
contextual k8s.io/kubernetes/pkg/features/.*
contextual k8s.io/kubernetes/pkg/fieldpath/.*
contextual k8s.io/kubernetes/pkg/generated/.*
contextual k8s.io/kubernetes/pkg/printers/.*
contextual k8s.io/kubernetes/pkg/quota/.*
contextual k8s.io/kubernetes/pkg/scheduler/.*
contextual k8s.io/kubernetes/pkg/security/.*
contextual k8s.io/kubernetes/pkg/securitycontext/.*
contextual k8s.io/kubernetes/test/e2e/dra/.*
contextual k8s.io/kubernetes/test/images/sample-device-plugin/.*
contextual k8s.io/kubernetes/pkg/kubelet/.*
# https://github.com/kubernetes/kubernetes/pull/129336 pending,
# unclear whether it'll ever get merged (more discussion around
# API design needed).
-contextual k8s.io/client-go/plugin/pkg/client/auth/.*
sorted:
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: check if feature gates are sorted
original-url: k8s.io/kubernetes/hack/tools/golangci-lint/sorted
settings:
files:
- cmd/kubeadm/app/features/features.go
- pkg/features/kube_features.go
- staging/src/k8s.io/apiserver/pkg/features/kube_features.go
- staging/src/k8s.io/client-go/features/known_features.go
- staging/src/k8s.io/controller-manager/pkg/features/kube_features.go
- staging/src/k8s.io/apiextensions-apiserver/pkg/features/kube_features.go
- test/e2e/feature/feature.go
- test/e2e/environment/environment.go
kubeapilinter:
# hack/tools/golangci-lint/main.go compiles this linter into golangci-lint.
type: module
description: kube-api-linter and lints Kube like APIs based on API conventions and best practices.
original-url: sigs.k8s.io/kube-api-linter
settings:
linters:
disable:
- '*'
enable:
- "commentstart" # Ensure comments start with the serialized version of the field name.
- "conditions" # Ensure conditions have the correct json tags and markers.
- "conflictingmarkers" # Detect mutually exclusive markers on the same field.
- "defaultorrequired" # Prevent the usage of default tags with required fields.
- "integers" # Ensure only int32 and int64 are used for integers.
- "jsontags" # Ensure every field has a json tag.
# - "maxlength" # Ensure all strings and arrays have maximum lengths/maximum items. ONLY for CRDs until declarative markers exist in core types.
# - "nobools" # Bools do not evolve over time, should use enums instead.
# - "nofloats" # Ensure floats are not used.
- "nomaps" # Ensure maps are not used, unless they are `map[string]string` (for labels/annotations/etc).
- "nonpointerstructs" # Ensure non-pointer structs are correctly tagged as optional or required.
- "nonullable" # Ensure fields are not marked as nullable.
# - "nophase" # Ensure field names do not have the word "phase" in them.
- "notimestamp" # Ensure fields are not named "timestamp", prefer "time".
- "optionalfields" # Ensure fields marked optional have omitempty and pointers.
- "optionalorrequired" # Every field should be marked as `+optional` xor `+required`.
# - "requiredfields" # Required fields should only be pointers when required based on the validity of the zero value, they should always have `omitempty`.
- "ssatags" # Ensure lists have a listType tag.
- "uniquemarkers" # Ensure markers are not duplicated across field and type definitions.
- "duplicatemarkers" #Prevent identical markers from being present on types and fields
- "dependenttags" # Ensure markers dependent on other markers are present.
- "nodurations" # Ensure duration types are not used.
- "noreferences" # Ensure field names use Ref/Refs suffixes instead of Reference/References.
lintersConfig:
conditions:
isFirstField: Ignore
usePatchStrategy: SuggestFix
useProtobuf: SuggestFix
conflictingmarkers:
conflicts:
- name: "optional_vs_required"
sets:
- ["k8s:optional", "optional", "kubebuilder:validation:Optional"]
- ["k8s:required", "required", "kubebuilder:validation:Required"]
description: "fields cannot be both optional and required"
dependenttags:
rules:
- identifier: "k8s:unionMember"
type: "All"
dependsOn:
- "k8s:optional"
# jsonTags:
# jsonTagRegex: "^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$" # The default regex is appropriate for our use case.
# nomaps:
# policy: AllowStringToStringMaps # Determines how the linter should handle maps of basic types. Maps of objects are always disallowed.
optionalFields:
pointers:
preference: Always # Whether to always require pointers, or only when required. Defaults to `Always`.
policy: SuggestFix # The policy for pointers in optional fields. Defaults to `SuggestFix`.
omitempty:
policy: SuggestFix # The policy for omitempty in optional fields. Defaults to `SuggestFix`.
omitzero:
policy: Forbid # The policy for omitzero in optional fields. Defaults to `SuggestFix`.
# optionalOrRequired:
# preferredOptionalMarker: optional # The preferred optional marker to use, fixes will suggest to use this marker. Defaults to `optional`.
# preferredRequiredMarker: required # The preferred required marker to use, fixes will suggest to use this marker. Defaults to `required`.
# requiredFields:
# pointers:
# policy: SuggestFix | Warn # The policy for pointers in required fields. Defaults to `SuggestFix`.
# omitempty:
# policy: SuggestFix | Warn | Ignore # The policy for omitempty in required fields. Defaults to `SuggestFix`.
# omitzero:
# policy: SuggestFix | Warn | Forbid # The policy for omitzero in required fields. Defaults to `SuggestFix`.
ssatags:
listTypeSetUsage: Warn
# uniquemarkers:
# customMarkers:
# - identifier: custom:SomeCustomMarker
# attributes:
# - fruit
depguard:
rules:
utils:
files:
- $all
deny:
- pkg: "k8s.io/utils/pointer"
desc: "k8s.io/utils/pointer shall no longer be used, please use k8s.io/utils/ptr."
test-only-dependencies:
files:
# Apply deny list to all files except for _test.go files.
- $all
- "!$test"
# Some normal packages are meant to be used only in tests and thus
# are also exempt.
- "!**/test/**"
- "!**/*testing/**"
deny:
- pkg: "github.com/google/go-cmp/cmp"
desc: "cmp is allowed only in test files"
- pkg: "html/template"
desc: "template is allowed only in test files as it disables dead code elimination"
- pkg: "k8s.io/ktesting"
desc: "ktesting is allowed only in test files"
- pkg: "k8s.io/client-go/ktesting"
desc: "ktesting is allowed only in test files"
# Normal packages exempted above also must not be used in production code.
# depguard wants a prefix here, so we would need to list packages explicitly
# instead of using wildcards as above.
#
# This only covers one level of indirection, though.
# A better solution might be transitive deny (https://github.com/OpenPeeDeeP/depguard/issues/68).
forbidigo:
analyze-types: true
forbid:
- pattern: \.AnnotatedEventf$
# https://github.com/kubernetes/kubernetes/pull/137270
msg: "Do not use AnnotatedEventf. Events are fire-and-forget and aggressively throttled; do not rely on them to pass state or metadata for programmatic triggers."
- pattern: md5\.*
# https://github.com/kubernetes/kubernetes/issues/129652
msg: md5 is oudated, insecure, prefer a secure hash (such as sha256) or a non-cryptographic hash
- pattern: ^managedfields\.ExtractInto$
pkg: ^k8s\.io/apimachinery/pkg/util/managedfields$
msg: should not be used because managedFields was removed
- pattern: \.Extract
pkg: ^k8s\.io/client-go/applyconfigurations/
msg: should not be used because managedFields was removed
- pattern: \.Add$
pkg: ^k8s\.io/component-base/featuregate$
msg: should not use Add, use AddVersioned instead
- pattern: \.(ReportBeforeSuite|ReportAfterSuite)
pkg: ^github\.com/onsi/ginkgo/v2$
msg: usage is restricted to code under control of SIG Testing
# Exceptions are listed above under rules.
- pattern: \.(T|TB)$
pkg: ^testing$
msg: Production code should not depend on the testing package. Helper packages should be more flexible and support other implementations like ktesting.TContext. Replace with a locally-defined interface or some pre-defined one like test/utils.TB or ktesting.TB. Choose based on the context and which dependencies are acceptable.
# Exceptions are listed above under rules.
# testing.B is not checked because there are some (rare) valid usages and it's less common anyway, so we don't need to enforce anything.
gocritic:
enabled-checks: # These are in addition to the default checks - see https://golangci-lint.run/docs/linters/configuration/#gocritic
- boolExprSimplify
- equalFold
disabled-checks: # This disables checks that are enabled by default (this can be combined with enabled-checks, contrary to the docs)
- appendAssign
- assignOp # https://github.com/kubernetes/kubernetes/issues/117288#issuecomment-1507008918
- captLocal
- commentFormatting
- elseif
# The following have few (single-digit) occurrences left in k/k and wouldn't be too onerous to enable
- exitAfterDefer
- regexpMust
- sloppyLen
- typeSwitchVar
- underef
- unslice
modernize:
# List of analyzers to disable.
# By default, all analyzers are enabled but in
# Kubernetes we want to be more selective and
# disable those which are not useful for it.
#
# Analyzers which are kept enabled are not
# called out here, see https://pkg.go.dev/golang.org/x/tools/go/analysis/passes/modernize#section-documentation
# for the full list.
#
# We don't pro-actively modernize existing code, so checks need to be disabled
# for the base config unless we happen to pass the check already.
# For new language features (identified with e.g. "go 1.27" for a feature added in 1.27)
# we hold back enabling as hint to reduce the risk that usage of the feature makes
# backporting harder. Waiting until all supported releases support the feature is safe,
# but it's also okay to go faster because backports to very old releases become less
# likely over time and some features might be worth a hint sooner - use common sense.
#
# Please keep sorted alphabetically.
disable:
# Replace interface{} with any.
#
# Disabled because developers may
# prefer to use `interface{}` for
# consistency with existing code
# and it's just syntactic sugar.
- any
# go 1.19: can simplify atomic int assignment/access
- atomictypes
# go 1.27: can declare embedded fields inline
# TODO Kubernetes 1.39: limit to base config
- embedlit
# go 1.26: can simplify with errors.AsType
- errorsastype
# Replace explicit loops over maps with calls to maps package.
#
# Completely disabled because the benefit
# isn't immediately obvious.
- mapsloop
# Replace if/else statements with calls to min or max.
#
# A useful hint for new code.
- minmax
# go 1.26: can simplify with new(expr)
- newexpr
# Replace 3-clause for loops with for-range over integers.
#
# A useful hint for new code (makes it shorter).
- rangeint
# go 1.26: can use iterators instead of Len/At-style APIs
- stditerators
# go 1.25: can simplify with reflect.TypeAssert
- reflecttypeassert
# Replace reflect.TypeOf(x) with TypeFor[T]().
#
# A useful hint for new code, it could be more efficient.
- reflecttypefor
# go 1.23: can simplify with slices.Backward
- slicesbackward
# Suggest replacing omitempty with omitzero for struct fields.
#
# Disabled because might interfere
# with encoding of API structs.
- omitzero
# Replace loops with slices.Contains or slices.ContainsFunc.
#
# A useful hint because it can make code more obvious
# and/or avoid helper functions.
- slicescontains
# Replace strings.Index etc. with strings.Cut
#
# A useful hint because it can make code more obvious.
- stringscut
# Replace HasPrefix/TrimPrefix with CutPrefix.
#
# A useful hint because the code becomes shorter.
- stringscutprefix
# Replace ranging over Split/Fields with SplitSeq/FieldsSeq.
#
# A useful hint because it's more efficient.
- stringsseq
# Replace += with strings.Builder.
#
# Disabled because in code which
# isn't performance-sensitive +=
# can be a bit more readable.
- stringsbuilder
# Replace context.WithCancel with t.Context in tests.
#
# Disabled because in Kubernetes,
# k8s.io/ktesting handles
# context cancellation and also
# addresses other pain points.
- testingcontext
# Replace wg.Add(1)/go/wg.Done() with wg.Go.
#
# A useful hint leading to shorter code.
# Makes wait.Group obsolete.
- waitgroupgo
revive:
# Only these rules are enabled.
rules:
- name: exported
arguments:
- disableStutteringCheck
staticcheck:
checks:
- "all"
- "-QF1008" # Omit embedded fields from selector expression
- "-QF1001" # Apply De Morgan’s law
- "-QF1002" # Convert untagged switch to tagged switch
- "-QF1003" # Convert if/else-if chain to tagged switch
- "-QF1004" # Use strings.ReplaceAll instead of strings.Replace with n == -1
- "-QF1006" # Lift if+break into loop condition
- "-QF1007" # Merge conditional assignment into variable declaration
- "-QF1008" # Omit embedded fields from selector expression
- "-QF1009" # Use time.Time.Equal instead of == operator
- "-QF1011" # Omit redundant type from variable declaration
- "-QF1012" # Use fmt.Fprintf(x, ...) instead of x.Write(fmt.Sprintf(...))
- "-S1000" # Use plain channel send or receive instead of single-case select
- "-S1002" # Omit comparison with boolean constant
- "-S1003" # Replace call to strings.Index with strings.Contains
- "-S1004" # Replace call to bytes.Compare with bytes.Equal
- "-S1005" # Drop unnecessary use of the blank identifier
- "-S1006" # Use for { ... } for infinite loops
- "-S1007" # Simplify regular expression by using raw string literal
- "-S1008" # Simplify returning boolean expression
- "-S1009" # Omit redundant nil check on slices, maps, and channels
- "-S1011" # Use a single append to concatenate two slices
- "-S1012" # Replace time.Now().Sub(x) with time.Since(x)
- "-S1016" # Use a type conversion instead of manually copying struct fields
- "-S1017" # Replace manual trimming with strings.TrimPrefix
- "-S1019" # Simplify make call by omitting redundant arguments
- "-S1021" # Merge variable declaration and assignment
- "-S1023" # Omit redundant control flow
- "-S1024" # Replace x.Sub(time.Now()) with time.Until(x)
- "-S1025" # Don’t use fmt.Sprintf("%s", x) unnecessarily
- "-S1028" # Simplify error construction with fmt.Errorf
- "-S1030" # Use bytes.Buffer.String or bytes.Buffer.Bytes
- "-S1034" # Use result of type assertion to simplify cases
- "-S1036" # Unnecessary guard around map access
- "-S1038" # Unnecessarily complex way of printing formatted string
- "-S1039" # Unnecessary use of fmt.Sprint
- "-S1040" # Type assertion to current type
- "-SA1006" # Printf with dynamic first argument and no further arguments
- "-SA1019" # Using a deprecated function, variable, constant or field
- "-SA2002" # Called testing.T.FailNow or SkipNow in a goroutine, which isn’t allowed
- "-SA4006" # A value assigned to a variable is never read before being overwritten. Forgotten error check or dead code?
- "-SA4011" # ineffective break statement. Did you mean to break out of the outer loop?
- "-ST1000" # Incorrect or missing package comment
- "-ST1001" # Dot imports are discouraged
- "-ST1003" # Poorly chosen identifier
- "-ST1005" # Incorrectly formatted error string
- "-ST1006" # Poorly chosen receiver name
- "-ST1008" # A function’s error value should be its last return value
- "-ST1011" # Poorly chosen name for variable of type time.Duration
- "-ST1012" # Poorly chosen name for error variable
- "-ST1013" # Should use constants for HTTP error codes, not magic numbers
- "-ST1016" # Use consistent method receiver names
- "-ST1017" # Don’t use Yoda conditions
- "-ST1020" # The documentation of an exported function should start with the function’s name
- "-ST1023" # Redundant type in variable declaration
testifylint:
enable-all: true
disable:
- empty
- encoded-compare
- equal-values
- error-nil
- expected-actual
- float-compare
- formatter
- len
- useless-assert
- require-error