Skip to content

Commit 13eaa95

Browse files
kubebuilder validation and clarified API behavior for KubeletConfig API doc and adds tests
1 parent 22c7448 commit 13eaa95

6 files changed

Lines changed: 313 additions & 41 deletions

File tree

Lines changed: 195 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,195 @@
1+
apiVersion: apiextensions.k8s.io/v1 # Hack because controller-gen complains if we don't have this
2+
name: "KubeletConfig"
3+
crdName: kubeletconfigs.machineconfiguration.openshift.io
4+
tests:
5+
onCreate:
6+
# LogLevel Boundary Tests
7+
- name: Should be able to set logLevel to 0 (minimum)
8+
initial: |
9+
apiVersion: machineconfiguration.openshift.io/v1
10+
kind: KubeletConfig
11+
spec:
12+
logLevel: 0
13+
expected: |
14+
apiVersion: machineconfiguration.openshift.io/v1
15+
kind: KubeletConfig
16+
spec:
17+
logLevel: 0
18+
- name: Should be able to set logLevel to 10 (maximum)
19+
initial: |
20+
apiVersion: machineconfiguration.openshift.io/v1
21+
kind: KubeletConfig
22+
spec:
23+
logLevel: 10
24+
expected: |
25+
apiVersion: machineconfiguration.openshift.io/v1
26+
kind: KubeletConfig
27+
spec:
28+
logLevel: 10
29+
- name: Should reject logLevel less than 0
30+
initial: |
31+
apiVersion: machineconfiguration.openshift.io/v1
32+
kind: KubeletConfig
33+
spec:
34+
logLevel: -1
35+
expectedError: "Invalid value"
36+
- name: Should reject logLevel greater than 10
37+
initial: |
38+
apiVersion: machineconfiguration.openshift.io/v1
39+
kind: KubeletConfig
40+
spec:
41+
logLevel: 11
42+
expectedError: "Invalid value"
43+
44+
# TLSSecurityProfile CEL Validation tests
45+
- name: Should allow tlsSecurityProfile with Old type
46+
initial: |
47+
apiVersion: machineconfiguration.openshift.io/v1
48+
kind: KubeletConfig
49+
spec:
50+
tlsSecurityProfile:
51+
type: Old
52+
expected: |
53+
apiVersion: machineconfiguration.openshift.io/v1
54+
kind: KubeletConfig
55+
spec:
56+
tlsSecurityProfile:
57+
type: Old
58+
- name: Should allow tlsSecurityProfile with Intermediate type
59+
initial: |
60+
apiVersion: machineconfiguration.openshift.io/v1
61+
kind: KubeletConfig
62+
spec:
63+
tlsSecurityProfile:
64+
type: Intermediate
65+
expected: |
66+
apiVersion: machineconfiguration.openshift.io/v1
67+
kind: KubeletConfig
68+
spec:
69+
tlsSecurityProfile:
70+
type: Intermediate
71+
- name: Should reject tlsSecurityProfile with Modern type
72+
initial: |
73+
apiVersion: machineconfiguration.openshift.io/v1
74+
kind: KubeletConfig
75+
spec:
76+
tlsSecurityProfile:
77+
type: Modern
78+
expectedError: "only Old and Intermediate TLS profiles are supported for kubelet"
79+
- name: Should reject tlsSecurityProfile with Custom type
80+
initial: |
81+
apiVersion: machineconfiguration.openshift.io/v1
82+
kind: KubeletConfig
83+
spec:
84+
tlsSecurityProfile:
85+
type: Custom
86+
custom:
87+
ciphers:
88+
- ECDHE-ECDSA-AES128-GCM-SHA256
89+
minTLSVersion: VersionTLS12
90+
expectedError: "only Old and Intermediate TLS profiles are supported for kubelet"
91+
- name: Should allow tlsSecurityProfile without type field for backward compatibility
92+
initial: |
93+
apiVersion: machineconfiguration.openshift.io/v1
94+
kind: KubeletConfig
95+
spec:
96+
tlsSecurityProfile:
97+
custom:
98+
ciphers:
99+
- ECDHE-ECDSA-AES128-GCM-SHA256
100+
minTLSVersion: VersionTLS12
101+
expected: |
102+
apiVersion: machineconfiguration.openshift.io/v1
103+
kind: KubeletConfig
104+
spec:
105+
tlsSecurityProfile:
106+
custom:
107+
ciphers:
108+
- ECDHE-ECDSA-AES128-GCM-SHA256
109+
minTLSVersion: VersionTLS12
110+
111+
onUpdate:
112+
# Ratcheting tests - ensure existing objects with previously valid values can be updated
113+
- name: Should allow updating other fields with a previously valid Custom TLS profile persisted
114+
initialCRDPatches:
115+
- op: remove
116+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/tlsSecurityProfile/x-kubernetes-validations
117+
initial: |
118+
apiVersion: machineconfiguration.openshift.io/v1
119+
kind: KubeletConfig
120+
spec:
121+
tlsSecurityProfile:
122+
type: Custom
123+
custom:
124+
ciphers:
125+
- ECDHE-ECDSA-AES128-GCM-SHA256
126+
minTLSVersion: VersionTLS12
127+
updated: |
128+
apiVersion: machineconfiguration.openshift.io/v1
129+
kind: KubeletConfig
130+
spec:
131+
logLevel: 5
132+
tlsSecurityProfile:
133+
type: Custom
134+
custom:
135+
ciphers:
136+
- ECDHE-ECDSA-AES128-GCM-SHA256
137+
minTLSVersion: VersionTLS12
138+
expected: |
139+
apiVersion: machineconfiguration.openshift.io/v1
140+
kind: KubeletConfig
141+
spec:
142+
logLevel: 5
143+
tlsSecurityProfile:
144+
type: Custom
145+
custom:
146+
ciphers:
147+
- ECDHE-ECDSA-AES128-GCM-SHA256
148+
minTLSVersion: VersionTLS12
149+
- name: Should allow updating other fields with a previously valid Modern TLS profile persisted
150+
initialCRDPatches:
151+
- op: remove
152+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/tlsSecurityProfile/x-kubernetes-validations
153+
initial: |
154+
apiVersion: machineconfiguration.openshift.io/v1
155+
kind: KubeletConfig
156+
spec:
157+
tlsSecurityProfile:
158+
type: Modern
159+
updated: |
160+
apiVersion: machineconfiguration.openshift.io/v1
161+
kind: KubeletConfig
162+
spec:
163+
logLevel: 3
164+
tlsSecurityProfile:
165+
type: Modern
166+
expected: |
167+
apiVersion: machineconfiguration.openshift.io/v1
168+
kind: KubeletConfig
169+
spec:
170+
logLevel: 3
171+
tlsSecurityProfile:
172+
type: Modern
173+
- name: Should allow updating other fields with a previously valid logLevel outside current range
174+
initialCRDPatches:
175+
- op: remove
176+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/logLevel/maximum
177+
- op: remove
178+
path: /spec/versions/0/schema/openAPIV3Schema/properties/spec/properties/logLevel/minimum
179+
initial: |
180+
apiVersion: machineconfiguration.openshift.io/v1
181+
kind: KubeletConfig
182+
spec:
183+
logLevel: 15
184+
updated: |
185+
apiVersion: machineconfiguration.openshift.io/v1
186+
kind: KubeletConfig
187+
spec:
188+
logLevel: 15
189+
autoSizingReserved: true
190+
expected: |
191+
apiVersion: machineconfiguration.openshift.io/v1
192+
kind: KubeletConfig
193+
spec:
194+
logLevel: 15
195+
autoSizingReserved: true

machineconfiguration/v1/types.go

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -737,27 +737,42 @@ type KubeletConfig struct {
737737
Status KubeletConfigStatus `json:"status"`
738738
}
739739

740-
// KubeletConfigSpec defines the desired state of KubeletConfig
740+
// KubeletConfigSpec configures the kubelet running on cluster nodes.
741741
type KubeletConfigSpec struct {
742+
// autoSizingReserved controls whether system-reserved CPU and memory are automatically
743+
// calculated based on each node's installed capacity. When enabled, prevents node failure
744+
// from resource starvation of system components (kubelet, CRI-O) without manual configuration.
745+
// When omitted, this means the user has no opinion and the platform is left to choose a reasonable default,
746+
// which is subject to change over time. The current default is true for worker nodes and false for control plane nodes.
747+
// When set to false, automatic resource reservation is disabled and manual settings must be configured.
742748
// +optional
743749
AutoSizingReserved *bool `json:"autoSizingReserved,omitempty"`
750+
// logLevel sets the kubelet log verbosity, controlling the amount of detail in kubelet logs.
751+
// Valid values range from 0 (minimal logging) to 10 (maximum verbosity with trace-level detail).
752+
// Higher log levels may impact node performance. When omitted, the platform chooses a reasonable default,
753+
// which is subject to change over time. The current default is 2 (standard informational logging).
754+
// +kubebuilder:validation:Minimum=0
755+
// +kubebuilder:validation:Maximum=10
744756
// +optional
745757
LogLevel *int32 `json:"logLevel,omitempty"`
746758

747-
// machineConfigPoolSelector selects which pools the KubeletConfig shoud apply to.
748-
// A nil selector will result in no pools being selected.
759+
// machineConfigPoolSelector selects which pools the KubeletConfig should apply to.
760+
// A nil selector results in no pools being selected, meaning this kubelet configuration
761+
// will not be applied to any nodes in the cluster.
749762
// +optional
750763
MachineConfigPoolSelector *metav1.LabelSelector `json:"machineConfigPoolSelector,omitempty"`
751-
// kubeletConfig fields are defined in kubernetes upstream. Please refer to the types defined in the version/commit used by
752-
// OpenShift of the upstream kubernetes. It's important to note that, since the fields of the kubelet configuration are directly fetched from
753-
// upstream the validation of those values is handled directly by the kubelet. Please refer to the upstream version of the relevant kubernetes
754-
// for the valid values of these fields. Invalid values of the kubelet configuration fields may render cluster nodes unusable.
764+
// kubeletConfig contains upstream Kubernetes kubelet configuration fields.
765+
// Values are validated by the kubelet itself. Invalid values may render nodes unusable.
766+
// Refer to OpenShift documentation for the Kubernetes version corresponding to your
767+
// OpenShift release to find valid kubelet configuration options.
755768
// +optional
756769
KubeletConfig *runtime.RawExtension `json:"kubeletConfig,omitempty"`
757770

758-
// If unset, the default is based on the apiservers.config.openshift.io/cluster resource.
759-
// Note that only Old and Intermediate profiles are currently supported, and
760-
// the maximum available minTLSVersion is VersionTLS12.
771+
// tlsSecurityProfile configures TLS settings for the kubelet.
772+
// When omitted, the TLS configuration defaults to the value from apiservers.config.openshift.io/cluster.
773+
// When specified, the type field can be set to either "Old" or "Intermediate", or omitted for backward compatibility.
774+
// Modern and Custom TLS profiles are not supported for kubelet; maximum minTLSVersion is VersionTLS12.
775+
// +kubebuilder:validation:XValidation:rule="!has(self.type) || self.type == 'Old' || self.type == 'Intermediate'",message="only Old and Intermediate TLS profiles are supported for kubelet"
761776
// +optional
762777
TLSSecurityProfile *configv1.TLSSecurityProfile `json:"tlsSecurityProfile,omitempty"`
763778
}

machineconfiguration/v1/zz_generated.crd-manifests/0000_80_machine-config_01_kubeletconfigs.crd.yaml

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,37 @@ spec:
4747
description: spec contains the desired kubelet configuration.
4848
properties:
4949
autoSizingReserved:
50+
description: |-
51+
autoSizingReserved controls whether system-reserved CPU and memory are automatically
52+
calculated based on each node's installed capacity. When enabled, prevents node failure
53+
from resource starvation of system components (kubelet, CRI-O) without manual configuration.
54+
When omitted, this means the user has no opinion and the platform is left to choose a reasonable default,
55+
which is subject to change over time. The current default is true for worker nodes and false for control plane nodes.
56+
When set to false, automatic resource reservation is disabled and manual settings must be configured.
5057
type: boolean
5158
kubeletConfig:
5259
description: |-
53-
kubeletConfig fields are defined in kubernetes upstream. Please refer to the types defined in the version/commit used by
54-
OpenShift of the upstream kubernetes. It's important to note that, since the fields of the kubelet configuration are directly fetched from
55-
upstream the validation of those values is handled directly by the kubelet. Please refer to the upstream version of the relevant kubernetes
56-
for the valid values of these fields. Invalid values of the kubelet configuration fields may render cluster nodes unusable.
60+
kubeletConfig contains upstream Kubernetes kubelet configuration fields.
61+
Values are validated by the kubelet itself. Invalid values may render nodes unusable.
62+
Refer to OpenShift documentation for the Kubernetes version corresponding to your
63+
OpenShift release to find valid kubelet configuration options.
5764
type: object
5865
x-kubernetes-preserve-unknown-fields: true
5966
logLevel:
67+
description: |-
68+
logLevel sets the kubelet log verbosity, controlling the amount of detail in kubelet logs.
69+
Valid values range from 0 (minimal logging) to 10 (maximum verbosity with trace-level detail).
70+
Higher log levels may impact node performance. When omitted, the platform chooses a reasonable default,
71+
which is subject to change over time. The current default is 2 (standard informational logging).
6072
format: int32
73+
maximum: 10
74+
minimum: 0
6175
type: integer
6276
machineConfigPoolSelector:
6377
description: |-
64-
machineConfigPoolSelector selects which pools the KubeletConfig shoud apply to.
65-
A nil selector will result in no pools being selected.
78+
machineConfigPoolSelector selects which pools the KubeletConfig should apply to.
79+
A nil selector results in no pools being selected, meaning this kubelet configuration
80+
will not be applied to any nodes in the cluster.
6681
properties:
6782
matchExpressions:
6883
description: matchExpressions is a list of label selector requirements.
@@ -109,9 +124,10 @@ spec:
109124
x-kubernetes-map-type: atomic
110125
tlsSecurityProfile:
111126
description: |-
112-
If unset, the default is based on the apiservers.config.openshift.io/cluster resource.
113-
Note that only Old and Intermediate profiles are currently supported, and
114-
the maximum available minTLSVersion is VersionTLS12.
127+
tlsSecurityProfile configures TLS settings for the kubelet.
128+
When omitted, the TLS configuration defaults to the value from apiservers.config.openshift.io/cluster.
129+
When specified, the type field can be set to either "Old" or "Intermediate", or omitted for backward compatibility.
130+
Modern and Custom TLS profiles are not supported for kubelet; maximum minTLSVersion is VersionTLS12.
115131
properties:
116132
custom:
117133
description: |-
@@ -240,6 +256,10 @@ spec:
240256
- Custom
241257
type: string
242258
type: object
259+
x-kubernetes-validations:
260+
- message: only Old and Intermediate TLS profiles are supported for
261+
kubelet
262+
rule: '!has(self.type) || self.type == ''Old'' || self.type == ''Intermediate'''
243263
type: object
244264
status:
245265
description: status contains observed information about the kubelet configuration.

0 commit comments

Comments
 (0)