mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-10-28 15:05:03 +08:00
802 lines
47 KiB
YAML
802 lines
47 KiB
YAML
# 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
|