Skip to content
Merged
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
2 changes: 2 additions & 0 deletions api/v1alpha1/shared_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,13 +231,15 @@ type KubernetesContainerSpec struct {
// Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
// This field is mutually exclusive with ImageRepository.
//
// +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')",message="Image must include a tag and allowed characters only (e.g., 'repo:tag')."
// +optional
Image *string `json:"image,omitempty"`

// ImageRepository specifies the container image repository to be used without specifying a tag.
// The default tag will be used.
// This field is mutually exclusive with Image.
//
// +kubebuilder:validation:XValidation:rule="self.matches('^[a-zA-Z0-9._/-]+$')",message="ImageRepository must contain only allowed characters and must not include a tag or any colons."
// +optional
ImageRepository *string `json:"imageRepository,omitempty"`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -608,12 +608,20 @@ spec:
Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
This field is mutually exclusive with ImageRepository.
type: string
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
The default tag will be used.
This field is mutually exclusive with Image.
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
characters and must not include a tag or any colons.
rule: self.matches('^[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
Expand Down Expand Up @@ -4445,12 +4453,20 @@ spec:
Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
This field is mutually exclusive with ImageRepository.
type: string
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
The default tag will be used.
This field is mutually exclusive with Image.
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
characters and must not include a tag or any colons.
rule: self.matches('^[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -607,12 +607,20 @@ spec:
Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
This field is mutually exclusive with ImageRepository.
type: string
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
The default tag will be used.
This field is mutually exclusive with Image.
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
characters and must not include a tag or any colons.
rule: self.matches('^[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
Expand Down Expand Up @@ -4444,12 +4452,20 @@ spec:
Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
This field is mutually exclusive with ImageRepository.
type: string
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
The default tag will be used.
This field is mutually exclusive with Image.
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
characters and must not include a tag or any colons.
rule: self.matches('^[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
Expand Down
94 changes: 92 additions & 2 deletions test/cel-validation/envoyproxy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1545,7 +1545,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
},
},
{
desc: "valid: image set, imageRepository not set",
desc: "valid: image set with tag, imageRepository not set",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
Expand All @@ -1563,7 +1563,7 @@ func TestEnvoyProxyProvider(t *testing.T) {
wantErrors: []string{},
},
{
desc: "valid: imageRepository set, image not set",
desc: "valid: imageRepository set without tag, image not set",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
Expand Down Expand Up @@ -1599,6 +1599,96 @@ func TestEnvoyProxyProvider(t *testing.T) {
},
wantErrors: []string{"Either image or imageRepository can be set."},
},
{
desc: "invalid: image set without tag",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
Type: egv1a1.ProviderTypeKubernetes,
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
Container: &egv1a1.KubernetesContainerSpec{
Image: ptr.To("envoyproxy/envoy"),
},
},
},
},
}
},
wantErrors: []string{"Image must include a tag and allowed characters only (e.g., 'repo:tag')."},
},
{
desc: "invalid: image ends with colon",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
Type: egv1a1.ProviderTypeKubernetes,
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
Container: &egv1a1.KubernetesContainerSpec{
Image: ptr.To("envoyproxy/envoy:"),
},
},
},
},
}
},
wantErrors: []string{"Image must include a tag and allowed characters only (e.g., 'repo:tag')."},
},
{
desc: "invalid: image starts with colon",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
Type: egv1a1.ProviderTypeKubernetes,
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
Container: &egv1a1.KubernetesContainerSpec{
Image: ptr.To(":v1.25.2"),
},
},
},
},
}
},
wantErrors: []string{"Image must include a tag and allowed characters only (e.g., 'repo:tag')."},
},
{
desc: "invalid: image with multiple colons",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
Type: egv1a1.ProviderTypeKubernetes,
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
Container: &egv1a1.KubernetesContainerSpec{
Image: ptr.To("registry.com/envoy:v1.2.3:latest"),
},
},
},
},
}
},
wantErrors: []string{"Image must include a tag and allowed characters only (e.g., 'repo:tag')."},
},
{
desc: "invalid: imageRepository contains tag",
mutate: func(envoy *egv1a1.EnvoyProxy) {
envoy.Spec = egv1a1.EnvoyProxySpec{
Provider: &egv1a1.EnvoyProxyProvider{
Type: egv1a1.ProviderTypeKubernetes,
Kubernetes: &egv1a1.EnvoyProxyKubernetesProvider{
EnvoyDeployment: &egv1a1.KubernetesDeploymentSpec{
Container: &egv1a1.KubernetesContainerSpec{
ImageRepository: ptr.To("envoyproxy/envoy:v1.2.3"),
},
},
},
},
}
},
wantErrors: []string{"ImageRepository must contain only allowed characters and must not include a tag or any colons."},
},
}

for _, tc := range cases {
Expand Down
16 changes: 16 additions & 0 deletions test/helm/gateway-crds-helm/all.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -24189,12 +24189,20 @@ spec:
Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
This field is mutually exclusive with ImageRepository.
type: string
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
The default tag will be used.
This field is mutually exclusive with Image.
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
characters and must not include a tag or any colons.
rule: self.matches('^[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
Expand Down Expand Up @@ -28026,12 +28034,20 @@ spec:
Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
This field is mutually exclusive with ImageRepository.
type: string
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
The default tag will be used.
This field is mutually exclusive with Image.
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
characters and must not include a tag or any colons.
rule: self.matches('^[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
Expand Down
16 changes: 16 additions & 0 deletions test/helm/gateway-crds-helm/envoy-gateway-crds.out.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6877,12 +6877,20 @@ spec:
Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
This field is mutually exclusive with ImageRepository.
type: string
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
The default tag will be used.
This field is mutually exclusive with Image.
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
characters and must not include a tag or any colons.
rule: self.matches('^[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
Expand Down Expand Up @@ -10714,12 +10722,20 @@ spec:
Image specifies the EnvoyProxy container image to be used including a tag, instead of the default image.
This field is mutually exclusive with ImageRepository.
type: string
x-kubernetes-validations:
- message: Image must include a tag and allowed characters
only (e.g., 'repo:tag').
rule: self.matches('^[a-zA-Z0-9._/-]+:[a-zA-Z0-9._-]+$')
imageRepository:
description: |-
ImageRepository specifies the container image repository to be used without specifying a tag.
The default tag will be used.
This field is mutually exclusive with Image.
type: string
x-kubernetes-validations:
- message: ImageRepository must contain only allowed
characters and must not include a tag or any colons.
rule: self.matches('^[a-zA-Z0-9._/-]+$')
resources:
description: |-
Resources required by this container.
Expand Down