diff --git a/example/v1/tests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml b/example/v1/tests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml index 2ff4c005863..0047620141a 100644 --- a/example/v1/tests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml +++ b/example/v1/tests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml @@ -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: | diff --git a/example/v1/types_stable.go b/example/v1/types_stable.go index 1b394f3ad24..74963afff73 100644 --- a/example/v1/types_stable.go +++ b/example/v1/types_stable.go @@ -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 @@ -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 diff --git a/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-CustomNoUpgrade.crd.yaml b/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-CustomNoUpgrade.crd.yaml index 575b86b1870..2de7a643e7e 100644 --- a/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-CustomNoUpgrade.crd.yaml +++ b/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-CustomNoUpgrade.crd.yaml @@ -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. diff --git a/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-Default.crd.yaml b/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-Default.crd.yaml index 2d65bba1c42..948bf74fe5c 100644 --- a/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-Default.crd.yaml +++ b/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-Default.crd.yaml @@ -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. diff --git a/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-DevPreviewNoUpgrade.crd.yaml b/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-DevPreviewNoUpgrade.crd.yaml index 15644db9519..99b8d38a81d 100644 --- a/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-DevPreviewNoUpgrade.crd.yaml +++ b/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-DevPreviewNoUpgrade.crd.yaml @@ -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. diff --git a/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-TechPreviewNoUpgrade.crd.yaml b/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-TechPreviewNoUpgrade.crd.yaml index a52efe94dfc..f700b43c4a7 100644 --- a/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-TechPreviewNoUpgrade.crd.yaml +++ b/example/v1/zz_generated.crd-manifests/0000_50_my-operator_01_stableconfigtypes-TechPreviewNoUpgrade.crd.yaml @@ -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. diff --git a/example/v1/zz_generated.deepcopy.go b/example/v1/zz_generated.deepcopy.go index 6b441392db3..6ff7efdad06 100644 --- a/example/v1/zz_generated.deepcopy.go +++ b/example/v1/zz_generated.deepcopy.go @@ -36,6 +36,47 @@ func (in *CELUnion) DeepCopy() *CELUnion { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EscapingExamples) DeepCopyInto(out *EscapingExamples) { + *out = *in + if in.EscapingTestPattern != nil { + in, out := &in.EscapingTestPattern, &out.EscapingTestPattern + *out = new(string) + **out = **in + } + if in.EscapingTestPatternQuoted != nil { + in, out := &in.EscapingTestPatternQuoted, &out.EscapingTestPatternQuoted + *out = new(string) + **out = **in + } + if in.EscapingTestCELQuoted != nil { + in, out := &in.EscapingTestCELQuoted, &out.EscapingTestCELQuoted + *out = new(string) + **out = **in + } + if in.EscapingTestCELRaw != nil { + in, out := &in.EscapingTestCELRaw, &out.EscapingTestCELRaw + *out = new(string) + **out = **in + } + if in.EscapingTestCELRawPrefix != nil { + in, out := &in.EscapingTestCELRawPrefix, &out.EscapingTestCELRawPrefix + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EscapingExamples. +func (in *EscapingExamples) DeepCopy() *EscapingExamples { + if in == nil { + return nil + } + out := new(EscapingExamples) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *EvolvingUnion) DeepCopyInto(out *EvolvingUnion) { *out = *in @@ -129,6 +170,11 @@ func (in *StableConfigTypeSpec) DeepCopyInto(out *StableConfigTypeSpec) { copy(*out, *in) } in.SubnetsWithExclusions.DeepCopyInto(&out.SubnetsWithExclusions) + if in.EscapingExamples != nil { + in, out := &in.EscapingExamples, &out.EscapingExamples + *out = new(EscapingExamples) + (*in).DeepCopyInto(*out) + } return } diff --git a/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml b/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml index 6b0412b14c4..13cd3a11808 100644 --- a/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml +++ b/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/AAA_ungated.yaml @@ -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. diff --git a/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/Example+Example2.yaml b/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/Example+Example2.yaml index edd053058bf..58c21e95a46 100644 --- a/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/Example+Example2.yaml +++ b/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/Example+Example2.yaml @@ -80,6 +80,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. diff --git a/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/Example.yaml b/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/Example.yaml index 26ec0fa19b2..d9fe02c5cf5 100644 --- a/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/Example.yaml +++ b/example/v1/zz_generated.featuregated-crd-manifests/stableconfigtypes.example.openshift.io/Example.yaml @@ -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. diff --git a/example/v1/zz_generated.swagger_doc_generated.go b/example/v1/zz_generated.swagger_doc_generated.go index 6dd73b7f181..e21b52bb19c 100644 --- a/example/v1/zz_generated.swagger_doc_generated.go +++ b/example/v1/zz_generated.swagger_doc_generated.go @@ -22,6 +22,19 @@ func (CELUnion) SwaggerDoc() map[string]string { return map_CELUnion } +var map_EscapingExamples = map[string]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.", + "escapingTestPattern": "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.", + "escapingTestPatternQuoted": "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.", + "escapingTestCELQuoted": "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.", + "escapingTestCELRaw": "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.", + "escapingTestCELRawPrefix": "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.", +} + +func (EscapingExamples) SwaggerDoc() map[string]string { + return map_EscapingExamples +} + var map_EvolvingUnion = map[string]string{ "type": "type is the discriminator. It has different values for Default and for TechPreviewNoUpgrade", } @@ -63,6 +76,7 @@ var map_StableConfigTypeSpec = map[string]string{ "set": "set demonstrates how to define and validate set of strings", "subdomainNameField": "subdomainNameField represents a kubenetes name field. The intention is that it validates the name in the same way metadata.Name is validated. That is, it is a DNS-1123 subdomain.", "subnetsWithExclusions": "subnetsWithExclusions demonstrates how to validate a list of subnets with exclusions", + "escapingExamples": "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.", } func (StableConfigTypeSpec) SwaggerDoc() map[string]string { diff --git a/openapi/generated_openapi/zz_generated.openapi.go b/openapi/generated_openapi/zz_generated.openapi.go index 716ae1470c9..9391f5435d7 100644 --- a/openapi/generated_openapi/zz_generated.openapi.go +++ b/openapi/generated_openapi/zz_generated.openapi.go @@ -532,6 +532,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/openshift/api/console/v1.Link": schema_openshift_api_console_v1_Link(ref), "github.com/openshift/api/console/v1.NamespaceDashboardSpec": schema_openshift_api_console_v1_NamespaceDashboardSpec(ref), "github.com/openshift/api/example/v1.CELUnion": schema_openshift_api_example_v1_CELUnion(ref), + "github.com/openshift/api/example/v1.EscapingExamples": schema_openshift_api_example_v1_EscapingExamples(ref), "github.com/openshift/api/example/v1.EvolvingUnion": schema_openshift_api_example_v1_EvolvingUnion(ref), "github.com/openshift/api/example/v1.StableConfigType": schema_openshift_api_example_v1_StableConfigType(ref), "github.com/openshift/api/example/v1.StableConfigTypeList": schema_openshift_api_example_v1_StableConfigTypeList(ref), @@ -25731,6 +25732,54 @@ func schema_openshift_api_example_v1_CELUnion(ref common.ReferenceCallback) comm } } +func schema_openshift_api_example_v1_EscapingExamples(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "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: []string{"object"}, + Properties: map[string]spec.Schema{ + "escapingTestPattern": { + SchemaProps: spec.SchemaProps{ + 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.", + Type: []string{"string"}, + Format: "", + }, + }, + "escapingTestPatternQuoted": { + SchemaProps: spec.SchemaProps{ + 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.", + Type: []string{"string"}, + Format: "", + }, + }, + "escapingTestCELQuoted": { + SchemaProps: spec.SchemaProps{ + 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.", + Type: []string{"string"}, + Format: "", + }, + }, + "escapingTestCELRaw": { + SchemaProps: spec.SchemaProps{ + 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.", + Type: []string{"string"}, + Format: "", + }, + }, + "escapingTestCELRawPrefix": { + SchemaProps: spec.SchemaProps{ + 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.", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + } +} + func schema_openshift_api_example_v1_EvolvingUnion(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -25962,12 +26011,18 @@ func schema_openshift_api_example_v1_StableConfigTypeSpec(ref common.ReferenceCa Ref: ref("github.com/openshift/api/example/v1.SubnetsWithExclusions"), }, }, + "escapingExamples": { + SchemaProps: spec.SchemaProps{ + 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.", + Ref: ref("github.com/openshift/api/example/v1.EscapingExamples"), + }, + }, }, Required: []string{"immutableField"}, }, }, Dependencies: []string{ - "github.com/openshift/api/example/v1.CELUnion", "github.com/openshift/api/example/v1.EvolvingUnion", "github.com/openshift/api/example/v1.SubnetsWithExclusions"}, + "github.com/openshift/api/example/v1.CELUnion", "github.com/openshift/api/example/v1.EscapingExamples", "github.com/openshift/api/example/v1.EvolvingUnion", "github.com/openshift/api/example/v1.SubnetsWithExclusions"}, } }