Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,144 @@ tests:
requiredMember: foo
immutableField: foo
expectedError: "Invalid value: \"object\": requiredMember is required when type is RequiredMember, and forbidden otherwise"

# Escaping test fields - validating Pattern vs CEL escaping behavior
- name: Should accept valid value for escapingTestPattern (Pattern marker)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestPattern: "a123"
expected: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
nonZeroDefault: 8
escapingExamples:
escapingTestPattern: "a123"

- name: Should reject invalid value for escapingTestPattern (Pattern marker)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestPattern: "A123"
expectedError: "should match"

- name: Should accept valid value for escapingTestPatternQuoted (Pattern marker with quoted string)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestPatternQuoted: "b456"
expected: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
nonZeroDefault: 8
escapingExamples:
escapingTestPatternQuoted: "b456"

- name: Should reject invalid value for escapingTestPatternQuoted (Pattern marker with quoted string)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestPatternQuoted: "B456"
expectedError: "should match"

- name: Should accept valid value for escapingTestCELQuoted (CEL with quoted string)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestCELQuoted: "z99"
expected: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
nonZeroDefault: 8
escapingExamples:
escapingTestCELQuoted: "z99"

- name: Should reject invalid value for escapingTestCELQuoted (CEL with quoted string)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestCELQuoted: "123"
expectedError: "must match pattern with quoted string escaping"

- name: Should accept valid value for escapingTestCELRaw (CEL with raw string)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestCELRaw: "b456"
expected: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
nonZeroDefault: 8
escapingExamples:
escapingTestCELRaw: "b456"

- name: Should reject invalid value for escapingTestCELRaw (CEL with raw string)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestCELRaw: "B456"
expectedError: "must match pattern with raw string escaping"

# Tests for CEL raw string prefix (r'...')
- name: Should accept valid value for escapingTestCELRawPrefix (CEL raw string with r prefix)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestCELRawPrefix: "c789"
expected: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
nonZeroDefault: 8
escapingExamples:
escapingTestCELRawPrefix: "c789"

- name: Should reject invalid value for escapingTestCELRawPrefix (CEL raw string with r prefix)
initial: |
apiVersion: example.openshift.io/v1
kind: StableConfigType
spec:
immutableField: foo
escapingExamples:
escapingTestCELRawPrefix: "C789"
expectedError: "must match pattern with CEL raw string"

onUpdate:
- name: Should not allow changing an immutable field
initial: |
Expand Down
57 changes: 57 additions & 0 deletions example/v1/types_stable.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ type StableConfigTypeSpec struct {
// subnetsWithExclusions demonstrates how to validate a list of subnets with exclusions
// +optional
SubnetsWithExclusions SubnetsWithExclusions `json:"subnetsWithExclusions,omitempty"`

// escapingExamples demonstrates regex escaping requirements across different validation contexts.
// This field provides comprehensive examples of how to properly escape regex patterns
// depending on whether you're using Pattern markers or CEL expressions with various string types.
// +optional
EscapingExamples *EscapingExamples `json:"escapingExamples,omitempty"`
}

// SetValue defines the types allowed in string set type
Expand Down Expand Up @@ -208,6 +214,57 @@ type SubnetsWithExclusions struct {
// +kubebuilder:validation:MaxLength:=43
type CIDR string

// EscapingExamples demonstrates regex escaping requirements across different validation contexts.
// Each field validates the same pattern (lowercase letter + digits) but uses different
// string literal types, requiring different escaping.
type EscapingExamples struct {
// escapingTestPattern demonstrates use of the Pattern marker with raw string literal (backticks).
// Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
// Pattern uses raw string literal (backticks), so single backslash.
// +kubebuilder:validation:Pattern=`^[a-z]\d+$`
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=15
// +optional
EscapingTestPattern *string `json:"escapingTestPattern,omitempty"`

// escapingTestPatternQuoted demonstrates use of the Pattern marker with Go quoted string.
// Must match format: lowercase letter followed by one or more digits (e.g., "b456", "c789").
// Quoted strings interpret escape sequences, requiring double backslash for regex metacharacters.
// +kubebuilder:validation:Pattern="^[a-z]\\d+$"
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=15
// +optional
EscapingTestPatternQuoted *string `json:"escapingTestPatternQuoted,omitempty"`

// escapingTestCELQuoted demonstrates use of CEL .matches() with Go quoted string.
// Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
// Quoted strings require double backslash for regex metacharacters.
// +kubebuilder:validation:XValidation:rule="self.matches('^[a-z]\\\\d+$')",message="must match pattern with quoted string escaping"
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=15
// +optional
EscapingTestCELQuoted *string `json:"escapingTestCELQuoted,omitempty"`

// escapingTestCELRaw demonstrates use of CEL .matches() with raw string literal (backticks).
// Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
// Raw string literals (backticks) preserve backslashes literally, same as Pattern.
// +kubebuilder:validation:XValidation:rule=`self.matches('^[a-z]\\d+$')`,message="must match pattern with raw string escaping"
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=15
// +optional
EscapingTestCELRaw *string `json:"escapingTestCELRaw,omitempty"`

// escapingTestCELRawPrefix demonstrates use of CEL .matches() with raw
// string literal (backticks) + CEL raw string (r prefix).
// Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
// Tests whether CEL's r'...' raw string syntax reduces backslash requirements.
// +kubebuilder:validation:XValidation:rule=`self.matches(r'^[a-z]\d+$')`,message="must match pattern with CEL raw string"
// +kubebuilder:validation:MinLength=1
// +kubebuilder:validation:MaxLength=15
// +optional
EscapingTestCELRawPrefix *string `json:"escapingTestCELRawPrefix,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +openshift:compatibility-gen:level=1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,65 @@ spec:
description: coolNewField is a field that is for tech preview only. On
normal clusters this shouldn't be present
type: string
escapingExamples:
description: |-
escapingExamples demonstrates regex escaping requirements across different validation contexts.
This field provides comprehensive examples of how to properly escape regex patterns
depending on whether you're using Pattern markers or CEL expressions with various string types.
properties:
escapingTestCELQuoted:
description: |-
escapingTestCELQuoted demonstrates use of CEL .matches() with Go quoted string.
Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
Quoted strings require double backslash for regex metacharacters.
maxLength: 15
minLength: 1
type: string
x-kubernetes-validations:
- message: must match pattern with quoted string escaping
rule: self.matches('^[a-z]\\d+$')
escapingTestCELRaw:
description: |-
escapingTestCELRaw demonstrates use of CEL .matches() with raw string literal (backticks).
Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
Raw string literals (backticks) preserve backslashes literally, same as Pattern.
maxLength: 15
minLength: 1
type: string
x-kubernetes-validations:
- message: must match pattern with raw string escaping
rule: self.matches('^[a-z]\\d+$')
escapingTestCELRawPrefix:
description: |-
escapingTestCELRawPrefix demonstrates use of CEL .matches() with raw
string literal (backticks) + CEL raw string (r prefix).
Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
Tests whether CEL's r'...' raw string syntax reduces backslash requirements.
maxLength: 15
minLength: 1
type: string
x-kubernetes-validations:
- message: must match pattern with CEL raw string
rule: self.matches(r'^[a-z]\d+$')
escapingTestPattern:
description: |-
escapingTestPattern demonstrates use of the Pattern marker with raw string literal (backticks).
Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
Pattern uses raw string literal (backticks), so single backslash.
maxLength: 15
minLength: 1
pattern: ^[a-z]\d+$
type: string
escapingTestPatternQuoted:
description: |-
escapingTestPatternQuoted demonstrates use of the Pattern marker with Go quoted string.
Must match format: lowercase letter followed by one or more digits (e.g., "b456", "c789").
Quoted strings interpret escape sequences, requiring double backslash for regex metacharacters.
maxLength: 15
minLength: 1
pattern: ^[a-z]\d+$
type: string
type: object
evolvingCollection:
description: |-
evolvingCollection demonstrates how to have a collection where the maximum number of items varies on cluster type.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,65 @@ spec:
- message: optionalMember is forbidden when type is not OptionalMember
rule: 'has(self.type) && self.type == ''OptionalMember'' ? true
: !has(self.optionalMember)'
escapingExamples:
description: |-
escapingExamples demonstrates regex escaping requirements across different validation contexts.
This field provides comprehensive examples of how to properly escape regex patterns
depending on whether you're using Pattern markers or CEL expressions with various string types.
properties:
escapingTestCELQuoted:
description: |-
escapingTestCELQuoted demonstrates use of CEL .matches() with Go quoted string.
Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
Quoted strings require double backslash for regex metacharacters.
maxLength: 15
minLength: 1
type: string
x-kubernetes-validations:
- message: must match pattern with quoted string escaping
rule: self.matches('^[a-z]\\d+$')
escapingTestCELRaw:
description: |-
escapingTestCELRaw demonstrates use of CEL .matches() with raw string literal (backticks).
Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
Raw string literals (backticks) preserve backslashes literally, same as Pattern.
maxLength: 15
minLength: 1
type: string
x-kubernetes-validations:
- message: must match pattern with raw string escaping
rule: self.matches('^[a-z]\\d+$')
escapingTestCELRawPrefix:
description: |-
escapingTestCELRawPrefix demonstrates use of CEL .matches() with raw
string literal (backticks) + CEL raw string (r prefix).
Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
Tests whether CEL's r'...' raw string syntax reduces backslash requirements.
maxLength: 15
minLength: 1
type: string
x-kubernetes-validations:
- message: must match pattern with CEL raw string
rule: self.matches(r'^[a-z]\d+$')
escapingTestPattern:
description: |-
escapingTestPattern demonstrates use of the Pattern marker with raw string literal (backticks).
Must match format: lowercase letter followed by one or more digits (e.g., "a123", "z99").
Pattern uses raw string literal (backticks), so single backslash.
maxLength: 15
minLength: 1
pattern: ^[a-z]\d+$
type: string
escapingTestPatternQuoted:
description: |-
escapingTestPatternQuoted demonstrates use of the Pattern marker with Go quoted string.
Must match format: lowercase letter followed by one or more digits (e.g., "b456", "c789").
Quoted strings interpret escape sequences, requiring double backslash for regex metacharacters.
maxLength: 15
minLength: 1
pattern: ^[a-z]\d+$
type: string
type: object
evolvingCollection:
description: |-
evolvingCollection demonstrates how to have a collection where the maximum number of items varies on cluster type.
Expand Down
Loading