diff --git a/api/configuration/v1alpha1/kongpluginbinding_types.go b/api/configuration/v1alpha1/kongpluginbinding_types.go index c08113c2..0e9168ff 100644 --- a/api/configuration/v1alpha1/kongpluginbinding_types.go +++ b/api/configuration/v1alpha1/kongpluginbinding_types.go @@ -33,19 +33,22 @@ import ( // +kubebuilder:printcolumn:name="Plugin-kind",type=string,JSONPath=`.spec.pluginReference.kind`,description="Kind of the plugin" // +kubebuilder:printcolumn:name="Plugin-name",type=string,JSONPath=`.spec.pluginReference.name`,description="Name of the plugin" // +kubebuilder:printcolumn:name="Programmed",description="The Resource is Programmed",type=string,JSONPath=`.status.conditions[?(@.type=='Programmed')].status` -// +kubebuilder:validation:XValidation:rule="(has(self.spec.kong.consumerRef) && has(self.spec.kong.routeRef) && has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.consumerGroupRef) && has(self.spec.kong.serviceRef) && has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerRef)) || (has(self.spec.kong.consumerRef) && has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerGroupRef) && !has(self.spec.kong.serviceRef)) || (has(self.spec.kong.consumerRef) && has(self.spec.kong.serviceRef) && !has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.consumerGroupRef) && has(self.spec.kong.routeRef) && !has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerRef)) || (has(self.spec.kong.consumerGroupRef) && has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerRef) && !has(self.spec.kong.routeRef)) || (has(self.spec.kong.routeRef) && has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerRef) && !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.consumerRef) && !has(self.spec.kong.serviceRef) && !has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.consumerGroupRef) && !has(self.spec.kong.serviceRef) && !has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerRef)) || (has(self.spec.kong.routeRef) && !has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerRef) && !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.serviceRef) && !has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerGroupRef) && !has(self.spec.kong.consumerRef))", message="The combination of entities set is not allowed" type KongPluginBinding struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` + // +kubebuilder:validation:XValidation:message="When global is set, target refs cannot be used",rule="(has(self.global) && self.global == true) ? !has(self.targets) : true" + // +kubebuilder:validation:XValidation:message="When global is unset, target refs have to be used",rule="(!has(self.global) || self.global == false) ? has(self.targets) : true" Spec KongPluginBindingSpec `json:"spec"` Status KongPluginBindingStatus `json:"status,omitempty"` } +// GetKonnectStatus returns the Konnect status contained in the KongPluginBinding status. func (c *KongPluginBinding) GetKonnectStatus() *konnectv1alpha1.KonnectEntityStatus { return &c.Status.Konnect.KonnectEntityStatus } +// GetTypeName returns the KongPluginBinding Kind name func (c KongPluginBinding) GetTypeName() string { return "KongPluginBinding" } @@ -65,7 +68,12 @@ type KongPluginBindingSpec struct { // PluginReference is a reference to the KongPlugin or KongClusterPlugin resource. It is required PluginReference PluginRef `json:"pluginRef"` - // Kong contains the Kong entity references. It is possible to set multiple combinations + // Global can be set to automatically target all the entities in the Kong cluster. When set to true, + // all the services, routes and consumers in the Kong cluster are targeted by the plugin. + // +optional + Global *bool `json:"global,omitempty"` + + // Targets contains the targets references. It is possible to set multiple combinations // of references, as described in https://docs.konghq.com/gateway/latest/key-concepts/plugins/#precedence // The complete set of allowed combinations and their order of precedence for plugins // configured to multiple entities is: @@ -81,66 +89,83 @@ type KongPluginBindingSpec struct { // 9. Consumer group // 10. Route // 11. Service - // 12. Global // - // TODO(mlavacca): we need to figure out how to deal with global plugins. By means of this new API, - // KongClusterPlugin can be replaced by kongPluginBindings with no Kong references. This way we'd be - // more coherent with the Konnect approach. - // https://github.com/Kong/kubernetes-configuration/issues/7 - Kong *KongReferences `json:"kong,omitempty"` - - // TODO(mlavacca): let's defer this one to the future as we are not sure about the shape we want to give it. - // https://github.com/Kong/kubernetes-configuration/issues/8 - // EntityReference *GenericEntityRef `json:"genericEntityRef,omitempty"` + // +optional + // +kubebuilder:validation:XValidation:message="The combination of entities set is not allowed",rule="(has(self.consumerRef) && has(self.routeRef) && has(self.serviceRef) && !has(self.consumerGroupRef)) || (has(self.consumerGroupRef) && has(self.serviceRef) && has(self.routeRef) && !has(self.consumerRef)) || (has(self.consumerRef) && has(self.routeRef) && !has(self.consumerGroupRef) && !has(self.serviceRef)) || (has(self.consumerRef) && has(self.serviceRef) && !has(self.routeRef) && !has(self.consumerGroupRef)) || (has(self.consumerGroupRef) && has(self.routeRef) && !has(self.serviceRef) && !has(self.consumerRef)) || (has(self.consumerGroupRef) && has(self.serviceRef) && !has(self.consumerRef) && !has(self.routeRef)) || (has(self.routeRef) && has(self.serviceRef) && !has(self.consumerRef) && !has(self.consumerGroupRef)) || (has(self.consumerRef) && !has(self.serviceRef) && !has(self.routeRef) && !has(self.consumerGroupRef)) || (has(self.consumerGroupRef) && !has(self.serviceRef) && !has(self.routeRef) && !has(self.consumerRef)) || (has(self.routeRef) && !has(self.serviceRef) && !has(self.consumerRef) && !has(self.consumerGroupRef)) || (has(self.serviceRef) && !has(self.routeRef) && !has(self.consumerGroupRef) && !has(self.consumerRef))" + // +kubebuilder:validation:XValidation:message="At least one entity reference must be set",rule="has(self.routeRef) || has(self.serviceRef) || has(self.consumerRef) || has(self.consumerGroupRef)" + // +kubebuilder:validation:XValidation:message="KongRoute can be used only when serviceRef is unset or set to KongService, and viceversa",rule="(has(self.routeRef) && self.routeRef.kind == 'KongRoute') ? (!has(self.serviceRef) || self.serviceRef.kind == 'KongService') : true" + Targets *KongPluginBindingTargets `json:"targets,omitempty"` } -type KongReferences struct { - RouteReference *EntityRef `json:"routeRef,omitempty"` - ServiceReference *EntityRef `json:"serviceRef,omitempty"` - ConsumerReference *EntityRef `json:"consumerRef,omitempty"` - ConsumerGroupReference *EntityRef `json:"consumerGroupRef,omitempty"` +// KongPluginBindingTargets contains the targets references. +type KongPluginBindingTargets struct { + // RouteReference can be used to reference one of the following resouces: + // - networking.k8s.io/Ingress + // - gateway.networking.k8s.io/HTTPRoute + // - gateway.networking.k8s.io/GRPCRoute + // - configuration.konghq.com/KongRoute + // + // +optional + // +kubebuilder:validation:XValidation:message="group/kind not allowed for the routeRef",rule="(self.kind == 'KongRoute' && self.group == 'configuration.konghq.com') || (self.kind == 'Ingress' && self.group == 'networking.k8s.io') || (self.kind == 'HTTPRoute' && self.group == 'gateway.networking.k8s.io') || (self.kind == 'GRPCRoute' && self.group == 'gateway.networking.k8s.io')" + RouteReference *TargetRefWithGroupKind `json:"routeRef,omitempty"` + + // ServiceReference can be used to reference one of the following resouces: + // - core/Service or /Service + // - configuration.konghq.com/KongService + // + // +optional + // +kubebuilder:validation:XValidation:message="group/kind not allowed for the serviceRef",rule="(self.kind == 'KongService' && self.group == 'configuration.konghq.com') || (self.kind == 'Service' && (self.group == '' || self.group == 'core'))" + ServiceReference *TargetRefWithGroupKind `json:"serviceRef,omitempty"` + + // ConsumerReference is used to reference a configuration.konghq.com/Consumer resource. + // The group/kind is fixed, therefore the reference is performed only by name. + ConsumerReference *TargetRef `json:"consumerRef,omitempty"` + + // ConsumerGroupReference is used to reference a configuration.konghq.com/ConsumerGroup resource. + // The group/kind is fixed, therefore the reference is performed only by name. + ConsumerGroupReference *TargetRef `json:"consumerGroupRef,omitempty"` } +// PluginRef is a reference to a KongPlugin or KongClusterPlugin resource. type PluginRef struct { - // TODO(mattia): What about cross-namespace references? Do we want to introduce a namespace field - // to allow such a reference? We could allow it and require a RefGrant. + // TODO(mattia): cross-namespace references are not supported yet. // https://github.com/Kong/kubernetes-configuration/issues/9 // Name is the name of the KongPlugin or KongClusterPlugin resource. // +kubebuilder:validation:Required Name string `json:"name"` - // kind can be KongPlugin or KongClusterPlugin. If not set, it is assumed to be KongPlugin. + + // Kind can be KongPlugin or KongClusterPlugin. If not set, it is assumed to be KongPlugin. // +kubebuilder:validation:Enum=KongPlugin;KongClusterPlugin // +kubebuilder:default:=KongPlugin Kind *string `json:"kind,omitempty"` } -type EntityRef struct { +// TargetRef is a reference based on the object's name. +type TargetRef struct { // Name is the name of the entity. // +kubebuilder:validation:Required Name string `json:"name"` } -// type GenericEntityRef struct { -// // Name is the name of the generic entity. -// // +kubebuilder:validation:Required -// Name string `json:"name"` +// TargetRefWithGroupKind is a reference based on the object's group, kind, and name. +type TargetRefWithGroupKind struct { + // Name is the name of the entity. + // +kubebuilder:validation:Required + Name string `json:"name"` -// // kind is the kind of the entity. -// // +kubebuilder:validation:Enum=Service;HTTPRoute;GCPRoute;TLSRoute;TCPRoute;UDPRoute;Ingress -// Kind string `json:"kind"` + // +kubebuilder:validation:Enum=Service;Ingress;HTTPRoute;GRPCRoute;KongService;KongRoute + Kind string `json:"kind"` -// // TODO(mlavacca): add cross-field validation. Kind can be set depending on the group. -// // Group is the group of the entity. -// // +kubebuilder:validation:Enum="";core;gateway.networking.k8s.io;networking.k8s.io -// Group string `json:"group"` -// } + // +kubebuilder:validation:Enum="";core;networking.k8s.io;gateway.networking.k8s.io;configuration.konghq.com + Group string `json:"group"` +} // KongPluginBindingStatus represents the current status of the KongBinding resource. type KongPluginBindingStatus struct { // Konnect contains the Konnect entity status. // +optional - Konnect *konnectv1alpha1.KonnectEntityStatusWithControlPlaneAndServiceRefs `json:"konnect,omitempty"` + Konnect *konnectv1alpha1.KonnectEntityStatusWithControlPlaneRef `json:"konnect,omitempty"` // Conditions describe the status of the Konnect entity. // +listType=map diff --git a/api/configuration/v1alpha1/zz_generated.deepcopy.go b/api/configuration/v1alpha1/zz_generated.deepcopy.go index e8010172..b80e82e2 100644 --- a/api/configuration/v1alpha1/zz_generated.deepcopy.go +++ b/api/configuration/v1alpha1/zz_generated.deepcopy.go @@ -87,21 +87,6 @@ func (in *ControllerReference) DeepCopy() *ControllerReference { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *EntityRef) DeepCopyInto(out *EntityRef) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EntityRef. -func (in *EntityRef) DeepCopy() *EntityRef { - if in == nil { - return nil - } - out := new(EntityRef) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *IngressClassParameters) DeepCopyInto(out *IngressClassParameters) { *out = *in @@ -462,9 +447,14 @@ func (in *KongPluginBindingList) DeepCopyObject() runtime.Object { func (in *KongPluginBindingSpec) DeepCopyInto(out *KongPluginBindingSpec) { *out = *in in.PluginReference.DeepCopyInto(&out.PluginReference) - if in.Kong != nil { - in, out := &in.Kong, &out.Kong - *out = new(KongReferences) + if in.Global != nil { + in, out := &in.Global, &out.Global + *out = new(bool) + **out = **in + } + if in.Targets != nil { + in, out := &in.Targets, &out.Targets + *out = new(KongPluginBindingTargets) (*in).DeepCopyInto(*out) } } @@ -484,7 +474,7 @@ func (in *KongPluginBindingStatus) DeepCopyInto(out *KongPluginBindingStatus) { *out = *in if in.Konnect != nil { in, out := &in.Konnect, &out.Konnect - *out = new(konnectv1alpha1.KonnectEntityStatusWithControlPlaneAndServiceRefs) + *out = new(konnectv1alpha1.KonnectEntityStatusWithControlPlaneRef) **out = **in } if in.Conditions != nil { @@ -507,36 +497,36 @@ func (in *KongPluginBindingStatus) DeepCopy() *KongPluginBindingStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *KongReferences) DeepCopyInto(out *KongReferences) { +func (in *KongPluginBindingTargets) DeepCopyInto(out *KongPluginBindingTargets) { *out = *in if in.RouteReference != nil { in, out := &in.RouteReference, &out.RouteReference - *out = new(EntityRef) + *out = new(TargetRefWithGroupKind) **out = **in } if in.ServiceReference != nil { in, out := &in.ServiceReference, &out.ServiceReference - *out = new(EntityRef) + *out = new(TargetRefWithGroupKind) **out = **in } if in.ConsumerReference != nil { in, out := &in.ConsumerReference, &out.ConsumerReference - *out = new(EntityRef) + *out = new(TargetRef) **out = **in } if in.ConsumerGroupReference != nil { in, out := &in.ConsumerGroupReference, &out.ConsumerGroupReference - *out = new(EntityRef) + *out = new(TargetRef) **out = **in } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KongReferences. -func (in *KongReferences) DeepCopy() *KongReferences { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KongPluginBindingTargets. +func (in *KongPluginBindingTargets) DeepCopy() *KongPluginBindingTargets { if in == nil { return nil } - out := new(KongReferences) + out := new(KongPluginBindingTargets) in.DeepCopyInto(out) return out } @@ -1132,3 +1122,33 @@ func (in *ServiceRef) DeepCopy() *ServiceRef { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TargetRef) DeepCopyInto(out *TargetRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetRef. +func (in *TargetRef) DeepCopy() *TargetRef { + if in == nil { + return nil + } + out := new(TargetRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TargetRefWithGroupKind) DeepCopyInto(out *TargetRefWithGroupKind) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TargetRefWithGroupKind. +func (in *TargetRefWithGroupKind) DeepCopy() *TargetRefWithGroupKind { + if in == nil { + return nil + } + out := new(TargetRefWithGroupKind) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/configuration.konghq.com_kongpluginbindings.yaml b/config/crd/bases/configuration.konghq.com_kongpluginbindings.yaml index 49c76bc9..9ea4ed03 100644 --- a/config/crd/bases/configuration.konghq.com_kongpluginbindings.yaml +++ b/config/crd/bases/configuration.konghq.com_kongpluginbindings.yaml @@ -53,9 +53,33 @@ spec: spec: description: KongPluginBindingSpec defines specification of a KongPluginBinding. properties: - kong: + global: description: |- - Kong contains the Kong entity references. It is possible to set multiple combinations + Global can be set to automatically target all the entities in the Kong cluster. When set to true, + all the services, routes and consumers in the Kong cluster are targeted by the plugin. + type: boolean + pluginRef: + description: PluginReference is a reference to the KongPlugin or KongClusterPlugin + resource. It is required + properties: + kind: + default: KongPlugin + description: Kind can be KongPlugin or KongClusterPlugin. If not + set, it is assumed to be KongPlugin. + enum: + - KongPlugin + - KongClusterPlugin + type: string + name: + description: Name is the name of the KongPlugin or KongClusterPlugin + resource. + type: string + required: + - name + type: object + targets: + description: |- + Targets contains the targets references. It is possible to set multiple combinations of references, as described in https://docs.konghq.com/gateway/latest/key-concepts/plugins/#precedence The complete set of allowed combinations and their order of precedence for plugins configured to multiple entities is: @@ -72,15 +96,11 @@ spec: 9. Consumer group 10. Route 11. Service - 12. Global - - - TODO(mlavacca): we need to figure out how to deal with global plugins. By means of this new API, - KongClusterPlugin can be replaced by kongPluginBindings with no Kong references. This way we'd be - more coherent with the Konnect approach. - https://github.com/Kong/kubernetes-configuration/issues/7 properties: consumerGroupRef: + description: |- + ConsumerGroupReference is used to reference a configuration.konghq.com/ConsumerGroup resource. + The group/kind is fixed, therefore the reference is performed only by name. properties: name: description: Name is the name of the entity. @@ -89,6 +109,9 @@ spec: - name type: object consumerRef: + description: |- + ConsumerReference is used to reference a configuration.konghq.com/Consumer resource. + The group/kind is fixed, therefore the reference is performed only by name. properties: name: description: Name is the name of the entity. @@ -97,44 +120,116 @@ spec: - name type: object routeRef: + description: |- + RouteReference can be used to reference one of the following resouces: + - networking.k8s.io/Ingress + - gateway.networking.k8s.io/HTTPRoute + - gateway.networking.k8s.io/GRPCRoute + - configuration.konghq.com/KongRoute properties: + group: + enum: + - "" + - core + - networking.k8s.io + - gateway.networking.k8s.io + - configuration.konghq.com + type: string + kind: + enum: + - Service + - Ingress + - HTTPRoute + - GRPCRoute + - KongService + - KongRoute + type: string name: description: Name is the name of the entity. type: string required: + - group + - kind - name type: object + x-kubernetes-validations: + - message: group/kind not allowed for the routeRef + rule: (self.kind == 'KongRoute' && self.group == 'configuration.konghq.com') + || (self.kind == 'Ingress' && self.group == 'networking.k8s.io') + || (self.kind == 'HTTPRoute' && self.group == 'gateway.networking.k8s.io') + || (self.kind == 'GRPCRoute' && self.group == 'gateway.networking.k8s.io') serviceRef: + description: |- + ServiceReference can be used to reference one of the following resouces: + - core/Service or /Service + - configuration.konghq.com/KongService properties: + group: + enum: + - "" + - core + - networking.k8s.io + - gateway.networking.k8s.io + - configuration.konghq.com + type: string + kind: + enum: + - Service + - Ingress + - HTTPRoute + - GRPCRoute + - KongService + - KongRoute + type: string name: description: Name is the name of the entity. type: string required: + - group + - kind - name type: object + x-kubernetes-validations: + - message: group/kind not allowed for the serviceRef + rule: (self.kind == 'KongService' && self.group == 'configuration.konghq.com') + || (self.kind == 'Service' && (self.group == '' || self.group + == 'core')) type: object - pluginRef: - description: PluginReference is a reference to the KongPlugin or KongClusterPlugin - resource. It is required - properties: - kind: - default: KongPlugin - description: kind can be KongPlugin or KongClusterPlugin. If not - set, it is assumed to be KongPlugin. - enum: - - KongPlugin - - KongClusterPlugin - type: string - name: - description: Name is the name of the KongPlugin or KongClusterPlugin - resource. - type: string - required: - - name - type: object + x-kubernetes-validations: + - message: The combination of entities set is not allowed + rule: (has(self.consumerRef) && has(self.routeRef) && has(self.serviceRef) + && !has(self.consumerGroupRef)) || (has(self.consumerGroupRef) + && has(self.serviceRef) && has(self.routeRef) && !has(self.consumerRef)) + || (has(self.consumerRef) && has(self.routeRef) && !has(self.consumerGroupRef) + && !has(self.serviceRef)) || (has(self.consumerRef) && has(self.serviceRef) + && !has(self.routeRef) && !has(self.consumerGroupRef)) || (has(self.consumerGroupRef) + && has(self.routeRef) && !has(self.serviceRef) && !has(self.consumerRef)) + || (has(self.consumerGroupRef) && has(self.serviceRef) && !has(self.consumerRef) + && !has(self.routeRef)) || (has(self.routeRef) && has(self.serviceRef) + && !has(self.consumerRef) && !has(self.consumerGroupRef)) || (has(self.consumerRef) + && !has(self.serviceRef) && !has(self.routeRef) && !has(self.consumerGroupRef)) + || (has(self.consumerGroupRef) && !has(self.serviceRef) && !has(self.routeRef) + && !has(self.consumerRef)) || (has(self.routeRef) && !has(self.serviceRef) + && !has(self.consumerRef) && !has(self.consumerGroupRef)) || (has(self.serviceRef) + && !has(self.routeRef) && !has(self.consumerGroupRef) && !has(self.consumerRef)) + - message: At least one entity reference must be set + rule: has(self.routeRef) || has(self.serviceRef) || has(self.consumerRef) + || has(self.consumerGroupRef) + - message: KongRoute can be used only when serviceRef is unset or + set to KongService, and viceversa + rule: '(has(self.routeRef) && self.routeRef.kind == ''KongRoute'') + ? (!has(self.serviceRef) || self.serviceRef.kind == ''KongService'') + : true' required: - pluginRef type: object + x-kubernetes-validations: + - message: When global is set, target refs cannot be used + rule: '(has(self.global) && self.global == true) ? !has(self.targets) + : true' + - message: When global is unset, target refs have to be used + rule: '(!has(self.global) || self.global == false) ? has(self.targets) + : true' status: description: KongPluginBindingStatus represents the current status of the KongBinding resource. @@ -225,7 +320,7 @@ spec: properties: controlPlaneID: description: ControlPlaneID is the Konnect ID of the ControlPlane - this entity is associated with. + this Route is associated with. type: string id: description: |- @@ -240,39 +335,11 @@ spec: description: ServerURL is the URL of the Konnect server in which the entity exists. type: string - serviceID: - description: ServiceID is the Konnect ID of the Service this entity - is associated with. - type: string type: object type: object required: - spec type: object - x-kubernetes-validations: - - message: The combination of entities set is not allowed - rule: (has(self.spec.kong.consumerRef) && has(self.spec.kong.routeRef) && - has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerGroupRef)) - || (has(self.spec.kong.consumerGroupRef) && has(self.spec.kong.serviceRef) - && has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerRef)) || - (has(self.spec.kong.consumerRef) && has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerGroupRef) - && !has(self.spec.kong.serviceRef)) || (has(self.spec.kong.consumerRef) - && has(self.spec.kong.serviceRef) && !has(self.spec.kong.routeRef) && - !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.consumerGroupRef) - && has(self.spec.kong.routeRef) && !has(self.spec.kong.serviceRef) && - !has(self.spec.kong.consumerRef)) || (has(self.spec.kong.consumerGroupRef) - && has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerRef) - && !has(self.spec.kong.routeRef)) || (has(self.spec.kong.routeRef) && - has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerRef) && - !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.consumerRef) - && !has(self.spec.kong.serviceRef) && !has(self.spec.kong.routeRef) && - !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.consumerGroupRef) - && !has(self.spec.kong.serviceRef) && !has(self.spec.kong.routeRef) && - !has(self.spec.kong.consumerRef)) || (has(self.spec.kong.routeRef) && - !has(self.spec.kong.serviceRef) && !has(self.spec.kong.consumerRef) && - !has(self.spec.kong.consumerGroupRef)) || (has(self.spec.kong.serviceRef) - && !has(self.spec.kong.routeRef) && !has(self.spec.kong.consumerGroupRef) - && !has(self.spec.kong.consumerRef)) served: true storage: true subresources: diff --git a/config/samples/kongpluginbinding.yaml b/config/samples/kongpluginbinding.yaml index 346a6502..27e8f064 100644 --- a/config/samples/kongpluginbinding.yaml +++ b/config/samples/kongpluginbinding.yaml @@ -2,14 +2,44 @@ apiVersion: configuration.konghq.com/v1alpha1 kind: KongPluginBinding metadata: generation: 1 - name: sample-1 + name: plugin-binding-kongservice-kongroute-kongconsumer spec: pluginRef: name: plugin-sample - kong: + targets: consumerRef: name: consumer-sample serviceRef: name: service-sample + kind: KongService + group: configuration.konghq.com routeRef: name: route-sample + kind: KongRoute + group: configuration.konghq.com +--- +apiVersion: configuration.konghq.com/v1alpha1 +kind: KongPluginBinding +metadata: + generation: 1 + name: plugin-binding-kongservice-kongconsumer +spec: + pluginRef: + name: plugin-sample + targets: + consumerRef: + name: consumer-sample + serviceRef: + name: service-sample + kind: KongService + group: configuration.konghq.com +--- +apiVersion: configuration.konghq.com/v1alpha1 +kind: KongPluginBinding +metadata: + generation: 1 + name: global-binding +spec: + pluginRef: + name: plugin-sample + global: true diff --git a/docs/api-reference.md b/docs/api-reference.md index 2472130b..e0ae8921 100644 --- a/docs/api-reference.md +++ b/docs/api-reference.md @@ -492,21 +492,6 @@ _Appears in:_ _Appears in:_ - [KongLicenseControllerStatus](#konglicensecontrollerstatus) -#### EntityRef - - - - - - -| Field | Description | -| --- | --- | -| `name` _string_ | Name is the name of the entity. | - - -_Appears in:_ -- [KongReferences](#kongreferences) - #### Group _Underlying type:_ `string` @@ -614,7 +599,8 @@ KongPluginBindingSpec defines specification of a KongPluginBinding. | Field | Description | | --- | --- | | `pluginRef` _[PluginRef](#pluginref)_ | PluginReference is a reference to the KongPlugin or KongClusterPlugin resource. It is required | -| `kong` _[KongReferences](#kongreferences)_ | Kong contains the Kong entity references. It is possible to set multiple combinations of references, as described in https://docs.konghq.com/gateway/latest/key-concepts/plugins/#precedence The complete set of allowed combinations and their order of precedence for plugins configured to multiple entities is:

1. Consumer + route + service 2. Consumer group + service + route 3. Consumer + route 4. Consumer + service 5. Consumer group + route 6. Consumer group + service 7. Route + service 8. Consumer 9. Consumer group 10. Route 11. Service 12. Global

TODO(mlavacca): we need to figure out how to deal with global plugins. By means of this new API, KongClusterPlugin can be replaced by kongPluginBindings with no Kong references. This way we'd be more coherent with the Konnect approach. https://github.com/Kong/kubernetes-configuration/issues/7 | +| `global` _boolean_ | Global can be set to automatically target all the entities in the Kong cluster. When set to true, all the services, routes and consumers in the Kong cluster are targeted by the plugin. | +| `targets` _[KongPluginBindingTargets](#kongpluginbindingtargets)_ | Targets contains the targets references. It is possible to set multiple combinations of references, as described in https://docs.konghq.com/gateway/latest/key-concepts/plugins/#precedence The complete set of allowed combinations and their order of precedence for plugins configured to multiple entities is:

1. Consumer + route + service 2. Consumer group + service + route 3. Consumer + route 4. Consumer + service 5. Consumer group + route 6. Consumer group + service 7. Route + service 8. Consumer 9. Consumer group 10. Route 11. Service | _Appears in:_ @@ -622,19 +608,19 @@ _Appears in:_ -#### KongReferences - +#### KongPluginBindingTargets +KongPluginBindingTargets contains the targets references. | Field | Description | | --- | --- | -| `routeRef` _[EntityRef](#entityref)_ | | -| `serviceRef` _[EntityRef](#entityref)_ | | -| `consumerRef` _[EntityRef](#entityref)_ | | -| `consumerGroupRef` _[EntityRef](#entityref)_ | | +| `routeRef` _[TargetRefWithGroupKind](#targetrefwithgroupkind)_ | RouteReference can be used to reference one of the following resouces: - networking.k8s.io/Ingress - gateway.networking.k8s.io/HTTPRoute - gateway.networking.k8s.io/GRPCRoute - configuration.konghq.com/KongRoute | +| `serviceRef` _[TargetRefWithGroupKind](#targetrefwithgroupkind)_ | ServiceReference can be used to reference one of the following resouces: - core/Service or /Service - configuration.konghq.com/KongService | +| `consumerRef` _[TargetRef](#targetref)_ | ConsumerReference is used to reference a configuration.konghq.com/Consumer resource. The group/kind is fixed, therefore the reference is performed only by name. | +| `consumerGroupRef` _[TargetRef](#targetref)_ | ConsumerGroupReference is used to reference a configuration.konghq.com/ConsumerGroup resource. The group/kind is fixed, therefore the reference is performed only by name. | _Appears in:_ @@ -868,14 +854,14 @@ _Appears in:_ #### PluginRef - +PluginRef is a reference to a KongPlugin or KongClusterPlugin resource. | Field | Description | | --- | --- | | `name` _string_ | Name is the name of the KongPlugin or KongClusterPlugin resource. | -| `kind` _string_ | kind can be KongPlugin or KongClusterPlugin. If not set, it is assumed to be KongPlugin. | +| `kind` _string_ | Kind can be KongPlugin or KongClusterPlugin. If not set, it is assumed to be KongPlugin. | _Appears in:_ @@ -897,6 +883,38 @@ _Appears in:_ _Appears in:_ - [KongRouteSpec](#kongroutespec) +#### TargetRef + + +TargetRef is a reference based on the object's name. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Name is the name of the entity. | + + +_Appears in:_ +- [KongPluginBindingTargets](#kongpluginbindingtargets) + +#### TargetRefWithGroupKind + + +TargetRefWithGroupKind is a reference based on the object's group, kind, and name. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Name is the name of the entity. | +| `kind` _string_ | | +| `group` _string_ | | + + +_Appears in:_ +- [KongPluginBindingTargets](#kongpluginbindingtargets) + ## configuration.konghq.com/v1beta1