Skip to content

Commit f6b520a

Browse files
committed
Enable optionalfields linter
1 parent 1f62140 commit f6b520a

File tree

9 files changed

+87
-28
lines changed

9 files changed

+87
-28
lines changed

.golangci-kal.yml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ linters:
2323
- "nobools" # Bools do not evolve over time, should use enums instead.
2424
- "nofloats" # Ensure floats are not used.
2525
- "nomaps" # Ensure maps are not used.
26+
- "optionalfields" # Ensure that all fields marked as optional adhere to being pointers and
27+
# having the `omitempty` value in their `json` tag where appropriate.
2628
- "optionalorrequired" # Every field should be marked as `+optional` or `+required`.
2729
- "requiredfields" # Required fields should not be pointers, and should not have `omitempty`.
2830
- "statusoptional" # Ensure all first children within status should be optional.
@@ -42,6 +44,12 @@ linters:
4244
isFirstField: Warn # Require conditions to be the first field in the status struct.
4345
usePatchStrategy: Forbid # Require conditions to be the first field in the status struct.
4446
useProtobuf: Forbid # We don't use protobuf, so protobuf tags are not required.
47+
optionalFields:
48+
pointers:
49+
preference: WhenRequired # Always | WhenRequired # Whether to always require pointers, or only when required. Defaults to `Always`.
50+
policy: SuggestFix # SuggestFix | Warn # The policy for pointers in optional fields. Defaults to `SuggestFix`.
51+
omitempty:
52+
policy: SuggestFix # SuggestFix | Warn | Ignore # The policy for omitempty in optional fields. Defaults to `SuggestFix`.
4553
# jsonTags:
4654
# jsonTagRegex: "^[a-z][a-z0-9]*(?:[A-Z][a-z0-9]*)*$" # The default regex is appropriate for our use case.
4755
# optionalOrRequired:
@@ -71,6 +79,10 @@ linters:
7179
text: "Conditions field must be a slice of metav1.Condition"
7280
linters:
7381
- kubeapilinter
82+
- path: "api/addons/v1beta1/*|api/bootstrap/kubeadm/v1beta1/*|api/controlplane/kubeadm/v1beta1/*|api/core/v1beta1/*|api/ipam/v1beta1/*|api/ipam/v1alpha1/*|api/runtime/v1alpha1/*|cmd/clusterctl/api/v1alpha3/*"
83+
text: "optionalfields"
84+
linters:
85+
- kubeapilinter
7486
- path: "api/core/v1beta2/*|api/core/v1beta1/*"
7587
text: "field Conditions type Conditions must have a maximum items, add kubebuilder:validation:MaxItems marker"
7688
linters:
@@ -144,6 +156,30 @@ linters:
144156
text: "field Ref is marked as required, should not be a pointer"
145157
linters:
146158
- kubeapilinter
159+
160+
## TODO: optional required tasks.
161+
# Move up
162+
# Audit the entire hook types + builtins from a serialization point of view (this is not a CRD)
163+
- path: "api/runtime/hooks/v1alpha1/*"
164+
text: "optionalfields"
165+
linters:
166+
- kubeapilinter
167+
168+
# https://github.com/kubernetes-sigs/cluster-api/pull/12429
169+
# FailureMessage will be removed when v1beta1 is removed
170+
- path: "api/*"
171+
text: "field FailureMessage is optional and does not allow the zero value"
172+
linters:
173+
- kubeapilinter
174+
175+
# https://github.com/kubernetes-sigs/cluster-api/pull/12431
176+
# https://github.com/kubernetes-sigs/cluster-api/pull/12435
177+
# Take a closer look
178+
- path: ".*"
179+
text: "field Spec|Status is optional"
180+
linters:
181+
- kubeapilinter
182+
147183
issues:
148184
max-same-issues: 0
149185
max-issues-per-linter: 0

api/bootstrap/kubeadm/v1beta2/kubeadm_types.go

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ type InitConfiguration struct {
8585
// When used in the context of control plane nodes, NodeRegistration should remain consistent
8686
// across both InitConfiguration and JoinConfiguration
8787
// +optional
88-
NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"`
88+
// +kubebuilder:validation:MinProperties=1
89+
NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty,omitzero"` // nolint:kubeapilinter // nolint:kubeapilinter
8990

9091
// localAPIEndpoint represents the endpoint of the API server instance that's deployed on this control plane node
9192
// In HA setups, this differs from ClusterConfiguration.ControlPlaneEndpoint in the sense that ControlPlaneEndpoint
@@ -94,7 +95,8 @@ type InitConfiguration struct {
9495
// on. By default, kubeadm tries to auto-detect the IP of the default interface and use that, but in case that process
9596
// fails you may set the desired value here.
9697
// +optional
97-
LocalAPIEndpoint APIEndpoint `json:"localAPIEndpoint,omitempty"`
98+
// +kubebuilder:validation:MinProperties=1
99+
LocalAPIEndpoint APIEndpoint `json:"localAPIEndpoint,omitempty,omitzero"` // nolint:kubeapilinter
98100

99101
// skipPhases is a list of phases to skip during command execution.
100102
// The list of phases can be obtained with the "kubeadm init --help" command.
@@ -120,7 +122,8 @@ type ClusterConfiguration struct {
120122
// etcd holds configuration for etcd.
121123
// NB: This value defaults to a Local (stacked) etcd
122124
// +optional
123-
Etcd Etcd `json:"etcd,omitempty"`
125+
// +kubebuilder:validation:MinProperties=1
126+
Etcd Etcd `json:"etcd,omitempty,omitzero"` // nolint:kubeapilinter // FIXME: double check that unsetting etcd still works: https://github.com/kubernetes-sigs/cluster-api/pull/12065
124127

125128
// controlPlaneEndpoint sets a stable IP address or DNS name for the control plane; it
126129
// can be a valid IP address or a RFC-1123 DNS subdomain, both with optional TCP port.
@@ -141,19 +144,23 @@ type ClusterConfiguration struct {
141144

142145
// apiServer contains extra settings for the API server control plane component
143146
// +optional
144-
APIServer APIServer `json:"apiServer,omitempty"`
147+
// +kubebuilder:validation:MinProperties=1
148+
APIServer APIServer `json:"apiServer,omitempty,omitzero"` // nolint:kubeapilinter
145149

146150
// controllerManager contains extra settings for the controller manager control plane component
147151
// +optional
148-
ControllerManager ControlPlaneComponent `json:"controllerManager,omitempty"`
152+
// +kubebuilder:validation:MinProperties=1
153+
ControllerManager ControlPlaneComponent `json:"controllerManager,omitempty,omitzero"` // nolint:kubeapilinter // FIXME: replace with ControllerManager struct
149154

150155
// scheduler contains extra settings for the scheduler control plane component
151156
// +optional
152-
Scheduler ControlPlaneComponent `json:"scheduler,omitempty"`
157+
// +kubebuilder:validation:MinProperties=1
158+
Scheduler ControlPlaneComponent `json:"scheduler,omitempty,omitzero"` // nolint:kubeapilinter // FIXME: replace with Scheduler struct
153159

154160
// dns defines the options for the DNS add-on installed in the cluster.
155161
// +optional
156-
DNS DNS `json:"dns,omitempty"`
162+
// +kubebuilder:validation:MinProperties=1
163+
DNS DNS `json:"dns,omitempty,omitzero"` // nolint:kubeapilinter
157164

158165
// certificatesDir specifies where to store or look for all required certificates.
159166
// NB: if not provided, this will default to `/etc/kubernetes/pki`
@@ -511,7 +518,8 @@ type JoinConfiguration struct {
511518
// When used in the context of control plane nodes, NodeRegistration should remain consistent
512519
// across both InitConfiguration and JoinConfiguration
513520
// +optional
514-
NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty"`
521+
// +kubebuilder:validation:MinProperties=1
522+
NodeRegistration NodeRegistrationOptions `json:"nodeRegistration,omitempty,omitzero"` // nolint:kubeapilinter
515523

516524
// caCertPath is the path to the SSL certificate authority used to
517525
// secure communications between node and control-plane.
@@ -525,7 +533,9 @@ type JoinConfiguration struct {
525533
// discovery specifies the options for the kubelet to use during the TLS Bootstrap process
526534
// +optional
527535
// TODO: revisit when there is defaulting from k/k
528-
Discovery Discovery `json:"discovery,omitempty"`
536+
// +kubebuilder:validation:MinProperties=1
537+
// FIXME: double check that one of BootstrapToken or File must be set
538+
Discovery Discovery `json:"discovery,omitempty,omitzero"` // nolint:kubeapilinter
529539

530540
// controlPlane defines the additional control plane instance to be deployed on the joining node.
531541
// If nil, no additional control plane instance will be deployed.
@@ -555,7 +565,8 @@ type JoinConfiguration struct {
555565
type JoinControlPlane struct {
556566
// localAPIEndpoint represents the endpoint of the API server instance to be deployed on this node.
557567
// +optional
558-
LocalAPIEndpoint APIEndpoint `json:"localAPIEndpoint,omitempty"`
568+
// +kubebuilder:validation:MinProperties=1
569+
LocalAPIEndpoint APIEndpoint `json:"localAPIEndpoint,omitempty,omitzero"` // nolint:kubeapilinter
559570
}
560571

561572
// Discovery specifies the options for the kubelet to use during the TLS Bootstrap process.

api/bootstrap/kubeadm/v1beta2/kubeadmconfig_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ type KubeadmConfigSpec struct {
116116

117117
// format specifies the output format of the bootstrap data
118118
// +optional
119-
Format Format `json:"format,omitempty"`
119+
Format Format `json:"format,omitempty"` // nolint:kubeapilinter // FIXME: Talk to Joel: optionalfields linter should be improved to detect enum on the type
120120

121121
// verbosity is the number for the kubeadm log level verbosity.
122122
// It overrides the `--v` flag in kubeadm commands.
@@ -630,7 +630,7 @@ type File struct {
630630

631631
// encoding specifies the encoding of the file contents.
632632
// +optional
633-
Encoding Encoding `json:"encoding,omitempty"`
633+
Encoding Encoding `json:"encoding,omitempty"` // nolint:kubeapilinter // FIXME: Talk to Joel: optionalfields linter should be improved to detect enum on the type
634634

635635
// append specifies whether to append Content to existing file if Path exists.
636636
// +optional

api/controlplane/kubeadm/v1beta2/kubeadm_control_plane_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,7 @@ type RolloutStrategy struct {
538538
// "RollingUpdate".
539539
// Default is RollingUpdate.
540540
// +optional
541-
Type RolloutStrategyType `json:"type,omitempty"`
541+
Type RolloutStrategyType `json:"type,omitempty"` // nolint:kubeapilinter // FIXME: Talk to Joel: optionalfields linter should be improved to detect enum on the type
542542

543543
// rollingUpdate is the rolling update config params. Present only if
544544
// RolloutStrategyType = RollingUpdate.

api/core/v1beta2/cluster_types.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -549,7 +549,8 @@ type Topology struct {
549549

550550
// controlPlane describes the cluster control plane.
551551
// +optional
552-
ControlPlane ControlPlaneTopology `json:"controlPlane,omitempty"`
552+
// +kubebuilder:validation:MinProperties=1
553+
ControlPlane ControlPlaneTopology `json:"controlPlane,omitempty,omitzero"` // nolint:kubeapilinter
553554

554555
// workers encapsulates the different constructs that form the worker nodes
555556
// for the cluster.
@@ -597,7 +598,8 @@ type ControlPlaneTopology struct {
597598
// is applied only to the ControlPlane.
598599
// At runtime this metadata is merged with the corresponding metadata from the ClusterClass.
599600
// +optional
600-
Metadata ObjectMeta `json:"metadata,omitempty"`
601+
// +kubebuilder:validation:MinProperties=1
602+
Metadata ObjectMeta `json:"metadata,omitempty,omitzero"` // nolint:kubeapilinter
601603

602604
// replicas is the number of control plane nodes.
603605
// If the value is nil, the ControlPlane object is created without the number of Replicas
@@ -675,7 +677,8 @@ type MachineDeploymentTopology struct {
675677
// metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment.
676678
// At runtime this metadata is merged with the corresponding metadata from the ClusterClass.
677679
// +optional
678-
Metadata ObjectMeta `json:"metadata,omitempty"`
680+
// +kubebuilder:validation:MinProperties=1
681+
Metadata ObjectMeta `json:"metadata,omitempty,omitzero"` // nolint:kubeapilinter
679682

680683
// class is the name of the MachineDeploymentClass used to create the set of worker nodes.
681684
// This should match one of the deployment classes defined in the ClusterClass object
@@ -789,7 +792,8 @@ type MachinePoolTopology struct {
789792
// metadata is the metadata applied to the MachinePool.
790793
// At runtime this metadata is merged with the corresponding metadata from the ClusterClass.
791794
// +optional
792-
Metadata ObjectMeta `json:"metadata,omitempty"`
795+
// +kubebuilder:validation:MinProperties=1
796+
Metadata ObjectMeta `json:"metadata,omitempty,omitzero"` // nolint:kubeapilinter
793797

794798
// class is the name of the MachinePoolClass used to create the pool of worker nodes.
795799
// This should match one of the deployment classes defined in the ClusterClass object

api/core/v1beta2/clusterclass_types.go

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,18 +104,21 @@ type ClusterClassSpec struct {
104104
// infrastructure is a reference to a local struct that holds the details
105105
// for provisioning the infrastructure cluster for the Cluster.
106106
// +optional
107-
Infrastructure InfrastructureClass `json:"infrastructure,omitempty"`
107+
// +kubebuilder:validation:MinProperties=1
108+
Infrastructure InfrastructureClass `json:"infrastructure,omitempty,omitzero"` // nolint:kubeapilinter
108109

109110
// controlPlane is a reference to a local struct that holds the details
110111
// for provisioning the Control Plane for the Cluster.
111112
// +optional
112-
ControlPlane ControlPlaneClass `json:"controlPlane,omitempty"`
113+
// +kubebuilder:validation:MinProperties=1
114+
ControlPlane ControlPlaneClass `json:"controlPlane,omitempty,omitzero"` // nolint:kubeapilinter
113115

114116
// workers describes the worker nodes for the cluster.
115117
// It is a collection of node types which can be used to create
116118
// the worker nodes of the cluster.
117119
// +optional
118-
Workers WorkersClass `json:"workers,omitempty"`
120+
// +kubebuilder:validation:MinProperties=1
121+
Workers WorkersClass `json:"workers,omitempty,omitzero"` // nolint:kubeapilinter
119122

120123
// variables defines the variables which can be configured
121124
// in the Cluster topology and are then used in patches.
@@ -151,7 +154,8 @@ type ControlPlaneClass struct {
151154
// This field is supported if and only if the control plane provider template
152155
// referenced is Machine based.
153156
// +optional
154-
Metadata ObjectMeta `json:"metadata,omitempty"`
157+
// +kubebuilder:validation:MinProperties=1
158+
Metadata ObjectMeta `json:"metadata,omitempty,omitzero"` // nolint:kubeapilinter
155159

156160
// LocalObjectTemplate contains the reference to a provider-specific control plane template.
157161
ClusterClassTemplate `json:",inline"`
@@ -354,7 +358,8 @@ type MachineDeploymentClassTemplate struct {
354358
// metadata is the metadata applied to the MachineDeployment and the machines of the MachineDeployment.
355359
// At runtime this metadata is merged with the corresponding metadata from the topology.
356360
// +optional
357-
Metadata ObjectMeta `json:"metadata,omitempty"`
361+
// +kubebuilder:validation:MinProperties=1
362+
Metadata ObjectMeta `json:"metadata,omitempty,omitzero"` // nolint:kubeapilinter
358363

359364
// bootstrap contains the bootstrap template reference to be used
360365
// for the creation of worker Machines.
@@ -504,7 +509,8 @@ type MachinePoolClassTemplate struct {
504509
// metadata is the metadata applied to the MachinePool.
505510
// At runtime this metadata is merged with the corresponding metadata from the topology.
506511
// +optional
507-
Metadata ObjectMeta `json:"metadata,omitempty"`
512+
// +kubebuilder:validation:MinProperties=1
513+
Metadata ObjectMeta `json:"metadata,omitempty,omitzero"` // nolint:kubeapilinter
508514

509515
// bootstrap contains the bootstrap template reference to be used
510516
// for the creation of the Machines in the MachinePool.
@@ -561,7 +567,8 @@ type ClusterClassVariable struct {
561567
// Deprecated: This field is deprecated and will be removed when support for v1beta1 will be dropped. Please use XMetadata in JSONSchemaProps instead.
562568
//
563569
// +optional
564-
DeprecatedV1Beta1Metadata ClusterClassVariableMetadata `json:"deprecatedV1Beta1Metadata,omitempty"`
570+
// +kubebuilder:validation:MinProperties=1
571+
DeprecatedV1Beta1Metadata ClusterClassVariableMetadata `json:"deprecatedV1Beta1Metadata,omitempty,omitzero"` // nolint:kubeapilinter
565572

566573
// schema defines the schema of the variable.
567574
// +required
@@ -1288,7 +1295,8 @@ type ClusterClassStatusVariableDefinition struct {
12881295
// Deprecated: This field is deprecated and will be removed when support for v1beta1 will be dropped. Please use XMetadata in JSONSchemaProps instead.
12891296
//
12901297
// +optional
1291-
DeprecatedV1Beta1Metadata ClusterClassVariableMetadata `json:"deprecatedV1Beta1Metadata,omitempty"`
1298+
// +kubebuilder:validation:MinProperties=1
1299+
DeprecatedV1Beta1Metadata ClusterClassVariableMetadata `json:"deprecatedV1Beta1Metadata,omitempty,omitzero"` // nolint:kubeapilinter
12921300

12931301
// schema defines the schema of the variable.
12941302
// +required

api/core/v1beta2/condition_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ type Condition struct {
7070
// understand the current situation and act accordingly.
7171
// The Severity field MUST be set only when Status=False.
7272
// +optional
73-
Severity ConditionSeverity `json:"severity,omitempty"`
73+
Severity ConditionSeverity `json:"severity,omitempty"` // nolint:kubeapilinter // field will be removed when v1beta1 is removed
7474

7575
// lastTransitionTime is the last time the condition transitioned from one status to another.
7676
// This should be when the underlying condition changed. If that is not known, then using the time when

api/ipam/v1beta2/ipaddressclaim_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ type IPAddressClaimStatus struct {
6565

6666
// addressRef is a reference to the address that was created for this claim.
6767
// +optional
68-
AddressRef IPAddressReference `json:"addressRef,omitempty"`
68+
AddressRef IPAddressReference `json:"addressRef,omitempty,omitzero"` // nolint:kubeapilinter // FIXME: Talk to Joel: optionalfields linter should be improved to detect omitzero
6969

7070
// deprecated groups all the status fields that are deprecated and will be removed when all the nested field are removed.
7171
// +optional

api/runtime/v1beta2/extensionconfig_types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ type ExtensionHandler struct {
179179
// Defaults to Fail if not set.
180180
// +optional
181181
// +kubebuilder:validation:Enum=Ignore;Fail
182-
FailurePolicy *FailurePolicy `json:"failurePolicy,omitempty"`
182+
FailurePolicy *FailurePolicy `json:"failurePolicy,omitempty"` // nolint:kubeapilinter // FIXME: change this to non-pointer
183183
}
184184

185185
// GroupVersionHook defines the runtime hook when the ExtensionHandler is called.

0 commit comments

Comments
 (0)