Skip to content

Commit 80d1f5c

Browse files
Merge pull request #2570 from openshift-cloud-team/format-marker-examples
Add test cases for all supported format markers
2 parents 5c461e2 + b69d477 commit 80d1f5c

File tree

12 files changed

+2022
-1
lines changed

12 files changed

+2022
-1
lines changed

example/v1/tests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml

Lines changed: 644 additions & 0 deletions
Large diffs are not rendered by default.

example/v1/types_stable.go

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ type StableConfigTypeSpec struct {
100100
// subnetsWithExclusions demonstrates how to validate a list of subnets with exclusions
101101
// +optional
102102
SubnetsWithExclusions SubnetsWithExclusions `json:"subnetsWithExclusions,omitempty"`
103+
104+
// formatMarkerExamples demonstrates all Kubebuilder Format markers supported as of Kubernetes 1.33.
105+
// This field serves as a comprehensive reference for format marker validation.
106+
// +optional
107+
FormatMarkerExamples *FormatMarkerExamples `json:"formatMarkerExamples,omitempty"`
103108
}
104109

105110
// SetValue defines the types allowed in string set type
@@ -208,6 +213,157 @@ type SubnetsWithExclusions struct {
208213
// +kubebuilder:validation:MaxLength:=43
209214
type CIDR string
210215

216+
// FormatMarkerExamples demonstrates all Kubebuilder Format markers supported as of Kubernetes 1.33.
217+
// This struct provides a comprehensive reference for format marker validation.
218+
// Each field uses a different format marker to validate its value.
219+
type FormatMarkerExamples struct {
220+
// ipv4Address must be a valid IPv4 address in dotted-quad notation.
221+
// Valid values range from 0.0.0.0 to 255.255.255.255 (e.g., 192.168.1.1).
222+
//
223+
// Use of Format=ipv4 is not recommended due to CVE-2021-29923 and CVE-2024-24790.
224+
// Instead, use the CEL expression `isIP(self) && ip(self).family() == 4` to validate IPv4 addresses.
225+
//
226+
// +kubebuilder:validation:Format=ipv4
227+
// +kubebuilder:validation:MinLength=1
228+
// +kubebuilder:validation:MaxLength=15
229+
// +optional
230+
IPv4Address string `json:"ipv4Address,omitempty"`
231+
232+
// ipv6Address must be a valid IPv6 address.
233+
// Valid examples include full form (2001:0db8:0000:0000:0000:0000:0000:0001) or compressed form (2001:db8::1 or ::1).
234+
//
235+
// Use of Format=ipv6 is not recommended due to CVE-2021-29923 and CVE-2024-24790.
236+
// Instead, use the CEL expression `isIP(self) && ip(self).family() == 6` to validate IPv6 addresses.
237+
//
238+
// +kubebuilder:validation:Format=ipv6
239+
// +kubebuilder:validation:MinLength=1
240+
// +kubebuilder:validation:MaxLength=45
241+
// +optional
242+
IPv6Address string `json:"ipv6Address,omitempty"`
243+
244+
// cidrNotation must be a valid CIDR notation IP address range.
245+
// Valid examples include IPv4 CIDR (10.0.0.0/8, 192.168.1.0/24) or IPv6 CIDR (fd00::/8, 2001:db8::/32).
246+
//
247+
// Use of Format=cidr is not recommended due to CVE-2021-29923 and CVE-2024-24790.
248+
// Instead, use the CEL expression `isCIDR(self)` to validate CIDR notation.
249+
// Additionally, use `isCIDR(self) && cidr(self).ip().family() == X` to validate IPvX specifically.
250+
//
251+
// +kubebuilder:validation:Format=cidr
252+
// +kubebuilder:validation:MinLength=1
253+
// +kubebuilder:validation:MaxLength=49
254+
// +optional
255+
CIDRNotation string `json:"cidrNotation,omitempty"`
256+
257+
// uriField must be a valid URI following RFC 3986 syntax.
258+
// Valid examples include https://example.com/path?query=value or /absolute-path.
259+
// +kubebuilder:validation:Format=uri
260+
// +kubebuilder:validation:MinLength=1
261+
// +kubebuilder:validation:MaxLength=2048
262+
// +optional
263+
URIField string `json:"uriField,omitempty"`
264+
265+
// emailAddress must be a valid email address.
266+
// Valid examples include [email protected] or [email protected].
267+
// +kubebuilder:validation:Format=email
268+
// +kubebuilder:validation:MinLength=1
269+
// +kubebuilder:validation:MaxLength=254
270+
// +optional
271+
EmailAddress string `json:"emailAddress,omitempty"`
272+
273+
// hostnameField must be a valid Internet hostname per RFC 1034.
274+
// Valid examples include example.com, api.example.com, or my-service.
275+
// +kubebuilder:validation:Format=hostname
276+
// +kubebuilder:validation:MinLength=1
277+
// +kubebuilder:validation:MaxLength=253
278+
// +optional
279+
HostnameField string `json:"hostnameField,omitempty"`
280+
281+
// macAddress must be a valid MAC address.
282+
// Valid examples include 00:1A:2B:3C:4D:5E or 00-1A-2B-3C-4D-5E.
283+
// +kubebuilder:validation:Format=mac
284+
// +kubebuilder:validation:MinLength=1
285+
// +kubebuilder:validation:MaxLength=17
286+
// +optional
287+
MACAddress string `json:"macAddress,omitempty"`
288+
289+
// uuidField must be a valid UUID (any version) in 8-4-4-4-12 format.
290+
// Valid examples include 550e8400-e29b-41d4-a716-446655440000 or 123e4567-e89b-12d3-a456-426614174000.
291+
// +kubebuilder:validation:Format=uuid
292+
// +kubebuilder:validation:MinLength=36
293+
// +kubebuilder:validation:MaxLength=36
294+
// +optional
295+
UUIDField string `json:"uuidField,omitempty"`
296+
297+
// uuid3Field must be a valid UUID version 3 (MD5 hash-based).
298+
// Version 3 UUIDs are generated using MD5 hashing of a namespace and name.
299+
// Valid example: a3bb189e-8bf9-3888-9912-ace4e6543002.
300+
// +kubebuilder:validation:Format=uuid3
301+
// +kubebuilder:validation:MinLength=36
302+
// +kubebuilder:validation:MaxLength=36
303+
// +optional
304+
UUID3Field string `json:"uuid3Field,omitempty"`
305+
306+
// uuid4Field must be a valid UUID version 4 (random).
307+
// Version 4 UUIDs are randomly generated.
308+
// Valid example: 550e8400-e29b-41d4-a716-446655440000.
309+
// +kubebuilder:validation:Format=uuid4
310+
// +kubebuilder:validation:MinLength=36
311+
// +kubebuilder:validation:MaxLength=36
312+
// +optional
313+
UUID4Field string `json:"uuid4Field,omitempty"`
314+
315+
// uuid5Field must be a valid UUID version 5 (SHA-1 hash-based).
316+
// Version 5 UUIDs are generated using SHA-1 hashing of a namespace and name.
317+
// Valid example: 74738ff5-5367-5958-9aee-98fffdcd1876.
318+
// +kubebuilder:validation:Format=uuid5
319+
// +kubebuilder:validation:MinLength=36
320+
// +kubebuilder:validation:MaxLength=36
321+
// +optional
322+
UUID5Field string `json:"uuid5Field,omitempty"`
323+
324+
// dateField must be a valid date in RFC 3339 full-date format (YYYY-MM-DD).
325+
// Valid examples include 2024-01-15 or 2023-12-31.
326+
// +kubebuilder:validation:Format=date
327+
// +kubebuilder:validation:MinLength=10
328+
// +kubebuilder:validation:MaxLength=10
329+
// +optional
330+
DateField string `json:"dateField,omitempty"`
331+
332+
// dateTimeField must be a valid RFC 3339 date-time.
333+
// Valid examples include 2024-01-15T14:30:00Z, 2024-01-15T14:30:00+00:00, or 2024-01-15T14:30:00.123Z.
334+
// +kubebuilder:validation:Format=date-time
335+
// +kubebuilder:validation:MinLength=20
336+
// +kubebuilder:validation:MaxLength=35
337+
// +optional
338+
DateTimeField string `json:"dateTimeField,omitempty"`
339+
340+
// durationField must be a valid duration string parseable by Go's time.ParseDuration.
341+
// Valid time units are ns, us (or µs), ms, s, m, h.
342+
// Valid examples include 30s, 5m, 1h30m, 100ms, or 1h.
343+
// +kubebuilder:validation:Format=duration
344+
// +kubebuilder:validation:MinLength=1
345+
// +kubebuilder:validation:MaxLength=255
346+
// +optional
347+
DurationField string `json:"durationField,omitempty"`
348+
349+
// base64Data must be valid base64-encoded data.
350+
// Valid examples include aGVsbG8= (encodes "hello") or SGVsbG8gV29ybGQh (encodes "Hello World!").
351+
// +kubebuilder:validation:Format=byte
352+
// +kubebuilder:validation:MinLength=1
353+
// +kubebuilder:validation:MaxLength=2048
354+
// +optional
355+
Base64Data string `json:"base64Data,omitempty"`
356+
357+
// passwordField is a marker for sensitive data.
358+
// Note that the password format marker does not perform any actual validation - it accepts any string value.
359+
// This marker is primarily used to signal that the field contains sensitive information.
360+
// +kubebuilder:validation:Format=password
361+
// +kubebuilder:validation:MinLength=1
362+
// +kubebuilder:validation:MaxLength=255
363+
// +optional
364+
PasswordField string `json:"passwordField,omitempty"`
365+
}
366+
211367
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
212368
// +openshift:compatibility-gen:level=1
213369

example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-CustomNoUpgrade.crd.yaml

Lines changed: 149 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,155 @@ spec:
103103
required:
104104
- type
105105
type: object
106+
formatMarkerExamples:
107+
description: |-
108+
formatMarkerExamples demonstrates all Kubebuilder Format markers supported as of Kubernetes 1.33.
109+
This field serves as a comprehensive reference for format marker validation.
110+
properties:
111+
base64Data:
112+
description: |-
113+
base64Data must be valid base64-encoded data.
114+
Valid examples include aGVsbG8= (encodes "hello") or SGVsbG8gV29ybGQh (encodes "Hello World!").
115+
format: byte
116+
maxLength: 2048
117+
minLength: 1
118+
type: string
119+
cidrNotation:
120+
description: |-
121+
cidrNotation must be a valid CIDR notation IP address range.
122+
Valid examples include IPv4 CIDR (10.0.0.0/8, 192.168.1.0/24) or IPv6 CIDR (fd00::/8, 2001:db8::/32).
123+
124+
Use of Format=cidr is not recommended due to CVE-2021-29923 and CVE-2024-24790.
125+
Instead, use the CEL expression `isCIDR(self)` to validate CIDR notation.
126+
Additionally, use `isCIDR(self) && cidr(self).ip().family() == X` to validate IPvX specifically.
127+
format: cidr
128+
maxLength: 49
129+
minLength: 1
130+
type: string
131+
dateField:
132+
description: |-
133+
dateField must be a valid date in RFC 3339 full-date format (YYYY-MM-DD).
134+
Valid examples include 2024-01-15 or 2023-12-31.
135+
format: date
136+
maxLength: 10
137+
minLength: 10
138+
type: string
139+
dateTimeField:
140+
description: |-
141+
dateTimeField must be a valid RFC 3339 date-time.
142+
Valid examples include 2024-01-15T14:30:00Z, 2024-01-15T14:30:00+00:00, or 2024-01-15T14:30:00.123Z.
143+
format: date-time
144+
maxLength: 35
145+
minLength: 20
146+
type: string
147+
durationField:
148+
description: |-
149+
durationField must be a valid duration string parseable by Go's time.ParseDuration.
150+
Valid time units are ns, us (or µs), ms, s, m, h.
151+
Valid examples include 30s, 5m, 1h30m, 100ms, or 1h.
152+
format: duration
153+
maxLength: 255
154+
minLength: 1
155+
type: string
156+
emailAddress:
157+
description: |-
158+
emailAddress must be a valid email address.
159+
Valid examples include [email protected] or [email protected].
160+
format: email
161+
maxLength: 254
162+
minLength: 1
163+
type: string
164+
hostnameField:
165+
description: |-
166+
hostnameField must be a valid Internet hostname per RFC 1034.
167+
Valid examples include example.com, api.example.com, or my-service.
168+
format: hostname
169+
maxLength: 253
170+
minLength: 1
171+
type: string
172+
ipv4Address:
173+
description: |-
174+
ipv4Address must be a valid IPv4 address in dotted-quad notation.
175+
Valid values range from 0.0.0.0 to 255.255.255.255 (e.g., 192.168.1.1).
176+
177+
Use of Format=ipv4 is not recommended due to CVE-2021-29923 and CVE-2024-24790.
178+
Instead, use the CEL expression `isIP(self) && ip(self).family() == 4` to validate IPv4 addresses.
179+
format: ipv4
180+
maxLength: 15
181+
minLength: 1
182+
type: string
183+
ipv6Address:
184+
description: |-
185+
ipv6Address must be a valid IPv6 address.
186+
Valid examples include full form (2001:0db8:0000:0000:0000:0000:0000:0001) or compressed form (2001:db8::1 or ::1).
187+
188+
Use of Format=ipv6 is not recommended due to CVE-2021-29923 and CVE-2024-24790.
189+
Instead, use the CEL expression `isIP(self) && ip(self).family() == 6` to validate IPv6 addresses.
190+
format: ipv6
191+
maxLength: 45
192+
minLength: 1
193+
type: string
194+
macAddress:
195+
description: |-
196+
macAddress must be a valid MAC address.
197+
Valid examples include 00:1A:2B:3C:4D:5E or 00-1A-2B-3C-4D-5E.
198+
format: mac
199+
maxLength: 17
200+
minLength: 1
201+
type: string
202+
passwordField:
203+
description: |-
204+
passwordField is a marker for sensitive data.
205+
Note that the password format marker does not perform any actual validation - it accepts any string value.
206+
This marker is primarily used to signal that the field contains sensitive information.
207+
format: password
208+
maxLength: 255
209+
minLength: 1
210+
type: string
211+
uriField:
212+
description: |-
213+
uriField must be a valid URI following RFC 3986 syntax.
214+
Valid examples include https://example.com/path?query=value or /absolute-path.
215+
format: uri
216+
maxLength: 2048
217+
minLength: 1
218+
type: string
219+
uuid3Field:
220+
description: |-
221+
uuid3Field must be a valid UUID version 3 (MD5 hash-based).
222+
Version 3 UUIDs are generated using MD5 hashing of a namespace and name.
223+
Valid example: a3bb189e-8bf9-3888-9912-ace4e6543002.
224+
format: uuid3
225+
maxLength: 36
226+
minLength: 36
227+
type: string
228+
uuid4Field:
229+
description: |-
230+
uuid4Field must be a valid UUID version 4 (random).
231+
Version 4 UUIDs are randomly generated.
232+
Valid example: 550e8400-e29b-41d4-a716-446655440000.
233+
format: uuid4
234+
maxLength: 36
235+
minLength: 36
236+
type: string
237+
uuid5Field:
238+
description: |-
239+
uuid5Field must be a valid UUID version 5 (SHA-1 hash-based).
240+
Version 5 UUIDs are generated using SHA-1 hashing of a namespace and name.
241+
Valid example: 74738ff5-5367-5958-9aee-98fffdcd1876.
242+
format: uuid5
243+
maxLength: 36
244+
minLength: 36
245+
type: string
246+
uuidField:
247+
description: |-
248+
uuidField must be a valid UUID (any version) in 8-4-4-4-12 format.
249+
Valid examples include 550e8400-e29b-41d4-a716-446655440000 or 123e4567-e89b-12d3-a456-426614174000.
250+
format: uuid
251+
maxLength: 36
252+
minLength: 36
253+
type: string
254+
type: object
106255
immutableField:
107256
description: |-
108257
immutableField is a field that is immutable once the object has been created.

0 commit comments

Comments
 (0)