Skip to content

Commit 5974ef5

Browse files
authored
Merge pull request #12470 from sbueringer/pr-enable-ssatags-linter
✨ Enable ssatags KAL linter
2 parents d40b68a + 596994a commit 5974ef5

23 files changed

+337
-8
lines changed

.golangci-kal.yml

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ linters:
2727
# having the `omitempty` value in their `json` tag where appropriate.
2828
- "optionalorrequired" # Every field should be marked as `+optional` or `+required`.
2929
- "requiredfields" # Required fields should not be pointers, and should not have `omitempty`.
30+
- "ssatags" # Ensure array fields have the appropriate listType markers
3031
- "statusoptional" # Ensure all first children within status should be optional.
3132
- "statussubresource" # All root objects that have a `status` field should have a status subresource.
3233
- "uniquemarkers" # Ensure that types and fields do not contain more than a single definition of a marker that should only be present once.
@@ -44,19 +45,21 @@ linters:
4445
isFirstField: Warn # Require conditions to be the first field in the status struct.
4546
usePatchStrategy: Forbid # Require conditions to be the first field in the status struct.
4647
useProtobuf: Forbid # We don't use protobuf, so protobuf tags are not required.
47-
optionalFields:
48+
optionalfields:
4849
pointers:
4950
preference: WhenRequired # Always | WhenRequired # Whether to always require pointers, or only when required. Defaults to `Always`.
5051
policy: SuggestFix # SuggestFix | Warn # The policy for pointers in optional fields. Defaults to `SuggestFix`.
5152
omitempty:
5253
policy: SuggestFix # SuggestFix | Warn | Ignore # The policy for omitempty in optional fields. Defaults to `SuggestFix`.
53-
# jsonTags:
54+
# jsontags:
5455
# jsonTagRegex: "^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$" # The default regex is appropriate for our use case.
55-
# optionalOrRequired:
56+
# optionalorrequired:
5657
# preferredOptionalMarker: optional | kubebuilder:validation:Optional # The preferred optional marker to use, fixes will suggest to use this marker. Defaults to `optional`.
5758
# preferredRequiredMarker: required | kubebuilder:validation:Required # The preferred required marker to use, fixes will suggest to use this marker. Defaults to `required`.
58-
# requiredFields:
59+
# requiredfields:
5960
# pointerPolicy: Warn | SuggestFix # Defaults to `SuggestFix`. We want our required fields to not be pointers.
61+
# ssatags:
62+
# listTypeSetUsage: Warn | Ignore # The policy for listType=set usage on object arrays. Defaults to `Warn`.
6063

6164
exclusions:
6265
generated: strict
@@ -83,23 +86,33 @@ linters:
8386
text: "Conditions field must be a slice of metav1.Condition"
8487
linters:
8588
- kubeapilinter
89+
- path: "api/addons/v1beta2|api/bootstrap/kubeadm/v1beta2|api/controlplane/kubeadm/v1beta2|api/core/v1beta2|api/ipam/v1beta2|api/runtime/v1beta2"
90+
text: "ssatags: Conditions should have a listType marker for proper Server-Side Apply behavior"
91+
linters:
92+
- kubeapilinter
8693
- path: "api/core/v1beta2"
8794
text: "field Conditions type Conditions must have a maximum items, add kubebuilder:validation:MaxItems marker"
8895
linters:
8996
- kubeapilinter
9097

9198
## Excludes for current clusterctl v1alpha3 and Runtime Hooks v1alpha1 apiVersions (can be fixed once we bump their apiVersion).
99+
# Note: The types in api/runtime/hooks/v1alpha1 are not CRDs, so e.g. SSA markers don't make sense there.
92100
- path: "cmd/clusterctl/api/v1alpha3|api/runtime/hooks/v1alpha1"
93-
text: "optionalfields|maxlength"
101+
text: "optionalfields|maxlength|ssatags"
94102
linters:
95103
- kubeapilinter
96104

97105
## Excludes for JSONSchemaProps
98-
# controller-gen does not allow to add MaxItems to Schemaless fields
106+
# controller-gen does not allow to add MaxItems to Schemaless fields: https://github.com/kubernetes-sigs/kube-api-linter/issues/120
99107
- path: "api/core/v1beta2/clusterclass_types.go"
100108
text: "maxlength: field (AllOf|OneOf|AnyOf) must have a maximum items, add kubebuilder:validation:MaxItems marker"
101109
linters:
102110
- kubeapilinter
111+
# controller-gen does not allow to add listType to Schemaless fields: https://github.com/kubernetes-sigs/kube-api-linter/issues/120
112+
- path: "api/core/v1beta2/clusterclass_types.go"
113+
text: "ssatags: (AllOf|OneOf|AnyOf) should have a listType marker for proper Server-Side Apply behavior"
114+
linters:
115+
- kubeapilinter
103116
# We want to align to the JSON tags of the CustomResourceDefinition fields.
104117
- path: "api/core/v1beta2/clusterclass_types"
105118
text: "field (XPreserveUnknownFields|XPreserveUnknownFields|XValidations|XMetadata|XIntOrString) json tag does not match pattern"

api/addons/v1beta2/clusterresourceset_types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type ClusterResourceSetSpec struct {
6464

6565
// resources is a list of Secrets/ConfigMaps where each contains 1 or more resources to be applied to remote clusters.
6666
// +optional
67+
// +listType=atomic
6768
// +kubebuilder:validation:MaxItems=100
6869
Resources []ResourceRef `json:"resources,omitempty"`
6970

api/addons/v1beta2/clusterresourcesetbinding_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ type ResourceSetBinding struct {
5757

5858
// resources is a list of resources that the ClusterResourceSet has.
5959
// +optional
60+
// +listType=atomic
6061
// +kubebuilder:validation:MaxItems=100
6162
Resources []ResourceBinding `json:"resources,omitempty"`
6263
}
@@ -137,6 +138,7 @@ type ClusterResourceSetBinding struct {
137138
type ClusterResourceSetBindingSpec struct {
138139
// bindings is a list of ClusterResourceSets and their resources.
139140
// +optional
141+
// +listType=atomic
140142
// +kubebuilder:validation:MaxItems=100
141143
Bindings []ResourceSetBinding `json:"bindings,omitempty"`
142144

api/bootstrap/kubeadm/v1beta2/kubeadm_types.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ type InitConfiguration struct {
7777
// bootstrapTokens is respected at `kubeadm init` time and describes a set of Bootstrap Tokens to create.
7878
// This information IS NOT uploaded to the kubeadm cluster configmap, partly because of its sensitive nature
7979
// +optional
80+
// +listType=atomic
8081
// +kubebuilder:validation:MaxItems=100
8182
BootstrapTokens []BootstrapToken `json:"bootstrapTokens,omitempty"`
8283

@@ -99,6 +100,7 @@ type InitConfiguration struct {
99100
// The list of phases can be obtained with the "kubeadm init --help" command.
100101
// This option takes effect only on Kubernetes >=1.22.0.
101102
// +optional
103+
// +listType=atomic
102104
// +kubebuilder:validation:MaxItems=50
103105
// +kubebuilder:validation:items:MinLength=1
104106
// +kubebuilder:validation:items:MaxLength=256
@@ -199,18 +201,21 @@ type APIServer struct {
199201

200202
// extraVolumes is an extra set of host volumes, mounted to the control plane component.
201203
// +optional
204+
// +listType=atomic
202205
// +kubebuilder:validation:MaxItems=100
203206
ExtraVolumes []HostPathMount `json:"extraVolumes,omitempty"`
204207

205208
// extraEnvs is an extra set of environment variables to pass to the control plane component.
206209
// Environment variables passed using ExtraEnvs will override any existing environment variables, or *_proxy environment variables that kubeadm adds by default.
207210
// This option takes effect only on Kubernetes >=1.31.0.
208211
// +optional
212+
// +listType=atomic
209213
// +kubebuilder:validation:MaxItems=100
210214
ExtraEnvs []EnvVar `json:"extraEnvs,omitempty"`
211215

212216
// certSANs sets extra Subject Alternative Names for the API Server signing cert.
213217
// +optional
218+
// +listType=atomic
214219
// +kubebuilder:validation:MaxItems=100
215220
// +kubebuilder:validation:items:MinLength=1
216221
// +kubebuilder:validation:items:MaxLength=253
@@ -234,13 +239,15 @@ type ControllerManager struct {
234239

235240
// extraVolumes is an extra set of host volumes, mounted to the control plane component.
236241
// +optional
242+
// +listType=atomic
237243
// +kubebuilder:validation:MaxItems=100
238244
ExtraVolumes []HostPathMount `json:"extraVolumes,omitempty"`
239245

240246
// extraEnvs is an extra set of environment variables to pass to the control plane component.
241247
// Environment variables passed using ExtraEnvs will override any existing environment variables, or *_proxy environment variables that kubeadm adds by default.
242248
// This option takes effect only on Kubernetes >=1.31.0.
243249
// +optional
250+
// +listType=atomic
244251
// +kubebuilder:validation:MaxItems=100
245252
ExtraEnvs []EnvVar `json:"extraEnvs,omitempty"`
246253
}
@@ -262,13 +269,15 @@ type Scheduler struct {
262269

263270
// extraVolumes is an extra set of host volumes, mounted to the control plane component.
264271
// +optional
272+
// +listType=atomic
265273
// +kubebuilder:validation:MaxItems=100
266274
ExtraVolumes []HostPathMount `json:"extraVolumes,omitempty"`
267275

268276
// extraEnvs is an extra set of environment variables to pass to the control plane component.
269277
// Environment variables passed using ExtraEnvs will override any existing environment variables, or *_proxy environment variables that kubeadm adds by default.
270278
// This option takes effect only on Kubernetes >=1.31.0.
271279
// +optional
280+
// +listType=atomic
272281
// +kubebuilder:validation:MaxItems=100
273282
ExtraEnvs []EnvVar `json:"extraEnvs,omitempty"`
274283
}
@@ -357,6 +366,7 @@ type NodeRegistrationOptions struct {
357366
// ignorePreflightErrors provides a slice of pre-flight errors to be ignored when the current node is registered, e.g. 'IsPrivilegedUser,Swap'.
358367
// Value 'all' ignores errors from all checks.
359368
// +optional
369+
// +listType=atomic
360370
// +kubebuilder:validation:MaxItems=50
361371
// +kubebuilder:validation:items:MinLength=1
362372
// +kubebuilder:validation:items:MaxLength=512
@@ -383,31 +393,38 @@ type BootstrapToken struct {
383393
// Used for joining nodes in the cluster.
384394
// +required
385395
Token *BootstrapTokenString `json:"token"`
396+
386397
// description sets a human-friendly message why this token exists and what it's used
387398
// for, so other administrators can know its purpose.
388399
// +optional
389400
// +kubebuilder:validation:MinLength=1
390401
// +kubebuilder:validation:MaxLength=512
391402
Description string `json:"description,omitempty"`
403+
392404
// ttlSeconds defines the time to live for this token. Defaults to 24h.
393405
// Expires and ttlSeconds are mutually exclusive.
394406
// +optional
395407
// +kubebuilder:validation:Minimum=0
396408
TTLSeconds *int32 `json:"ttlSeconds,omitempty"`
409+
397410
// expires specifies the timestamp when this token expires. Defaults to being set
398411
// dynamically at runtime based on the ttlSeconds. Expires and ttlSeconds are mutually exclusive.
399412
// +optional
400413
Expires *metav1.Time `json:"expires,omitempty"`
414+
401415
// usages describes the ways in which this token can be used. Can by default be used
402416
// for establishing bidirectional trust, but that can be changed here.
403417
// +optional
418+
// +listType=atomic
404419
// +kubebuilder:validation:MaxItems=100
405420
// +kubebuilder:validation:items:MinLength=1
406421
// +kubebuilder:validation:items:MaxLength=256
407422
Usages []string `json:"usages,omitempty"`
423+
408424
// groups specifies the extra groups that this token will authenticate as when/if
409425
// used for authentication
410426
// +optional
427+
// +listType=atomic
411428
// +kubebuilder:validation:MaxItems=100
412429
// +kubebuilder:validation:items:MinLength=1
413430
// +kubebuilder:validation:items:MaxLength=256
@@ -456,18 +473,21 @@ type LocalEtcd struct {
456473
// Environment variables passed using ExtraEnvs will override any existing environment variables, or *_proxy environment variables that kubeadm adds by default.
457474
// This option takes effect only on Kubernetes >=1.31.0.
458475
// +optional
476+
// +listType=atomic
459477
// +kubebuilder:validation:MaxItems=100
460478
ExtraEnvs []EnvVar `json:"extraEnvs,omitempty"`
461479

462480
// serverCertSANs sets extra Subject Alternative Names for the etcd server signing cert.
463481
// +optional
482+
// +listType=atomic
464483
// +kubebuilder:validation:MaxItems=100
465484
// +kubebuilder:validation:items:MinLength=1
466485
// +kubebuilder:validation:items:MaxLength=253
467486
ServerCertSANs []string `json:"serverCertSANs,omitempty"`
468487

469488
// peerCertSANs sets extra Subject Alternative Names for the etcd peer signing cert.
470489
// +optional
490+
// +listType=atomic
471491
// +kubebuilder:validation:MaxItems=100
472492
// +kubebuilder:validation:items:MinLength=1
473493
// +kubebuilder:validation:items:MaxLength=253
@@ -479,6 +499,7 @@ type LocalEtcd struct {
479499
type ExternalEtcd struct {
480500
// endpoints of etcd members. Required for ExternalEtcd.
481501
// +required
502+
// +listType=atomic
482503
// +kubebuilder:validation:MinItems=1
483504
// +kubebuilder:validation:MaxItems=50
484505
// +kubebuilder:validation:items:MinLength=1
@@ -538,6 +559,7 @@ type JoinConfiguration struct {
538559
// The list of phases can be obtained with the "kubeadm init --help" command.
539560
// This option takes effect only on Kubernetes >=1.22.0.
540561
// +optional
562+
// +listType=atomic
541563
// +kubebuilder:validation:MaxItems=50
542564
// +kubebuilder:validation:items:MinLength=1
543565
// +kubebuilder:validation:items:MaxLength=256
@@ -606,6 +628,7 @@ type BootstrapTokenDiscovery struct {
606628
// ASN.1. These hashes can be calculated using, for example, OpenSSL:
607629
// openssl x509 -pubkey -in ca.crt openssl rsa -pubin -outform der 2>&/dev/null | openssl dgst -sha256 -hex
608630
// +optional
631+
// +listType=atomic
609632
// +kubebuilder:validation:MaxItems=100
610633
// +kubebuilder:validation:items:MinLength=1
611634
// +kubebuilder:validation:items:MaxLength=512
@@ -743,6 +766,7 @@ type KubeConfigAuthExec struct {
743766

744767
// args is the arguments to pass to the command when executing it.
745768
// +optional
769+
// +listType=atomic
746770
// +kubebuilder:validation:MaxItems=100
747771
// +kubebuilder:validation:items:MinLength=1
748772
// +kubebuilder:validation:items:MaxLength=512
@@ -752,6 +776,7 @@ type KubeConfigAuthExec struct {
752776
// are unioned with the host's environment, as well as variables client-go uses
753777
// to pass argument to the plugin.
754778
// +optional
779+
// +listType=atomic
755780
// +kubebuilder:validation:MaxItems=100
756781
Env []KubeConfigAuthExecEnv `json:"env,omitempty"`
757782

api/bootstrap/kubeadm/v1beta2/kubeadmconfig_types.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ type KubeadmConfigSpec struct {
6666

6767
// files specifies extra files to be passed to user_data upon creation.
6868
// +optional
69+
// +listType=atomic
6970
// +kubebuilder:validation:MaxItems=200
7071
Files []File `json:"files,omitempty"`
7172

@@ -75,13 +76,15 @@ type KubeadmConfigSpec struct {
7576

7677
// mounts specifies a list of mount points to be setup.
7778
// +optional
79+
// +listType=atomic
7880
// +kubebuilder:validation:MaxItems=100
7981
Mounts []MountPoints `json:"mounts,omitempty"`
8082

8183
// bootCommands specifies extra commands to run very early in the boot process via the cloud-init bootcmd
8284
// module. bootcmd will run on every boot, 'cloud-init-per' command can be used to make bootcmd run exactly
8385
// once. This is typically run in the cloud-init.service systemd unit. This has no effect in Ignition.
8486
// +optional
87+
// +listType=atomic
8588
// +kubebuilder:validation:MaxItems=1000
8689
// +kubebuilder:validation:items:MinLength=1
8790
// +kubebuilder:validation:items:MaxLength=10240
@@ -91,6 +94,7 @@ type KubeadmConfigSpec struct {
9194
// With cloud-init, this is prepended to the runcmd module configuration, and is typically executed in
9295
// the cloud-final.service systemd unit. In Ignition, this is prepended to /etc/kubeadm.sh.
9396
// +optional
97+
// +listType=atomic
9498
// +kubebuilder:validation:MaxItems=1000
9599
// +kubebuilder:validation:items:MinLength=1
96100
// +kubebuilder:validation:items:MaxLength=10240
@@ -100,13 +104,15 @@ type KubeadmConfigSpec struct {
100104
// With cloud-init, this is appended to the runcmd module configuration, and is typically executed in
101105
// the cloud-final.service systemd unit. In Ignition, this is appended to /etc/kubeadm.sh.
102106
// +optional
107+
// +listType=atomic
103108
// +kubebuilder:validation:MaxItems=1000
104109
// +kubebuilder:validation:items:MinLength=1
105110
// +kubebuilder:validation:items:MaxLength=10240
106111
PostKubeadmCommands []string `json:"postKubeadmCommands,omitempty"`
107112

108113
// users specifies extra users to add
109114
// +optional
115+
// +listType=atomic
110116
// +kubebuilder:validation:MaxItems=100
111117
Users []User `json:"users,omitempty"`
112118

@@ -766,6 +772,7 @@ type User struct {
766772

767773
// sshAuthorizedKeys specifies a list of ssh authorized keys for the user
768774
// +optional
775+
// +listType=atomic
769776
// +kubebuilder:validation:MaxItems=100
770777
// +kubebuilder:validation:items:MinLength=1
771778
// +kubebuilder:validation:items:MaxLength=2048
@@ -776,6 +783,7 @@ type User struct {
776783
type NTP struct {
777784
// servers specifies which NTP servers to use
778785
// +optional
786+
// +listType=atomic
779787
// +kubebuilder:validation:MaxItems=100
780788
// +kubebuilder:validation:items:MinLength=1
781789
// +kubebuilder:validation:items:MaxLength=512
@@ -790,11 +798,13 @@ type NTP struct {
790798
type DiskSetup struct {
791799
// partitions specifies the list of the partitions to setup.
792800
// +optional
801+
// +listType=atomic
793802
// +kubebuilder:validation:MaxItems=100
794803
Partitions []Partition `json:"partitions,omitempty"`
795804

796805
// filesystems specifies the list of file systems to setup.
797806
// +optional
807+
// +listType=atomic
798808
// +kubebuilder:validation:MaxItems=100
799809
Filesystems []Filesystem `json:"filesystems,omitempty"`
800810
}
@@ -863,6 +873,7 @@ type Filesystem struct {
863873

864874
// extraOpts defined extra options to add to the command for creating the file system.
865875
// +optional
876+
// +listType=atomic
866877
// +kubebuilder:validation:MaxItems=100
867878
// +kubebuilder:validation:items:MinLength=1
868879
// +kubebuilder:validation:items:MaxLength=256

api/core/v1beta2/cluster_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -811,6 +811,7 @@ type MachinePoolTopology struct {
811811
// failureDomains is the list of failure domains the machine pool will be created in.
812812
// Must match a key in the FailureDomains map stored on the cluster object.
813813
// +optional
814+
// +listType=atomic
814815
// +kubebuilder:validation:MaxItems=100
815816
// +kubebuilder:validation:items:MinLength=1
816817
// +kubebuilder:validation:items:MaxLength=256
@@ -941,6 +942,7 @@ type ClusterNetwork struct {
941942
type NetworkRanges struct {
942943
// cidrBlocks is a list of CIDR blocks.
943944
// +required
945+
// +listType=atomic
944946
// +kubebuilder:validation:MaxItems=100
945947
// +kubebuilder:validation:items:MinLength=1
946948
// +kubebuilder:validation:items:MaxLength=43

0 commit comments

Comments
 (0)