From 20d3ea37b205e7c6b7ffaf4078d0af6f3a5916fa Mon Sep 17 00:00:00 2001 From: Guilherme Cassolato Date: Fri, 20 Oct 2023 07:07:32 +0200 Subject: [PATCH] AuthPolicy CEL validation rules - Invalid targetRef.group - Invalid targetRef.kind - Route selectors not supported when targeting a Gateway Note: cannot set a validation rule for !has(spec.targetRef.namespace) || spec.targetRef.namespace == metadata.namespace, because Kubernetes does not allow accessing `metadata.namespace`. See https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/#validation-rules --- api/v1beta2/authpolicy_types.go | 9 ++++++ ...adrant-operator.clusterserviceversion.yaml | 2 +- .../manifests/kuadrant.io_authpolicies.yaml | 29 +++++++++++++++++++ .../crd/bases/kuadrant.io_authpolicies.yaml | 29 +++++++++++++++++++ 4 files changed, 68 insertions(+), 1 deletion(-) diff --git a/api/v1beta2/authpolicy_types.go b/api/v1beta2/authpolicy_types.go index 5cc3327f0..d2569624e 100644 --- a/api/v1beta2/authpolicy_types.go +++ b/api/v1beta2/authpolicy_types.go @@ -115,8 +115,17 @@ type CallbackSpec struct { CommonAuthRuleSpec `json:""` } +// +kubebuilder:validation:XValidation:rule="self.targetRef.kind != 'Gateway' || !has(self.routeSelectors)",message="route selectors not supported when targeting a Gateway" +// +kubebuilder:validation:XValidation:rule="self.targetRef.kind != 'Gateway' || !has(self.rules.authentication) || !self.rules.authentication.exists(x, has(self.rules.authentication[x].routeSelectors))",message="route selectors not supported when targeting a Gateway" +// +kubebuilder:validation:XValidation:rule="self.targetRef.kind != 'Gateway' || !has(self.rules.metadata) || !self.rules.metadata.exists(x, has(self.rules.metadata[x].routeSelectors))",message="route selectors not supported when targeting a Gateway" +// +kubebuilder:validation:XValidation:rule="self.targetRef.kind != 'Gateway' || !has(self.rules.authorization) || !self.rules.authorization.exists(x, has(self.rules.authorization[x].routeSelectors))",message="route selectors not supported when targeting a Gateway" +// +kubebuilder:validation:XValidation:rule="self.targetRef.kind != 'Gateway' || !has(self.rules.response) || !has(self.rules.response.success) || self.rules.response.success.headers.exists(x, has(self.rules.response.success.headers[x].routeSelectors))",message="route selectors not supported when targeting a Gateway" +// +kubebuilder:validation:XValidation:rule="self.targetRef.kind != 'Gateway' || !has(self.rules.response) || !has(self.rules.response.success) || self.rules.response.success.dynamicMetadata.exists(x, has(self.rules.response.success.dynamicMetadata[x].routeSelectors))",message="route selectors not supported when targeting a Gateway" +// +kubebuilder:validation:XValidation:rule="self.targetRef.kind != 'Gateway' || !has(self.rules.callbacks) || !self.rules.callbacks.exists(x, has(self.rules.callbacks[x].routeSelectors))",message="route selectors not supported when targeting a Gateway" type AuthPolicySpec struct { // TargetRef identifies an API object to apply policy to. + // +kubebuilder:validation:XValidation:rule="self.group == 'gateway.networking.k8s.io'",message="Invalid targetRef.group. The only supported value is 'gateway.networking.k8s.io'" + // +kubebuilder:validation:XValidation:rule="self.kind == 'HTTPRoute' || self.kind == 'Gateway'",message="Invalid targetRef.kind. The only supported values are 'HTTPRoute' and 'Gateway'" TargetRef gatewayapiv1alpha2.PolicyTargetReference `json:"targetRef"` // Top-level route selectors. diff --git a/bundle/manifests/kuadrant-operator.clusterserviceversion.yaml b/bundle/manifests/kuadrant-operator.clusterserviceversion.yaml index dee7c5b69..9efbcc92b 100644 --- a/bundle/manifests/kuadrant-operator.clusterserviceversion.yaml +++ b/bundle/manifests/kuadrant-operator.clusterserviceversion.yaml @@ -41,7 +41,7 @@ metadata: capabilities: Basic Install categories: Integration & Delivery containerImage: quay.io/kuadrant/kuadrant-operator:latest - createdAt: "2023-10-20T10:36:08Z" + createdAt: "2023-10-20T10:46:36Z" operators.operatorframework.io/builder: operator-sdk-v1.28.1 operators.operatorframework.io/project_layout: go.kubebuilder.io/v3 repository: https://github.com/Kuadrant/kuadrant-operator diff --git a/bundle/manifests/kuadrant.io_authpolicies.yaml b/bundle/manifests/kuadrant.io_authpolicies.yaml index 6e900f5d0..971f8e947 100644 --- a/bundle/manifests/kuadrant.io_authpolicies.yaml +++ b/bundle/manifests/kuadrant.io_authpolicies.yaml @@ -4121,6 +4121,12 @@ spec: - kind - name type: object + x-kubernetes-validations: + - message: Invalid targetRef.group. The only supported value is 'gateway.networking.k8s.io' + rule: self.group == 'gateway.networking.k8s.io' + - message: Invalid targetRef.kind. The only supported values are 'HTTPRoute' + and 'Gateway' + rule: self.kind == 'HTTPRoute' || self.kind == 'Gateway' when: description: Overall conditions for the AuthPolicy to be enforced. If omitted, the AuthPolicy will be enforced at all requests to the @@ -4177,6 +4183,29 @@ spec: required: - targetRef type: object + x-kubernetes-validations: + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.routeSelectors) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.authentication) + || !self.rules.authentication.exists(x, has(self.rules.authentication[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.metadata) + || !self.rules.metadata.exists(x, has(self.rules.metadata[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.authorization) + || !self.rules.authorization.exists(x, has(self.rules.authorization[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.response) + || !has(self.rules.response.success) || self.rules.response.success.headers.exists(x, + has(self.rules.response.success.headers[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.response) + || !has(self.rules.response.success) || self.rules.response.success.dynamicMetadata.exists(x, + has(self.rules.response.success.dynamicMetadata[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.callbacks) + || !self.rules.callbacks.exists(x, has(self.rules.callbacks[x].routeSelectors)) status: properties: conditions: diff --git a/config/crd/bases/kuadrant.io_authpolicies.yaml b/config/crd/bases/kuadrant.io_authpolicies.yaml index 319163dab..86765f134 100644 --- a/config/crd/bases/kuadrant.io_authpolicies.yaml +++ b/config/crd/bases/kuadrant.io_authpolicies.yaml @@ -4120,6 +4120,12 @@ spec: - kind - name type: object + x-kubernetes-validations: + - message: Invalid targetRef.group. The only supported value is 'gateway.networking.k8s.io' + rule: self.group == 'gateway.networking.k8s.io' + - message: Invalid targetRef.kind. The only supported values are 'HTTPRoute' + and 'Gateway' + rule: self.kind == 'HTTPRoute' || self.kind == 'Gateway' when: description: Overall conditions for the AuthPolicy to be enforced. If omitted, the AuthPolicy will be enforced at all requests to the @@ -4176,6 +4182,29 @@ spec: required: - targetRef type: object + x-kubernetes-validations: + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.routeSelectors) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.authentication) + || !self.rules.authentication.exists(x, has(self.rules.authentication[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.metadata) + || !self.rules.metadata.exists(x, has(self.rules.metadata[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.authorization) + || !self.rules.authorization.exists(x, has(self.rules.authorization[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.response) + || !has(self.rules.response.success) || self.rules.response.success.headers.exists(x, + has(self.rules.response.success.headers[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.response) + || !has(self.rules.response.success) || self.rules.response.success.dynamicMetadata.exists(x, + has(self.rules.response.success.dynamicMetadata[x].routeSelectors)) + - message: route selectors not supported when targeting a Gateway + rule: self.targetRef.kind != 'Gateway' || !has(self.rules.callbacks) + || !self.rules.callbacks.exists(x, has(self.rules.callbacks[x].routeSelectors)) status: properties: conditions: