diff --git a/api/konnect/v1alpha1/konnect_event_gateway_types.go b/api/konnect/v1alpha1/konnect_event_gateway_types.go new file mode 100644 index 0000000000..3af0c1b15d --- /dev/null +++ b/api/konnect/v1alpha1/konnect_event_gateway_types.go @@ -0,0 +1,196 @@ +package v1alpha1 + +import ( + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + commonv1alpha1 "github.com/kong/kong-operator/v2/api/common/v1alpha1" + konnectv1alpha2 "github.com/kong/kong-operator/v2/api/konnect/v1alpha2" +) + +func init() { + SchemeBuilder.Register(&KonnectEventGateway{}, &KonnectEventGatewayList{}) +} + +// KonnectEventGateway is the Schema for the Konnect Event Gateways API. +// It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. +// +// +genclient +// +kubebuilder:resource:scope=Namespaced,shortName=keg,categories=kong;konnect +// +kubebuilder:object:root=true +// +kubebuilder:object:generate=true +// +kubebuilder:subresource:status +// +kubebuilder:printcolumn:name="Programmed",description="The Resource is Programmed on Konnect",type=string,JSONPath=`.status.conditions[?(@.type=='Programmed')].status` +// +kubebuilder:printcolumn:name="ID",description="Konnect ID",type=string,JSONPath=`.status.id` +// +kubebuilder:printcolumn:name="OrgID",description="Konnect Organization ID this resource belongs to.",type=string,JSONPath=`.status.organizationID` +// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` +// +kubebuilder:validation:XValidation:message="spec.konnect is immutable when an entity is already Programmed",rule="(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == 'Programmed' && c.status == 'True')) ? true : self.spec.konnect == oldSelf.spec.konnect" +// +kubebuilder:validation:XValidation:message="spec.konnect is immutable when an entity refers to a Valid API Auth Configuration",rule="(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == 'APIAuthValid' && c.status == 'True')) ? true : self.spec.konnect == oldSelf.spec.konnect" +// +kong:channels=kong-operator +type KonnectEventGateway struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + // Spec defines the desired state of KonnectEventGateway. + // + // +required + Spec KonnectEventGatewaySpec `json:"spec"` + + // Status defines the observed state of KonnectEventGateway. + // + // +optional + Status KonnectEventGatewayStatus `json:"status,omitempty"` +} + +// KonnectEventGatewaySpec defines the desired state of KonnectEventGateway. +// +// +kubebuilder:validation:XValidation:message="spec.source is immutable",rule="self.source == oldSelf.source" +// +kubebuilder:validation:XValidation:message="spec.createGatewayRequest cannot be set when source is Mirror",rule="self.source == 'Mirror' ? !has(self.createGatewayRequest) : true" +// +kubebuilder:validation:XValidation:message="spec.createGatewayRequest with name must be set when source is Origin",rule="self.source == 'Origin' ? has(self.createGatewayRequest) : true" +// +kubebuilder:validation:XValidation:message="spec.mirror must be set when source is Mirror",rule="self.source == 'Mirror' ? has(self.mirror) : true" +// +kubebuilder:validation:XValidation:message="spec.mirror cannot be set when source is Origin",rule="self.source == 'Origin' ? !has(self.mirror) : true" +type KonnectEventGatewaySpec struct { + // Source represents the source type of the Konnect entity. + // Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + // Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + // operator only reads its state and populates the status. + // + // +kubebuilder:validation:Enum=Origin;Mirror + // +kubebuilder:default=Origin + // +optional + Source *commonv1alpha1.EntitySource `json:"source,omitempty"` + + // Mirror holds the configuration for a mirrored Event Gateway. + // Only applicable when source is Mirror. + // + // +optional + Mirror *EventGatewayMirrorSpec `json:"mirror,omitempty"` + + // CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + // Only applicable when source is Origin. + // + // +optional + CreateGatewayRequest *CreateEventGatewayRequest `json:"createGatewayRequest,omitempty"` + + // KonnectConfiguration contains the Konnect API authentication configuration. + // + // +optional + KonnectConfiguration konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef `json:"konnect,omitempty"` +} + +// CreateEventGatewayRequest maps to the Konnect CreateGatewayRequest / UpdateGatewayRequest schema. +// +// +kubebuilder:validation:XValidation:message="spec.createGatewayRequest.labels must not have more than 40 entries",rule="!has(self.labels) || size(self.labels) <= 40" +// +kubebuilder:validation:XValidation:message="spec.createGatewayRequest.labels keys must be of length 1-63 characters",rule="!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)" +// +kubebuilder:validation:XValidation:message="spec.createGatewayRequest.labels values must be of length 1-63 characters",rule="!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)" +// +kubebuilder:validation:XValidation:message="spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_'",rule="!has(self.labels) || self.labels.all(key, !key.startsWith('kong') && !key.startsWith('konnect') && !key.startsWith('mesh') && !key.startsWith('kic') && !key.startsWith('_'))" +type CreateEventGatewayRequest struct { + // Name is the human-readable name of the Event Gateway. + // +required + // +kubebuilder:validation:MinLength=1 + // +kubebuilder:validation:MaxLength=255 + Name string `json:"name"` + + // Description is a human-readable description of the Event Gateway. + // + // +optional + // +kubebuilder:validation:MaxLength=512 + Description *string `json:"description,omitempty"` + + // MinRuntimeVersion is the minimum keg version that can connect to this gateway. + // Must match the pattern X.Y (e.g. "1.1"). + // + // +optional + // +kubebuilder:validation:Pattern=`^\d+\.\d+$` + MinRuntimeVersion *string `json:"minRuntimeVersion,omitempty"` + + // Labels are metadata key-value pairs for filtering and searching. + // + // +optional + Labels map[string]string `json:"labels,omitempty"` +} + +// EventGatewayMirrorSpec holds the configuration for a mirrored Event Gateway. +type EventGatewayMirrorSpec struct { + // Konnect contains the ID of the existing Event Gateway in Konnect. + // + // +required + Konnect EventGatewayMirrorKonnect `json:"konnect"` +} + +// EventGatewayMirrorKonnect contains the Konnect ID of an existing Event Gateway. +type EventGatewayMirrorKonnect struct { + // ID is the UUID of the existing Event Gateway in Konnect. + // + // +required + // +kubebuilder:validation:Pattern=`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$` + ID commonv1alpha1.KonnectIDType `json:"id"` +} + +// KonnectEventGatewayStatus defines the observed state of KonnectEventGateway. +type KonnectEventGatewayStatus struct { + // Conditions describe the current conditions of the KonnectEventGateway. + // + // Known condition types are: + // + // * "Programmed" + // * "APIAuthValid" + // + // +listType=map + // +listMapKey=type + // +patchStrategy=merge + // +patchMergeKey=type + // +kubebuilder:validation:MaxItems=8 + // +kubebuilder:default={{type:"Programmed",status:"Unknown",reason:"Pending",message:"Waiting for controller",lastTransitionTime:"1970-01-01T00:00:00Z"}} + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + // KonnectEntityStatus holds the Konnect ID and organization ID. + konnectv1alpha2.KonnectEntityStatus `json:",inline"` //nolint:embeddedstructfieldcheck +} + +// GetKonnectLabels returns the labels from the CreateGatewayRequest. +func (eg *KonnectEventGateway) GetKonnectLabels() map[string]string { + if eg.Spec.CreateGatewayRequest == nil { + return nil + } + return eg.Spec.CreateGatewayRequest.Labels +} + +// SetKonnectLabels sets the labels in the CreateGatewayRequest. +func (eg *KonnectEventGateway) SetKonnectLabels(labels map[string]string) { + if eg.Spec.CreateGatewayRequest == nil { + eg.Spec.CreateGatewayRequest = &CreateEventGatewayRequest{} + } + eg.Spec.CreateGatewayRequest.Labels = labels +} + +// GetKonnectName returns the name from the CreateGatewayRequest. +func (eg *KonnectEventGateway) GetKonnectName() string { + if eg.Spec.CreateGatewayRequest == nil { + return "" + } + return eg.Spec.CreateGatewayRequest.Name +} + +// SetKonnectName sets the name in the CreateGatewayRequest. +func (eg *KonnectEventGateway) SetKonnectName(name string) { + if eg.Spec.CreateGatewayRequest == nil { + eg.Spec.CreateGatewayRequest = &CreateEventGatewayRequest{} + } + eg.Spec.CreateGatewayRequest.Name = name +} + +// GetKonnectAPIAuthConfigurationRef returns the Konnect API Auth Configuration Ref. +func (eg *KonnectEventGateway) GetKonnectAPIAuthConfigurationRef() konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef { + return eg.Spec.KonnectConfiguration +} + +// KonnectEventGatewayList contains a list of KonnectEventGateway. +// +// +kubebuilder:object:root=true +type KonnectEventGatewayList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + + Items []KonnectEventGateway `json:"items"` +} diff --git a/api/konnect/v1alpha1/zz_generated.deepcopy.go b/api/konnect/v1alpha1/zz_generated.deepcopy.go index 605287c366..d482f0b1ba 100644 --- a/api/konnect/v1alpha1/zz_generated.deepcopy.go +++ b/api/konnect/v1alpha1/zz_generated.deepcopy.go @@ -262,6 +262,38 @@ func (in *CreateControlPlaneRequest) DeepCopy() *CreateControlPlaneRequest { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CreateEventGatewayRequest) DeepCopyInto(out *CreateEventGatewayRequest) { + *out = *in + if in.Description != nil { + in, out := &in.Description, &out.Description + *out = new(string) + **out = **in + } + if in.MinRuntimeVersion != nil { + in, out := &in.MinRuntimeVersion, &out.MinRuntimeVersion + *out = new(string) + **out = **in + } + if in.Labels != nil { + in, out := &in.Labels, &out.Labels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CreateEventGatewayRequest. +func (in *CreateEventGatewayRequest) DeepCopy() *CreateEventGatewayRequest { + if in == nil { + return nil + } + out := new(CreateEventGatewayRequest) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DataPlaneClientAuthStatus) DeepCopyInto(out *DataPlaneClientAuthStatus) { *out = *in @@ -282,6 +314,37 @@ func (in *DataPlaneClientAuthStatus) DeepCopy() *DataPlaneClientAuthStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventGatewayMirrorKonnect) DeepCopyInto(out *EventGatewayMirrorKonnect) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventGatewayMirrorKonnect. +func (in *EventGatewayMirrorKonnect) DeepCopy() *EventGatewayMirrorKonnect { + if in == nil { + return nil + } + out := new(EventGatewayMirrorKonnect) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *EventGatewayMirrorSpec) DeepCopyInto(out *EventGatewayMirrorSpec) { + *out = *in + out.Konnect = in.Konnect +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new EventGatewayMirrorSpec. +func (in *EventGatewayMirrorSpec) DeepCopy() *EventGatewayMirrorSpec { + if in == nil { + return nil + } + out := new(EventGatewayMirrorSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KonnectAPIAuthConfiguration) DeepCopyInto(out *KonnectAPIAuthConfiguration) { *out = *in @@ -784,6 +847,119 @@ func (in *KonnectEndpoints) DeepCopy() *KonnectEndpoints { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KonnectEventGateway) DeepCopyInto(out *KonnectEventGateway) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KonnectEventGateway. +func (in *KonnectEventGateway) DeepCopy() *KonnectEventGateway { + if in == nil { + return nil + } + out := new(KonnectEventGateway) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KonnectEventGateway) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KonnectEventGatewayList) DeepCopyInto(out *KonnectEventGatewayList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]KonnectEventGateway, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KonnectEventGatewayList. +func (in *KonnectEventGatewayList) DeepCopy() *KonnectEventGatewayList { + if in == nil { + return nil + } + out := new(KonnectEventGatewayList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *KonnectEventGatewayList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KonnectEventGatewaySpec) DeepCopyInto(out *KonnectEventGatewaySpec) { + *out = *in + if in.Source != nil { + in, out := &in.Source, &out.Source + *out = new(commonv1alpha1.EntitySource) + **out = **in + } + if in.Mirror != nil { + in, out := &in.Mirror, &out.Mirror + *out = new(EventGatewayMirrorSpec) + **out = **in + } + if in.CreateGatewayRequest != nil { + in, out := &in.CreateGatewayRequest, &out.CreateGatewayRequest + *out = new(CreateEventGatewayRequest) + (*in).DeepCopyInto(*out) + } + in.KonnectConfiguration.DeepCopyInto(&out.KonnectConfiguration) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KonnectEventGatewaySpec. +func (in *KonnectEventGatewaySpec) DeepCopy() *KonnectEventGatewaySpec { + if in == nil { + return nil + } + out := new(KonnectEventGatewaySpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *KonnectEventGatewayStatus) DeepCopyInto(out *KonnectEventGatewayStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]metav1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + out.KonnectEntityStatus = in.KonnectEntityStatus +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KonnectEventGatewayStatus. +func (in *KonnectEventGatewayStatus) DeepCopy() *KonnectEventGatewayStatus { + if in == nil { + return nil + } + out := new(KonnectEventGatewayStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *KonnectExtension) DeepCopyInto(out *KonnectExtension) { *out = *in diff --git a/api/konnect/v1alpha1/zz_generated_funcs_standalone.go b/api/konnect/v1alpha1/zz_generated_funcs_standalone.go index f23a9106b6..72eb6d8d57 100644 --- a/api/konnect/v1alpha1/zz_generated_funcs_standalone.go +++ b/api/konnect/v1alpha1/zz_generated_funcs_standalone.go @@ -82,3 +82,33 @@ func (obj *KonnectCloudGatewayNetwork) GetConditions() []metav1.Condition { func (obj *KonnectCloudGatewayNetwork) SetConditions(conditions []metav1.Condition) { obj.Status.Conditions = conditions } + +// GetKonnectStatus returns the Konnect status contained in the KonnectEventGateway status. +func (obj *KonnectEventGateway) GetKonnectStatus() *konnectv1alpha2.KonnectEntityStatus { + return &obj.Status.KonnectEntityStatus +} + +// GetKonnectID returns the Konnect ID in the KonnectEventGateway status. +func (obj *KonnectEventGateway) GetKonnectID() string { + return obj.Status.ID +} + +// SetKonnectID sets the Konnect ID in the KonnectEventGateway status. +func (obj *KonnectEventGateway) SetKonnectID(id string) { + obj.Status.ID = id +} + +// GetTypeName returns the KonnectEventGateway Kind name. +func (obj KonnectEventGateway) GetTypeName() string { + return "KonnectEventGateway" +} + +// GetConditions returns the Status Conditions. +func (obj *KonnectEventGateway) GetConditions() []metav1.Condition { + return obj.Status.Conditions +} + +// SetConditions sets the Status Conditions. +func (obj *KonnectEventGateway) SetConditions(conditions []metav1.Condition) { + obj.Status.Conditions = conditions +} diff --git a/api/konnect/v1alpha1/zz_generated_list_funcs.go b/api/konnect/v1alpha1/zz_generated_list_funcs.go index c91cff2335..0d6ea3b7fb 100644 --- a/api/konnect/v1alpha1/zz_generated_list_funcs.go +++ b/api/konnect/v1alpha1/zz_generated_list_funcs.go @@ -17,6 +17,11 @@ func (obj KonnectCloudGatewayNetworkList) GetItems() []KonnectCloudGatewayNetwor return obj.Items } +// GetItems returns the list of KonnectEventGateway items. +func (obj KonnectEventGatewayList) GetItems() []KonnectEventGateway { + return obj.Items +} + // GetItems returns the list of KonnectCloudGatewayDataPlaneGroupConfiguration items. func (obj KonnectCloudGatewayDataPlaneGroupConfigurationList) GetItems() []KonnectCloudGatewayDataPlaneGroupConfiguration { return obj.Items diff --git a/charts/kong-operator/charts/ko-crds/templates/ko-crds.yaml b/charts/kong-operator/charts/ko-crds/templates/ko-crds.yaml index 4ba34cc8fb..26e7cde7a2 100644 --- a/charts/kong-operator/charts/ko-crds/templates/ko-crds.yaml +++ b/charts/kong-operator/charts/ko-crds/templates/ko-crds.yaml @@ -59241,6 +59241,293 @@ spec: --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: +{{ if .Values.keep }} + helm.sh/resource-policy: keep +{{ end }} + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the + Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering + and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than + 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length + 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 + && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length + 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) + >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with + 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') + && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && + !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication + configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration + resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway + in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway + in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : + true' + - message: spec.createGatewayRequest with name must be set when source + is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : + true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been + created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the + entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, + c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect + == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API + Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, + c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect + == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: {{ if .Values.keep }} diff --git a/charts/kong-operator/ci/__snapshots__/affinity-values.snap b/charts/kong-operator/ci/__snapshots__/affinity-values.snap index ae532795d6..5d3c40f24c 100644 --- a/charts/kong-operator/ci/__snapshots__/affinity-values.snap +++ b/charts/kong-operator/ci/__snapshots__/affinity-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/controlplane-config-dump.snap b/charts/kong-operator/ci/__snapshots__/controlplane-config-dump.snap index f9491ff954..026839048a 100644 --- a/charts/kong-operator/ci/__snapshots__/controlplane-config-dump.snap +++ b/charts/kong-operator/ci/__snapshots__/controlplane-config-dump.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/disable-gateway-controller-values.snap b/charts/kong-operator/ci/__snapshots__/disable-gateway-controller-values.snap index a42ade51d5..c2bde52f1c 100644 --- a/charts/kong-operator/ci/__snapshots__/disable-gateway-controller-values.snap +++ b/charts/kong-operator/ci/__snapshots__/disable-gateway-controller-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/env-and-args-values.snap b/charts/kong-operator/ci/__snapshots__/env-and-args-values.snap index 1491db3e63..2a97b4ceed 100644 --- a/charts/kong-operator/ci/__snapshots__/env-and-args-values.snap +++ b/charts/kong-operator/ci/__snapshots__/env-and-args-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/env-and-customenv-values.snap b/charts/kong-operator/ci/__snapshots__/env-and-customenv-values.snap index 76d56e92d6..536b293622 100644 --- a/charts/kong-operator/ci/__snapshots__/env-and-customenv-values.snap +++ b/charts/kong-operator/ci/__snapshots__/env-and-customenv-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/extra-labels-values.snap b/charts/kong-operator/ci/__snapshots__/extra-labels-values.snap index 59e25bfc39..182d68d240 100644 --- a/charts/kong-operator/ci/__snapshots__/extra-labels-values.snap +++ b/charts/kong-operator/ci/__snapshots__/extra-labels-values.snap @@ -55708,6 +55708,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57598,6 +57859,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57615,6 +57877,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/image-pull-secrets-and-image-digest-values.snap b/charts/kong-operator/ci/__snapshots__/image-pull-secrets-and-image-digest-values.snap index 133b307a59..131b1e1f27 100644 --- a/charts/kong-operator/ci/__snapshots__/image-pull-secrets-and-image-digest-values.snap +++ b/charts/kong-operator/ci/__snapshots__/image-pull-secrets-and-image-digest-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/nightly-can-be-used-values.snap b/charts/kong-operator/ci/__snapshots__/nightly-can-be-used-values.snap index 521a438d1a..1cae8a287c 100644 --- a/charts/kong-operator/ci/__snapshots__/nightly-can-be-used-values.snap +++ b/charts/kong-operator/ci/__snapshots__/nightly-can-be-used-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/pod-annotations-values.snap b/charts/kong-operator/ci/__snapshots__/pod-annotations-values.snap index e82cf129ee..5b88bac7c1 100644 --- a/charts/kong-operator/ci/__snapshots__/pod-annotations-values.snap +++ b/charts/kong-operator/ci/__snapshots__/pod-annotations-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/probes-and-args-values.snap b/charts/kong-operator/ci/__snapshots__/probes-and-args-values.snap index 2ab9c919ef..e1ac380afd 100644 --- a/charts/kong-operator/ci/__snapshots__/probes-and-args-values.snap +++ b/charts/kong-operator/ci/__snapshots__/probes-and-args-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/tolerations-values.snap b/charts/kong-operator/ci/__snapshots__/tolerations-values.snap index 6df51d4549..ed2abdac4c 100644 --- a/charts/kong-operator/ci/__snapshots__/tolerations-values.snap +++ b/charts/kong-operator/ci/__snapshots__/tolerations-values.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/validating-policies-dataplane-ports-disabled.snap b/charts/kong-operator/ci/__snapshots__/validating-policies-dataplane-ports-disabled.snap index 19068a6fee..ebade33d89 100644 --- a/charts/kong-operator/ci/__snapshots__/validating-policies-dataplane-ports-disabled.snap +++ b/charts/kong-operator/ci/__snapshots__/validating-policies-dataplane-ports-disabled.snap @@ -55707,6 +55707,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57597,6 +57858,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57614,6 +57876,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/webhook-conversion-disabled-values.snap b/charts/kong-operator/ci/__snapshots__/webhook-conversion-disabled-values.snap index 52cd3a948c..f9e92a8a1c 100644 --- a/charts/kong-operator/ci/__snapshots__/webhook-conversion-disabled-values.snap +++ b/charts/kong-operator/ci/__snapshots__/webhook-conversion-disabled-values.snap @@ -29859,6 +29859,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -31076,6 +31337,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -31093,6 +31355,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/webhook-conversion-enabled-cert-manager.snap b/charts/kong-operator/ci/__snapshots__/webhook-conversion-enabled-cert-manager.snap index 6063f8e80d..99a719fb80 100644 --- a/charts/kong-operator/ci/__snapshots__/webhook-conversion-enabled-cert-manager.snap +++ b/charts/kong-operator/ci/__snapshots__/webhook-conversion-enabled-cert-manager.snap @@ -55657,6 +55657,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -57547,6 +57808,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -57564,6 +57826,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/ci/__snapshots__/webhooks-validating-and-conversion-disabled-values.snap b/charts/kong-operator/ci/__snapshots__/webhooks-validating-and-conversion-disabled-values.snap index f5c73b6da4..ebdc141272 100644 --- a/charts/kong-operator/ci/__snapshots__/webhooks-validating-and-conversion-disabled-values.snap +++ b/charts/kong-operator/ci/__snapshots__/webhooks-validating-and-conversion-disabled-values.snap @@ -29834,6 +29834,267 @@ spec: # Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : true' + - message: spec.createGatewayRequest with name must be set when source is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} +--- +# Source: kong-operator/charts/ko-crds/templates/ko-crds.yaml +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition metadata: annotations: helm.sh/resource-policy: keep @@ -31051,6 +31312,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -31068,6 +31330,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/charts/kong-operator/templates/cluster-role.yaml b/charts/kong-operator/templates/cluster-role.yaml index 90a6e94aac..80c5b56e64 100644 --- a/charts/kong-operator/templates/cluster-role.yaml +++ b/charts/kong-operator/templates/cluster-role.yaml @@ -416,6 +416,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -433,6 +434,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/config/crd/kong-operator/konnect.konghq.com_konnecteventgateways.yaml b/config/crd/kong-operator/konnect.konghq.com_konnecteventgateways.yaml new file mode 100644 index 0000000000..b9672a5c52 --- /dev/null +++ b/config/crd/kong-operator/konnect.konghq.com_konnecteventgateways.yaml @@ -0,0 +1,284 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + kubernetes-configuration.konghq.com/channels: kong-operator + kubernetes-configuration.konghq.com/version: v2.1.0 + name: konnecteventgateways.konnect.konghq.com +spec: + group: konnect.konghq.com + names: + categories: + - kong + - konnect + kind: KonnectEventGateway + listKind: KonnectEventGatewayList + plural: konnecteventgateways + shortNames: + - keg + singular: konnecteventgateway + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The Resource is Programmed on Konnect + jsonPath: .status.conditions[?(@.type=='Programmed')].status + name: Programmed + type: string + - description: Konnect ID + jsonPath: .status.id + name: ID + type: string + - description: Konnect Organization ID this resource belongs to. + jsonPath: .status.organizationID + name: OrgID + type: string + - jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + KonnectEventGateway is the Schema for the Konnect Event Gateways API. + It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: Spec defines the desired state of KonnectEventGateway. + properties: + createGatewayRequest: + description: |- + CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. + Only applicable when source is Origin. + properties: + description: + description: Description is a human-readable description of the + Event Gateway. + maxLength: 512 + type: string + labels: + additionalProperties: + type: string + description: Labels are metadata key-value pairs for filtering + and searching. + type: object + minRuntimeVersion: + description: |- + MinRuntimeVersion is the minimum keg version that can connect to this gateway. + Must match the pattern X.Y (e.g. "1.1"). + pattern: ^\d+\.\d+$ + type: string + name: + description: Name is the human-readable name of the Event Gateway. + maxLength: 255 + minLength: 1 + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: spec.createGatewayRequest.labels must not have more than + 40 entries + rule: '!has(self.labels) || size(self.labels) <= 40' + - message: spec.createGatewayRequest.labels keys must be of length + 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(key) >= 1 + && size(key) <= 63)' + - message: spec.createGatewayRequest.labels values must be of length + 1-63 characters + rule: '!has(self.labels) || self.labels.all(key, size(self.labels[key]) + >= 1 && size(self.labels[key]) <= 63)' + - message: spec.createGatewayRequest.labels keys must not start with + 'kong', 'konnect', 'mesh', 'kic' or '_' + rule: '!has(self.labels) || self.labels.all(key, !key.startsWith(''kong'') + && !key.startsWith(''konnect'') && !key.startsWith(''mesh'') && + !key.startsWith(''kic'') && !key.startsWith(''_''))' + konnect: + description: KonnectConfiguration contains the Konnect API authentication + configuration. + properties: + name: + description: Name is the name of the KonnectAPIAuthConfiguration + resource. + minLength: 1 + type: string + namespace: + description: |- + Namespace is the namespace of the KonnectAPIAuthConfiguration resource. + If not specified, defaults to the same namespace as the KonnectConfiguration resource. + minLength: 1 + type: string + required: + - name + type: object + mirror: + description: |- + Mirror holds the configuration for a mirrored Event Gateway. + Only applicable when source is Mirror. + properties: + konnect: + description: Konnect contains the ID of the existing Event Gateway + in Konnect. + properties: + id: + description: ID is the UUID of the existing Event Gateway + in Konnect. + maxLength: 36 + pattern: ^[0-9a-f]{8}(?:\-[0-9a-f]{4}){3}-[0-9a-f]{12}$ + type: string + required: + - id + type: object + required: + - konnect + type: object + source: + default: Origin + description: |- + Source represents the source type of the Konnect entity. + Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event + Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the + operator only reads its state and populates the status. + enum: + - Origin + - Mirror + type: string + type: object + x-kubernetes-validations: + - message: spec.source is immutable + rule: self.source == oldSelf.source + - message: spec.createGatewayRequest cannot be set when source is Mirror + rule: 'self.source == ''Mirror'' ? !has(self.createGatewayRequest) : + true' + - message: spec.createGatewayRequest with name must be set when source + is Origin + rule: 'self.source == ''Origin'' ? has(self.createGatewayRequest) : + true' + - message: spec.mirror must be set when source is Mirror + rule: 'self.source == ''Mirror'' ? has(self.mirror) : true' + - message: spec.mirror cannot be set when source is Origin + rule: 'self.source == ''Origin'' ? !has(self.mirror) : true' + status: + description: Status defines the observed state of KonnectEventGateway. + properties: + conditions: + default: + - lastTransitionTime: "1970-01-01T00:00:00Z" + message: Waiting for controller + reason: Pending + status: Unknown + type: Programmed + description: |- + Conditions describe the current conditions of the KonnectEventGateway. + + Known condition types are: + + * "Programmed" + * "APIAuthValid" + items: + description: Condition contains details for one aspect of the current + state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + maxItems: 8 + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + id: + description: |- + ID is the unique identifier of the Konnect entity as assigned by Konnect API. + If it's unset (empty string), it means the Konnect entity hasn't been created yet. + type: string + organizationID: + description: OrgID is ID of Konnect Org that this entity has been + created in. + type: string + serverURL: + description: ServerURL is the URL of the Konnect server in which the + entity exists. + type: string + type: object + required: + - spec + type: object + x-kubernetes-validations: + - message: spec.konnect is immutable when an entity is already Programmed + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, + c.type == ''Programmed'' && c.status == ''True'')) ? true : self.spec.konnect + == oldSelf.spec.konnect' + - message: spec.konnect is immutable when an entity refers to a Valid API + Auth Configuration + rule: '(!has(self.status) || !has(self.status.conditions) || !self.status.conditions.exists(c, + c.type == ''APIAuthValid'' && c.status == ''True'')) ? true : self.spec.konnect + == oldSelf.spec.konnect' + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/kong-operator/kustomization.yaml b/config/crd/kong-operator/kustomization.yaml index 749f91afee..94d96aa055 100644 --- a/config/crd/kong-operator/kustomization.yaml +++ b/config/crd/kong-operator/kustomization.yaml @@ -39,5 +39,6 @@ resources: - konnect.konghq.com_konnectcloudgatewaydataplanegroupconfigurations.yaml - konnect.konghq.com_konnectcloudgatewaynetworks.yaml - konnect.konghq.com_konnectcloudgatewaytransitgateways.yaml + - konnect.konghq.com_konnecteventgateways.yaml - konnect.konghq.com_konnectextensions.yaml - konnect.konghq.com_konnectgatewaycontrolplanes.yaml \ No newline at end of file diff --git a/config/rbac/role/role.yaml b/config/rbac/role/role.yaml index 8ed92df793..1694ee2ec9 100644 --- a/config/rbac/role/role.yaml +++ b/config/rbac/role/role.yaml @@ -416,6 +416,7 @@ rules: - konnectcloudgatewaydataplanegroupconfigurations - konnectcloudgatewaynetworks - konnectcloudgatewaytransitgateways + - konnecteventgateways verbs: - get - list @@ -433,6 +434,8 @@ rules: - konnectcloudgatewaynetworks/status - konnectcloudgatewaytransitgateways/finalizers - konnectcloudgatewaytransitgateways/status + - konnecteventgateways/finalizers + - konnecteventgateways/status - konnectextensions/finalizers - konnectextensions/status - konnectgatewaycontrolplanes/finalizers diff --git a/config/samples/konnect_eventgateway.yaml b/config/samples/konnect_eventgateway.yaml new file mode 100644 index 0000000000..798976c3c5 --- /dev/null +++ b/config/samples/konnect_eventgateway.yaml @@ -0,0 +1,53 @@ + +apiVersion: v1 +kind: Namespace +metadata: + name: auth +--- +# KonnectAPIAuthConfiguration holds the PAT used to authenticate with Konnect. +# Replace the token and serverURL with your own values. +# For available server URLs see: https://docs.konghq.com/konnect/network/ +kind: KonnectAPIAuthConfiguration +apiVersion: konnect.konghq.com/v1alpha1 +metadata: + name: konnect-api-auth + namespace: auth +spec: + type: token + token: kpat_PUT_YOUR_TOKEN_HERE + serverURL: us.api.konghq.tech +--- +# KonnectEventGateway (Origin): the operator creates and owns the Event Gateway in Konnect. +# Once reconciled, status.id will be populated with the Konnect Event Gateway ID. +kind: KonnectEventGateway +apiVersion: konnect.konghq.com/v1alpha1 +metadata: + name: my-event-gateway + namespace: default +spec: + source: Origin + createGatewayRequest: + name: my-event-gateway + description: "Managed by kong-operator" + minRuntimeVersion: "1.1" + labels: + env: dev + konnect: + name: konnect-api-auth + namespace: auth +--- +# KongReferenceGrant allows KonnectEventGateway in 'default' to reference +# KonnectAPIAuthConfiguration in 'auth'. +apiVersion: configuration.konghq.com/v1alpha1 +kind: KongReferenceGrant +metadata: + name: allow-event-gateway-to-auth + namespace: auth +spec: + from: + - group: konnect.konghq.com + kind: KonnectEventGateway + namespace: default + to: + - group: konnect.konghq.com + kind: KonnectAPIAuthConfiguration diff --git a/config/samples/konnect_eventgateway_mirror.yaml b/config/samples/konnect_eventgateway_mirror.yaml new file mode 100644 index 0000000000..fdf5fc4e86 --- /dev/null +++ b/config/samples/konnect_eventgateway_mirror.yaml @@ -0,0 +1,29 @@ +# KonnectAPIAuthConfiguration holds the PAT used to authenticate with Konnect. +# Replace the token and serverURL with your own values. +# For available server URLs see: https://docs.konghq.com/konnect/network/ +kind: KonnectAPIAuthConfiguration +apiVersion: konnect.konghq.com/v1alpha1 +metadata: + name: konnect-api-auth + namespace: default +spec: + type: token + token: kpat_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX + serverURL: eu.api.konghq.tech +--- +# KonnectEventGateway (Mirror) — the operator reads an existing Event Gateway from Konnect +# and populates status.id without creating or modifying the Konnect entity. +# Replace spec.mirror.konnect.id with the UUID of your existing Event Gateway. +kind: KonnectEventGateway +apiVersion: konnect.konghq.com/v1alpha1 +metadata: + name: existing-event-gateway + namespace: default +spec: + source: Mirror + mirror: + konnect: + id: "00000000-0000-0000-0000-000000000000" # fake Event Gateway UUID + konnect: + name: konnect-api-auth + namespace: default diff --git a/controller/konnect/constraints/constraints.go b/controller/konnect/constraints/constraints.go index 430c3f134e..2bbec7785e 100644 --- a/controller/konnect/constraints/constraints.go +++ b/controller/konnect/constraints/constraints.go @@ -40,6 +40,7 @@ type SupportedKonnectEntityType interface { konnectv1alpha1.KonnectCloudGatewayNetwork | konnectv1alpha1.KonnectCloudGatewayDataPlaneGroupConfiguration | konnectv1alpha1.KonnectCloudGatewayTransitGateway | + konnectv1alpha1.KonnectEventGateway | configurationv1alpha1.KongService | configurationv1alpha1.KongRoute | configurationv1.KongConsumer | diff --git a/controller/konnect/ops/ops.go b/controller/konnect/ops/ops.go index c6b6127a62..4a2ba16f10 100644 --- a/controller/konnect/ops/ops.go +++ b/controller/konnect/ops/ops.go @@ -112,6 +112,8 @@ func Create[ err = createSNI(ctx, sdk.GetSNIsSDK(), ent) case *configurationv1alpha1.KongDataPlaneClientCertificate: err = CreateKongDataPlaneClientCertificate(ctx, sdk.GetDataPlaneCertificatesSDK(), ent) + case *konnectv1alpha1.KonnectEventGateway: + err = ensureEventGateway(ctx, sdk.GetEventGatewaysSDK(), ent) // --------------------------------------------------------------------- // TODO: add other Konnect types default: @@ -174,6 +176,8 @@ func Create[ id, errGet = getKongCertificateForUID(ctx, sdk.GetCertificatesSDK(), ent) case *configurationv1alpha1.KongCACertificate: id, errGet = getKongCACertificateForUID(ctx, sdk.GetCACertificatesSDK(), ent) + case *konnectv1alpha1.KonnectEventGateway: + id, errGet = getEventGatewayForUID(ctx, sdk.GetEventGatewaysSDK(), ent) // --------------------------------------------------------------------- // TODO: add other Konnect types default: @@ -315,6 +319,8 @@ func Delete[ err = deleteSNI(ctx, sdk.GetSNIsSDK(), ent) case *configurationv1alpha1.KongDataPlaneClientCertificate: err = DeleteKongDataPlaneClientCertificate(ctx, sdk.GetDataPlaneCertificatesSDK(), ent) + case *konnectv1alpha1.KonnectEventGateway: + err = deleteEventGateway(ctx, sdk.GetEventGatewaysSDK(), ent) // --------------------------------------------------------------------- // TODO: add other Konnect types default: @@ -468,6 +474,10 @@ func Update[ err = updateSNI(ctx, sdk.GetSNIsSDK(), ent) case *configurationv1alpha1.KongDataPlaneClientCertificate: err = nil // DataPlaneCertificates are immutable. + case *konnectv1alpha1.KonnectEventGateway: + if ent.Spec.Source != nil && *ent.Spec.Source == commonv1alpha1.EntitySourceOrigin { + err = updateEventGateway(ctx, sdk.GetEventGatewaysSDK(), ent) + } // --------------------------------------------------------------------- // TODO: add other Konnect types @@ -852,7 +862,8 @@ func isMirrorableEntity[ TEnt constraints.EntityType[T], ](ent TEnt) bool { switch any(ent).(type) { - case *konnectv1alpha2.KonnectGatewayControlPlane: + case *konnectv1alpha2.KonnectGatewayControlPlane, + *konnectv1alpha1.KonnectEventGateway: return true default: return false @@ -865,9 +876,11 @@ func isMirrorEntity[ T constraints.SupportedKonnectEntityType, TEnt constraints.EntityType[T], ](ent TEnt) bool { - switch cp := any(ent).(type) { + switch e := any(ent).(type) { case *konnectv1alpha2.KonnectGatewayControlPlane: - return cp.Spec.Source != nil && *cp.Spec.Source == commonv1alpha1.EntitySourceMirror + return e.Spec.Source != nil && *e.Spec.Source == commonv1alpha1.EntitySourceMirror + case *konnectv1alpha1.KonnectEventGateway: + return e.Spec.Source != nil && *e.Spec.Source == commonv1alpha1.EntitySourceMirror default: return false } diff --git a/controller/konnect/ops/ops_konnecteventgateway.go b/controller/konnect/ops/ops_konnecteventgateway.go new file mode 100644 index 0000000000..6f7dbfe644 --- /dev/null +++ b/controller/konnect/ops/ops_konnecteventgateway.go @@ -0,0 +1,146 @@ +package ops + +import ( + "context" + "fmt" + + sdkkonnectgo "github.com/Kong/sdk-konnect-go" + sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components" + sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations" + + commonv1alpha1 "github.com/kong/kong-operator/v2/api/common/v1alpha1" + konnectv1alpha1 "github.com/kong/kong-operator/v2/api/konnect/v1alpha1" +) + +// ensureEventGateway ensures the Konnect Event Gateway exists. For Origin entities it +// creates the gateway; for Mirror entities it looks up the existing gateway by ID. +func ensureEventGateway( + ctx context.Context, + sdk sdkkonnectgo.EventGatewaysSDK, + eg *konnectv1alpha1.KonnectEventGateway, +) error { + switch *eg.Spec.Source { + case commonv1alpha1.EntitySourceOrigin: + return createEventGateway(ctx, sdk, eg) + case commonv1alpha1.EntitySourceMirror: + id := string(eg.Spec.Mirror.Konnect.ID) + resp, err := sdk.GetEventGateway(ctx, id) + if errWrap := wrapErrIfKonnectOpFailed(err, GetOp, eg); errWrap != nil { + return errWrap + } + if resp == nil || resp.EventGatewayInfo == nil { + return fmt.Errorf("failed getting %s: %w", eg.GetTypeName(), ErrNilResponse) + } + eg.SetKonnectID(resp.EventGatewayInfo.ID) + return nil + default: + // CEL validation prevents reaching this branch. + return fmt.Errorf("unsupported source type: %s", *eg.Spec.Source) + } +} + +// createEventGateway creates the Event Gateway in Konnect. +func createEventGateway( + ctx context.Context, + sdk sdkkonnectgo.EventGatewaysSDK, + eg *konnectv1alpha1.KonnectEventGateway, +) error { + req := sdkkonnectcomp.CreateGatewayRequest{ + Name: eg.Spec.CreateGatewayRequest.Name, + Description: eg.Spec.CreateGatewayRequest.Description, + MinRuntimeVersion: eg.Spec.CreateGatewayRequest.MinRuntimeVersion, + Labels: WithKubernetesMetadataLabels(eg, eg.Spec.CreateGatewayRequest.Labels), + } + + resp, err := sdk.CreateEventGateway(ctx, req) + if errWrap := wrapErrIfKonnectOpFailed(err, CreateOp, eg); errWrap != nil { + return errWrap + } + + if resp == nil || resp.EventGatewayInfo == nil || resp.EventGatewayInfo.ID == "" { + return fmt.Errorf("failed creating %s: %w", eg.GetTypeName(), ErrNilResponse) + } + + eg.SetKonnectID(resp.EventGatewayInfo.ID) + return nil +} + +// updateEventGateway updates an existing Origin Event Gateway in Konnect. +func updateEventGateway( + ctx context.Context, + sdk sdkkonnectgo.EventGatewaysSDK, + eg *konnectv1alpha1.KonnectEventGateway, +) error { + id := eg.GetKonnectStatus().GetKonnectID() + req := sdkkonnectcomp.UpdateGatewayRequest{ + Name: &eg.Spec.CreateGatewayRequest.Name, + Description: eg.Spec.CreateGatewayRequest.Description, + MinRuntimeVersion: eg.Spec.CreateGatewayRequest.MinRuntimeVersion, + Labels: WithKubernetesMetadataLabels(eg, eg.Spec.CreateGatewayRequest.Labels), + } + + resp, err := sdk.UpdateEventGateway(ctx, id, req) + if errWrap := wrapErrIfKonnectOpFailed(err, UpdateOp, eg); errWrap != nil { + return handleUpdateError(ctx, err, eg, func(ctx context.Context) error { + return createEventGateway(ctx, sdk, eg) + }) + } + + if resp == nil || resp.EventGatewayInfo == nil { + return fmt.Errorf("failed updating %s: %w", eg.GetTypeName(), ErrNilResponse) + } + + return nil +} + +// deleteEventGateway deletes an Origin Event Gateway from Konnect. +// Mirror gateways are never deleted. +func deleteEventGateway( + ctx context.Context, + sdk sdkkonnectgo.EventGatewaysSDK, + eg *konnectv1alpha1.KonnectEventGateway, +) error { + if eg.Spec.Source != nil && *eg.Spec.Source == commonv1alpha1.EntitySourceMirror { + return nil + } + + id := eg.GetKonnectStatus().GetKonnectID() + _, err := sdk.DeleteEventGateway(ctx, id) + if errWrap := wrapErrIfKonnectOpFailed(err, DeleteOp, eg); errWrap != nil { + return handleDeleteError(ctx, err, eg) + } + + return nil +} + +// getEventGatewayForUID lists Event Gateways filtered by spec name, then matches by +// Kubernetes UID label. Returns ("", nil) when not found (triggers a create). +func getEventGatewayForUID( + ctx context.Context, + sdk sdkkonnectgo.EventGatewaysSDK, + eg *konnectv1alpha1.KonnectEventGateway, +) (string, error) { + listResp, err := sdk.ListEventGateways(ctx, sdkkonnectops.ListEventGatewaysRequest{ + Filter: &sdkkonnectcomp.EventGatewayCommonFilter{ + Name: &sdkkonnectcomp.StringFieldContainsFilter{ + Contains: eg.Spec.CreateGatewayRequest.Name, + }, + }, + }) + if errWrap := wrapErrIfKonnectOpFailed(err, GetOp, eg); errWrap != nil { + return "", errWrap + } + + if listResp == nil || listResp.ListEventGatewaysResponse == nil { + return "", nil + } + + uid := string(eg.GetUID()) + for _, gw := range listResp.ListEventGatewaysResponse.Data { + if v, ok := gw.Labels[KubernetesUIDLabelKey]; ok && v == uid { + return gw.ID, nil + } + } + + return "", nil +} diff --git a/controller/konnect/ops/ops_konnecteventgateway_test.go b/controller/konnect/ops/ops_konnecteventgateway_test.go new file mode 100644 index 0000000000..8b2e13634e --- /dev/null +++ b/controller/konnect/ops/ops_konnecteventgateway_test.go @@ -0,0 +1,609 @@ +package ops + +import ( + "testing" + + sdkkonnectcomp "github.com/Kong/sdk-konnect-go/models/components" + sdkkonnectops "github.com/Kong/sdk-konnect-go/models/operations" + sdkkonnecterrs "github.com/Kong/sdk-konnect-go/models/sdkerrors" + "github.com/Kong/sdk-konnect-go/test/mocks" + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + k8stypes "k8s.io/apimachinery/pkg/types" + + commonv1alpha1 "github.com/kong/kong-operator/v2/api/common/v1alpha1" + konnectv1alpha1 "github.com/kong/kong-operator/v2/api/konnect/v1alpha1" + konnectv1alpha2 "github.com/kong/kong-operator/v2/api/konnect/v1alpha2" +) + +func TestCreateEventGateway(t *testing.T) { + const egID = "eg-12345" + ctx := t.Context() + + testCases := []struct { + name string + mockPair func(*testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) + expectedError error + expectedID string + }{ + { + name: "success", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + } + sdk.EXPECT(). + CreateEventGateway(ctx, sdkkonnectcomp.CreateGatewayRequest{ + Name: "my-event-gateway", + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(&sdkkonnectops.CreateEventGatewayResponse{ + EventGatewayInfo: &sdkkonnectcomp.EventGatewayInfo{ + ID: egID, + }, + }, nil) + return sdk, eg + }, + expectedID: egID, + }, + { + name: "fail", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-event-gateway", + Namespace: "default", + }, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + } + sdk.EXPECT(). + CreateEventGateway(ctx, sdkkonnectcomp.CreateGatewayRequest{ + Name: "my-event-gateway", + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(nil, &sdkkonnecterrs.BadRequestError{ + Status: 400, + Detail: "bad request", + }) + return sdk, eg + }, + expectedError: KonnectOperationFailedError{ + Op: CreateOp, + EntityType: "KonnectEventGateway", + EntityKey: "default/my-event-gateway", + Err: &sdkkonnecterrs.BadRequestError{ + Status: 400, + Detail: "bad request", + }, + }, + }, + { + name: "nil response returns error", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + } + sdk.EXPECT(). + CreateEventGateway(ctx, sdkkonnectcomp.CreateGatewayRequest{ + Name: "my-event-gateway", + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(nil, nil) + return sdk, eg + }, + expectedError: ErrNilResponse, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sdk, eg := tc.mockPair(t) + + err := createEventGateway(ctx, sdk, eg) + require.ErrorIs(t, err, tc.expectedError) + + if tc.expectedID != "" { + assert.Equal(t, tc.expectedID, eg.Status.ID) + } + }) + } +} + +func TestDeleteEventGateway(t *testing.T) { + ctx := t.Context() + + testCases := []struct { + name string + mockPair func(*testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) + expectedErr bool + }{ + { + name: "success", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + KonnectEntityStatus: konnectv1alpha2.KonnectEntityStatus{ID: "12345"}, + }, + } + sdk.EXPECT(). + DeleteEventGateway(ctx, "12345"). + Return(&sdkkonnectops.DeleteEventGatewayResponse{StatusCode: 204}, nil) + return sdk, eg + }, + }, + { + name: "fail", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{Name: "my-event-gateway", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + KonnectEntityStatus: konnectv1alpha2.KonnectEntityStatus{ID: "12345"}, + }, + } + sdk.EXPECT(). + DeleteEventGateway(ctx, "12345"). + Return(nil, &sdkkonnecterrs.BadRequestError{ + Status: 400, + Detail: "bad request", + }) + return sdk, eg + }, + expectedErr: true, + }, + { + name: "not found is ignored", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{Name: "my-event-gateway", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + KonnectEntityStatus: konnectv1alpha2.KonnectEntityStatus{ID: "12345"}, + }, + } + sdk.EXPECT(). + DeleteEventGateway(ctx, "12345"). + Return(nil, &sdkkonnecterrs.NotFoundError{ + Status: 404, + Detail: "not found", + }) + return sdk, eg + }, + }, + { + name: "mirror source skips delete", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceMirror), + Mirror: &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ID: "12345"}, + }, + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + KonnectEntityStatus: konnectv1alpha2.KonnectEntityStatus{ID: "12345"}, + }, + } + // No SDK call expected. Mirror gateways are never deleted. + return sdk, eg + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sdk, eg := tc.mockPair(t) + + err := deleteEventGateway(ctx, sdk, eg) + + if tc.expectedErr { + assert.Error(t, err) + return + } + require.NoError(t, err) + }) + } +} + +func TestUpdateEventGateway(t *testing.T) { + ctx := t.Context() + + testCases := []struct { + name string + mockPair func(*testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) + expectedErr bool + expectedID string + }{ + { + name: "success", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + KonnectEntityStatus: konnectv1alpha2.KonnectEntityStatus{ID: "12345"}, + }, + } + sdk.EXPECT(). + UpdateEventGateway(ctx, "12345", sdkkonnectcomp.UpdateGatewayRequest{ + Name: &eg.Spec.CreateGatewayRequest.Name, + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(&sdkkonnectops.UpdateEventGatewayResponse{ + EventGatewayInfo: &sdkkonnectcomp.EventGatewayInfo{ID: "12345"}, + }, nil) + return sdk, eg + }, + expectedID: "12345", + }, + { + name: "fail", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{Name: "my-event-gateway", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + KonnectEntityStatus: konnectv1alpha2.KonnectEntityStatus{ID: "12345"}, + }, + } + sdk.EXPECT(). + UpdateEventGateway(ctx, "12345", sdkkonnectcomp.UpdateGatewayRequest{ + Name: &eg.Spec.CreateGatewayRequest.Name, + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(nil, &sdkkonnecterrs.BadRequestError{ + Status: 400, + Detail: "bad request", + }) + return sdk, eg + }, + expectedErr: true, + }, + { + name: "not found triggers create", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{Name: "my-event-gateway", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + KonnectEntityStatus: konnectv1alpha2.KonnectEntityStatus{ID: "12345"}, + }, + } + sdk.EXPECT(). + UpdateEventGateway(ctx, "12345", sdkkonnectcomp.UpdateGatewayRequest{ + Name: &eg.Spec.CreateGatewayRequest.Name, + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(nil, &sdkkonnecterrs.NotFoundError{Status: 404, Detail: "not found"}) + sdk.EXPECT(). + CreateEventGateway(ctx, sdkkonnectcomp.CreateGatewayRequest{ + Name: "my-event-gateway", + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(&sdkkonnectops.CreateEventGatewayResponse{ + EventGatewayInfo: &sdkkonnectcomp.EventGatewayInfo{ID: "12345"}, + }, nil) + return sdk, eg + }, + expectedID: "12345", + }, + { + name: "nil response returns error", + mockPair: func(t *testing.T) (*mocks.MockEventGatewaysSDK, *konnectv1alpha1.KonnectEventGateway) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + KonnectEntityStatus: konnectv1alpha2.KonnectEntityStatus{ID: "12345"}, + }, + } + sdk.EXPECT(). + UpdateEventGateway(ctx, "12345", sdkkonnectcomp.UpdateGatewayRequest{ + Name: &eg.Spec.CreateGatewayRequest.Name, + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(nil, nil) + return sdk, eg + }, + expectedErr: true, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + sdk, eg := tc.mockPair(t) + + err := updateEventGateway(ctx, sdk, eg) + + if tc.expectedErr { + assert.Error(t, err) + return + } + require.NoError(t, err) + }) + } +} + +func TestEnsureEventGateway_Mirror(t *testing.T) { + const mirrorID = "mirror-eg-uuid" + ctx := t.Context() + + t.Run("mirror success", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceMirror), + Mirror: &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ID: mirrorID}, + }, + }, + } + sdk.EXPECT(). + GetEventGateway(ctx, mirrorID). + Return(&sdkkonnectops.GetEventGatewayResponse{ + EventGatewayInfo: &sdkkonnectcomp.EventGatewayInfo{ID: mirrorID}, + }, nil) + + err := ensureEventGateway(ctx, sdk, eg) + require.NoError(t, err) + assert.Equal(t, mirrorID, eg.Status.ID) + }) + + t.Run("mirror not found returns error", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{Name: "existing-eg", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceMirror), + Mirror: &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ID: mirrorID}, + }, + }, + } + sdk.EXPECT(). + GetEventGateway(ctx, mirrorID). + Return(nil, &sdkkonnecterrs.NotFoundError{Status: 404, Detail: "not found"}) + + err := ensureEventGateway(ctx, sdk, eg) + assert.Error(t, err) + }) + + t.Run("origin dispatches to create", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + } + sdk.EXPECT(). + CreateEventGateway(ctx, sdkkonnectcomp.CreateGatewayRequest{ + Name: "my-event-gateway", + Labels: WithKubernetesMetadataLabels(eg, nil), + }). + Return(&sdkkonnectops.CreateEventGatewayResponse{ + EventGatewayInfo: &sdkkonnectcomp.EventGatewayInfo{ID: mirrorID}, + }, nil) + + err := ensureEventGateway(ctx, sdk, eg) + require.NoError(t, err) + assert.Equal(t, mirrorID, eg.Status.ID) + }) + + t.Run("mirror nil response returns error", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceMirror), + Mirror: &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ID: mirrorID}, + }, + }, + } + sdk.EXPECT(). + GetEventGateway(ctx, mirrorID). + Return(nil, nil) + + err := ensureEventGateway(ctx, sdk, eg) + assert.ErrorIs(t, err, ErrNilResponse) + }) + + t.Run("unsupported source type returns error", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + unknown := commonv1alpha1.EntitySource("Unknown") + eg := &konnectv1alpha1.KonnectEventGateway{ + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: &unknown, + }, + } + + err := ensureEventGateway(ctx, sdk, eg) + assert.Error(t, err) + }) +} + +func TestGetEventGatewayForUID(t *testing.T) { + ctx := t.Context() + uid := k8stypes.UID(uuid.NewString()) + + t.Run("found by uid label", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-event-gateway", + UID: uid, + }, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + } + sdk.EXPECT(). + ListEventGateways(ctx, sdkkonnectops.ListEventGatewaysRequest{ + Filter: &sdkkonnectcomp.EventGatewayCommonFilter{ + Name: &sdkkonnectcomp.StringFieldContainsFilter{Contains: "my-event-gateway"}, + }, + }). + Return(&sdkkonnectops.ListEventGatewaysResponse{ + ListEventGatewaysResponse: &sdkkonnectcomp.ListEventGatewaysResponse{ + Data: []sdkkonnectcomp.EventGatewayInfo{ + { + ID: "found-id", + Name: "my-event-gateway", + Labels: map[string]string{ + KubernetesUIDLabelKey: string(uid), + }, + }, + }, + }, + }, nil) + + id, err := getEventGatewayForUID(ctx, sdk, eg) + require.NoError(t, err) + assert.Equal(t, "found-id", id) + }) + + t.Run("not found returns empty string", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-event-gateway", + UID: uid, + }, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + } + sdk.EXPECT(). + ListEventGateways(ctx, sdkkonnectops.ListEventGatewaysRequest{ + Filter: &sdkkonnectcomp.EventGatewayCommonFilter{ + Name: &sdkkonnectcomp.StringFieldContainsFilter{Contains: "my-event-gateway"}, + }, + }). + Return(&sdkkonnectops.ListEventGatewaysResponse{ + ListEventGatewaysResponse: &sdkkonnectcomp.ListEventGatewaysResponse{ + Data: []sdkkonnectcomp.EventGatewayInfo{ + // Different UID. should not match. + { + ID: "other-id", + Name: "my-event-gateway", + Labels: map[string]string{ + KubernetesUIDLabelKey: uuid.NewString(), + }, + }, + }, + }, + }, nil) + + id, err := getEventGatewayForUID(ctx, sdk, eg) + require.NoError(t, err) + assert.Empty(t, id) + }) + + t.Run("nil list response returns empty string", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{ + Name: "my-event-gateway", + UID: uid, + }, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + } + sdk.EXPECT(). + ListEventGateways(ctx, sdkkonnectops.ListEventGatewaysRequest{ + Filter: &sdkkonnectcomp.EventGatewayCommonFilter{ + Name: &sdkkonnectcomp.StringFieldContainsFilter{Contains: "my-event-gateway"}, + }, + }). + Return(nil, nil) + + id, err := getEventGatewayForUID(ctx, sdk, eg) + require.NoError(t, err) + assert.Empty(t, id) + }) + + t.Run("sdk error returns error", func(t *testing.T) { + sdk := mocks.NewMockEventGatewaysSDK(t) + eg := &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{Name: "my-event-gateway", Namespace: "default", UID: uid}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "my-event-gateway", + }, + }, + } + sdk.EXPECT(). + ListEventGateways(ctx, sdkkonnectops.ListEventGatewaysRequest{ + Filter: &sdkkonnectcomp.EventGatewayCommonFilter{ + Name: &sdkkonnectcomp.StringFieldContainsFilter{Contains: "my-event-gateway"}, + }, + }). + Return(nil, &sdkkonnecterrs.BadRequestError{Status: 400, Detail: "bad request"}) + + id, err := getEventGatewayForUID(ctx, sdk, eg) + assert.Error(t, err) + assert.Empty(t, id) + }) +} diff --git a/controller/konnect/ops/sdk/sdkfactory.go b/controller/konnect/ops/sdk/sdkfactory.go index e59b2e5ae1..32037ed1b3 100644 --- a/controller/konnect/ops/sdk/sdkfactory.go +++ b/controller/konnect/ops/sdk/sdkfactory.go @@ -34,6 +34,7 @@ type SDKWrapper interface { GetSNIsSDK() sdkkonnectgo.SNIsSDK GetDataPlaneCertificatesSDK() sdkkonnectgo.DPCertificatesSDK GetCloudGatewaysSDK() sdkkonnectgo.CloudGatewaysSDK + GetEventGatewaysSDK() sdkkonnectgo.EventGatewaysSDK // GetServerURL returns the server URL for recording metrics. GetServerURL() string @@ -172,6 +173,11 @@ func (w sdkWrapper) GetCloudGatewaysSDK() sdkkonnectgo.CloudGatewaysSDK { return w.sdk.CloudGateways } +// GetEventGatewaysSDK returns the SDK to operate Konnect Event Gateways SDK. +func (w sdkWrapper) GetEventGatewaysSDK() sdkkonnectgo.EventGatewaysSDK { + return w.sdk.EventGateways +} + // SDKToken is a token used to authenticate with the Konnect SDK. type SDKToken string diff --git a/controller/konnect/reconciler_generic_rbac.go b/controller/konnect/reconciler_generic_rbac.go index b1d5d1efee..7cdd5292c7 100644 --- a/controller/konnect/reconciler_generic_rbac.go +++ b/controller/konnect/reconciler_generic_rbac.go @@ -16,6 +16,10 @@ package konnect //+kubebuilder:rbac:groups=konnect.konghq.com,resources=konnectcloudgatewaytransitgateways/status,verbs=update;patch //+kubebuilder:rbac:groups=konnect.konghq.com,resources=konnectcloudgatewaytransitgateways/finalizers,verbs=update;patch +//+kubebuilder:rbac:groups=konnect.konghq.com,resources=konnecteventgateways,verbs=get;list;watch;update;patch +//+kubebuilder:rbac:groups=konnect.konghq.com,resources=konnecteventgateways/status,verbs=update;patch +//+kubebuilder:rbac:groups=konnect.konghq.com,resources=konnecteventgateways/finalizers,verbs=update;patch + //+kubebuilder:rbac:groups=configuration.konghq.com,resources=kongconsumers,verbs=get;list;watch //+kubebuilder:rbac:groups=configuration.konghq.com,resources=kongconsumers/status,verbs=get;update;patch diff --git a/controller/konnect/watch.go b/controller/konnect/watch.go index 4b4c6d8e20..bb9338fd79 100644 --- a/controller/konnect/watch.go +++ b/controller/konnect/watch.go @@ -49,6 +49,8 @@ func ReconciliationWatchOptionsForEntity[ return KonnectCloudGatewayDataPlaneGroupConfigurationReconciliationWatchOptions(cl) case *konnectv1alpha1.KonnectCloudGatewayTransitGateway: return KonnectCloudGatewayTransitGatewayWatchOptions(cl) + case *konnectv1alpha1.KonnectEventGateway: + return KonnectEventGatewayReconciliationWatchOptions(cl) case *configurationv1alpha1.KongPluginBinding: return KongPluginBindingReconciliationWatchOptions(cl) case *configurationv1alpha1.KongUpstream: @@ -317,7 +319,8 @@ type WatchableEntityType interface { configurationv1alpha1.KongKeySet | configurationv1alpha1.KongSNI | configurationv1alpha1.KongDataPlaneClientCertificate | - konnectv1alpha1.KonnectAPIAuthConfiguration + konnectv1alpha1.KonnectAPIAuthConfiguration | + konnectv1alpha1.KonnectEventGateway GetTypeName() string } diff --git a/controller/konnect/watch_konnecteventgateway.go b/controller/konnect/watch_konnecteventgateway.go new file mode 100644 index 0000000000..7cab2aaef3 --- /dev/null +++ b/controller/konnect/watch_konnecteventgateway.go @@ -0,0 +1,61 @@ +package konnect + +import ( + "context" + + ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/handler" + "sigs.k8s.io/controller-runtime/pkg/reconcile" + + configurationv1alpha1 "github.com/kong/kong-operator/v2/api/configuration/v1alpha1" + konnectv1alpha1 "github.com/kong/kong-operator/v2/api/konnect/v1alpha1" + "github.com/kong/kong-operator/v2/internal/utils/index" +) + +// KonnectEventGatewayReconciliationWatchOptions returns the watch options for KonnectEventGateway. +func KonnectEventGatewayReconciliationWatchOptions( + cl client.Client, +) []func(*ctrl.Builder) *ctrl.Builder { + return []func(*ctrl.Builder) *ctrl.Builder{ + func(b *ctrl.Builder) *ctrl.Builder { + return b.For(&konnectv1alpha1.KonnectEventGateway{}) + }, + func(b *ctrl.Builder) *ctrl.Builder { + return b.Watches( + &konnectv1alpha1.KonnectAPIAuthConfiguration{}, + handler.EnqueueRequestsFromMapFunc( + enqueueKonnectEventGatewayForKonnectAPIAuthConfiguration(cl), + ), + ) + }, + func(b *ctrl.Builder) *ctrl.Builder { + return b.Watches( + &configurationv1alpha1.KongReferenceGrant{}, + handler.EnqueueRequestsFromMapFunc( + enqueueObjectsForKongReferenceGrant[konnectv1alpha1.KonnectEventGatewayList](cl), + ), + ) + }, + } +} + +func enqueueKonnectEventGatewayForKonnectAPIAuthConfiguration( + cl client.Client, +) func(ctx context.Context, obj client.Object) []reconcile.Request { + return func(ctx context.Context, obj client.Object) []reconcile.Request { + auth, ok := obj.(*konnectv1alpha1.KonnectAPIAuthConfiguration) + if !ok { + return nil + } + var l konnectv1alpha1.KonnectEventGatewayList + if err := cl.List(ctx, &l, + client.MatchingFields{ + index.IndexFieldKonnectEventGatewayOnAPIAuthConfiguration: auth.GetNamespace() + "/" + auth.Name, + }, + ); err != nil { + return nil + } + return objectListToReconcileRequests(l.Items) + } +} diff --git a/controller/konnect/watch_konnecteventgateway_test.go b/controller/konnect/watch_konnecteventgateway_test.go new file mode 100644 index 0000000000..950705a9ce --- /dev/null +++ b/controller/konnect/watch_konnecteventgateway_test.go @@ -0,0 +1,158 @@ +package konnect + +import ( + "testing" + + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + ctrl "sigs.k8s.io/controller-runtime" + fakectrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client/fake" + + konnectv1alpha1 "github.com/kong/kong-operator/v2/api/konnect/v1alpha1" + konnectv1alpha2 "github.com/kong/kong-operator/v2/api/konnect/v1alpha2" + "github.com/kong/kong-operator/v2/internal/utils/index" + "github.com/kong/kong-operator/v2/modules/manager/scheme" +) + +func TestEnqueueKonnectEventGatewayForKonnectAPIAuthConfiguration(t *testing.T) { + auth := &konnectv1alpha1.KonnectAPIAuthConfiguration{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-auth", + Namespace: "default", + }, + } + + t.Run("non-KonnectAPIAuthConfiguration object returns nil", func(t *testing.T) { + cl := fakectrlruntimeclient.NewClientBuilder().WithScheme(scheme.Get()).Build() + f := enqueueKonnectEventGatewayForKonnectAPIAuthConfiguration(cl) + require.Nil(t, f(t.Context(), &konnectv1alpha1.KonnectEventGateway{})) + }) + + ns := func(s string) *string { return &s } + + tests := []struct { + name string + gateways []konnectv1alpha1.KonnectEventGateway + expected []ctrl.Request + }{ + { + name: "no gateways", + gateways: nil, + expected: nil, + }, + { + name: "single gateway references auth in same namespace", + gateways: []konnectv1alpha1.KonnectEventGateway{ + { + ObjectMeta: metav1.ObjectMeta{Name: "eg-1", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "test-auth", + }, + }, + }, + }, + expected: []ctrl.Request{ + {NamespacedName: types.NamespacedName{Name: "eg-1", Namespace: "default"}}, + }, + }, + { + name: "gateway in different namespace with explicit namespace override is enqueued", + gateways: []konnectv1alpha1.KonnectEventGateway{ + { + ObjectMeta: metav1.ObjectMeta{Name: "eg-1", Namespace: "other-ns"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "test-auth", + Namespace: ns("default"), + }, + }, + }, + }, + expected: []ctrl.Request{ + {NamespacedName: types.NamespacedName{Name: "eg-1", Namespace: "other-ns"}}, + }, + }, + { + name: "gateway in different namespace without namespace override is not enqueued", + gateways: []konnectv1alpha1.KonnectEventGateway{ + { + ObjectMeta: metav1.ObjectMeta{Name: "eg-1", Namespace: "other-ns"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + // No Namespace override: resolves to "other-ns/test-auth", not "default/test-auth". + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "test-auth", + }, + }, + }, + }, + expected: nil, + }, + { + name: "multiple gateways only one references auth", + gateways: []konnectv1alpha1.KonnectEventGateway{ + { + ObjectMeta: metav1.ObjectMeta{Name: "eg-1", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "test-auth", + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "eg-2", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "other-auth", + }, + }, + }, + }, + expected: []ctrl.Request{ + {NamespacedName: types.NamespacedName{Name: "eg-1", Namespace: "default"}}, + }, + }, + { + name: "multiple gateways all reference auth", + gateways: []konnectv1alpha1.KonnectEventGateway{ + { + ObjectMeta: metav1.ObjectMeta{Name: "eg-1", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "test-auth", + }, + }, + }, + { + ObjectMeta: metav1.ObjectMeta{Name: "eg-2", Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "test-auth", + }, + }, + }, + }, + expected: []ctrl.Request{ + {NamespacedName: types.NamespacedName{Name: "eg-1", Namespace: "default"}}, + {NamespacedName: types.NamespacedName{Name: "eg-2", Namespace: "default"}}, + }, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + builder := fakectrlruntimeclient.NewClientBuilder().WithScheme(scheme.Get()) + for i := range tt.gateways { + builder = builder.WithObjects(&tt.gateways[i]) + } + for _, opt := range index.OptionsForKonnectEventGateway() { + builder = builder.WithIndex(opt.Object, opt.Field, opt.ExtractValueFn) + } + cl := builder.Build() + + f := enqueueKonnectEventGatewayForKonnectAPIAuthConfiguration(cl) + require.Equal(t, tt.expected, f(t.Context(), auth)) + }) + } +} diff --git a/docs/all-api-reference.md b/docs/all-api-reference.md index 4c7b2844a4..df4af8d526 100644 --- a/docs/all-api-reference.md +++ b/docs/all-api-reference.md @@ -4941,6 +4941,7 @@ Package v1alpha1 contains API Schema definitions for the konnect.konghq.com v1al - [KonnectCloudGatewayDataPlaneGroupConfiguration](#konnect-konghq-com-v1alpha1-konnectcloudgatewaydataplanegroupconfiguration) - [KonnectCloudGatewayNetwork](#konnect-konghq-com-v1alpha1-konnectcloudgatewaynetwork) - [KonnectCloudGatewayTransitGateway](#konnect-konghq-com-v1alpha1-konnectcloudgatewaytransitgateway) +- [KonnectEventGateway](#konnect-konghq-com-v1alpha1-konnecteventgateway) - [KonnectExtension](#konnect-konghq-com-v1alpha1-konnectextension) - [KonnectGatewayControlPlane](#konnect-konghq-com-v1alpha1-konnectgatewaycontrolplane) @@ -5004,6 +5005,22 @@ KonnectCloudGatewayTransitGateway is the Schema for the Konnect Transit Gateway | `spec` _[KonnectCloudGatewayTransitGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnectcloudgatewaytransitgatewayspec)_ | Spec defines the desired state of KonnectCloudGatewayTransitGateway. | | `status` _[KonnectCloudGatewayTransitGatewayStatus](#konnect-konghq-com-v1alpha1-types-konnectcloudgatewaytransitgatewaystatus)_ | Status defines the observed state of KonnectCloudGatewayTransitGateway. | +### KonnectEventGateway + + +KonnectEventGateway is the Schema for the Konnect Event Gateways API. +It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + + + +| Field | Description | +| --- | --- | +| `apiVersion` _string_ | `konnect.konghq.com/v1alpha1` +| `kind` _string_ | `KonnectEventGateway` +| `metadata` _k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta_ | Refer to Kubernetes API documentation for fields of `metadata`. | +| `spec` _[KonnectEventGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnecteventgatewayspec)_ | Spec defines the desired state of KonnectEventGateway. | +| `status` _[KonnectEventGatewayStatus](#konnect-konghq-com-v1alpha1-types-konnecteventgatewaystatus)_ | Status defines the observed state of KonnectEventGateway. | + ### KonnectExtension @@ -5235,6 +5252,24 @@ _Appears in:_ - [KonnectGatewayControlPlaneSpec](#konnect-konghq-com-v1alpha1-types-konnectgatewaycontrolplanespec) +#### CreateEventGatewayRequest + + +CreateEventGatewayRequest maps to the Konnect CreateGatewayRequest / UpdateGatewayRequest schema. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Name is the human-readable name of the Event Gateway. | +| `description` _*string_ | Description is a human-readable description of the Event Gateway. | +| `minRuntimeVersion` _*string_ | MinRuntimeVersion is the minimum keg version that can connect to this gateway. Must match the pattern X.Y (e.g. "1.1"). | +| `labels` _map[string]string_ | Labels are metadata key-value pairs for filtering and searching. | + +_Appears in:_ + +- [KonnectEventGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnecteventgatewayspec) + #### DataPlaneClientAuthStatus @@ -5263,6 +5298,36 @@ _Appears in:_ - [KonnectExtensionDataPlane](#konnect-konghq-com-v1alpha1-types-konnectextensiondataplane) +#### EventGatewayMirrorKonnect + + +EventGatewayMirrorKonnect contains the Konnect ID of an existing Event Gateway. + + + +| Field | Description | +| --- | --- | +| `id` _[KonnectIDType](#common-konghq-com-v1alpha1-types-konnectidtype)_ | ID is the UUID of the existing Event Gateway in Konnect. | + +_Appears in:_ + +- [EventGatewayMirrorSpec](#konnect-konghq-com-v1alpha1-types-eventgatewaymirrorspec) + +#### EventGatewayMirrorSpec + + +EventGatewayMirrorSpec holds the configuration for a mirrored Event Gateway. + + + +| Field | Description | +| --- | --- | +| `konnect` _[EventGatewayMirrorKonnect](#konnect-konghq-com-v1alpha1-types-eventgatewaymirrorkonnect)_ | Konnect contains the ID of the existing Event Gateway in Konnect. | + +_Appears in:_ + +- [KonnectEventGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnecteventgatewayspec) + #### KonnectAPIAuthConfigurationSpec @@ -5494,6 +5559,42 @@ _Appears in:_ - [KonnectExtensionControlPlaneStatus](#konnect-konghq-com-v1alpha1-types-konnectextensioncontrolplanestatus) - [KonnectGatewayControlPlaneStatus](#konnect-konghq-com-v1alpha1-types-konnectgatewaycontrolplanestatus) +#### KonnectEventGatewaySpec + + +KonnectEventGatewaySpec defines the desired state of KonnectEventGateway. + + + +| Field | Description | +| --- | --- | +| `source` _[EntitySource](#common-konghq-com-v1alpha1-types-entitysource)_ | Source represents the source type of the Konnect entity. Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the operator only reads its state and populates the status. | +| `mirror` _[EventGatewayMirrorSpec](#konnect-konghq-com-v1alpha1-types-eventgatewaymirrorspec)_ | Mirror holds the configuration for a mirrored Event Gateway. Only applicable when source is Mirror. | +| `createGatewayRequest` _[CreateEventGatewayRequest](#konnect-konghq-com-v1alpha1-types-createeventgatewayrequest)_ | CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. Only applicable when source is Origin. | +| `konnect` _[ControlPlaneKonnectAPIAuthConfigurationRef](#konnect-konghq-com-v1alpha2-types-controlplanekonnectapiauthconfigurationref)_ | KonnectConfiguration contains the Konnect API authentication configuration. | + +_Appears in:_ + +- [KonnectEventGateway](#konnect-konghq-com-v1alpha1-konnecteventgateway) + +#### KonnectEventGatewayStatus + + +KonnectEventGatewayStatus defines the observed state of KonnectEventGateway. + + + +| Field | Description | +| --- | --- | +| `conditions` _[]k8s.io/apimachinery/pkg/apis/meta/v1.Condition_ | Conditions describe the current conditions of the KonnectEventGateway.

Known condition types are:

* "Programmed" * "APIAuthValid" | +| `id` _string_ | ID is the unique identifier of the Konnect entity as assigned by Konnect API. If it's unset (empty string), it means the Konnect entity hasn't been created yet. | +| `serverURL` _string_ | ServerURL is the URL of the Konnect server in which the entity exists. | +| `organizationID` _string_ | OrgID is ID of Konnect Org that this entity has been created in. | + +_Appears in:_ + +- [KonnectEventGateway](#konnect-konghq-com-v1alpha1-konnecteventgateway) + #### KonnectExtensionClientAuth @@ -5871,6 +5972,7 @@ in the control plane. _Appears in:_ - [ControlPlaneKonnectConfiguration](#konnect-konghq-com-v1alpha2-types-controlplanekonnectconfiguration) +- [KonnectEventGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnecteventgatewayspec) - [KonnectExtensionControlPlaneStatus](#konnect-konghq-com-v1alpha2-types-konnectextensioncontrolplanestatus) - [KonnectOptions](#gateway-operator-konghq-com-v2beta1-types-konnectoptions) @@ -5991,6 +6093,7 @@ _Appears in:_ - [KonnectEntityStatusWithControlPlaneAndUpstreamRefs](#konnect-konghq-com-v1alpha2-types-konnectentitystatuswithcontrolplaneandupstreamrefs) - [KonnectEntityStatusWithControlPlaneRef](#konnect-konghq-com-v1alpha2-types-konnectentitystatuswithcontrolplaneref) - [KonnectEntityStatusWithNetworkRef](#konnect-konghq-com-v1alpha2-types-konnectentitystatuswithnetworkref) +- [KonnectEventGatewayStatus](#konnect-konghq-com-v1alpha1-types-konnecteventgatewaystatus) - [KonnectGatewayControlPlaneStatus](#konnect-konghq-com-v1alpha1-types-konnectgatewaycontrolplanestatus) - [KonnectGatewayControlPlaneStatus](#konnect-konghq-com-v1alpha2-types-konnectgatewaycontrolplanestatus) diff --git a/docs/konnect-api-reference.md b/docs/konnect-api-reference.md index cf66b13169..713fd7adb3 100644 --- a/docs/konnect-api-reference.md +++ b/docs/konnect-api-reference.md @@ -13,6 +13,7 @@ Package v1alpha1 contains API Schema definitions for the konnect.konghq.com v1al - [KonnectCloudGatewayDataPlaneGroupConfiguration](#konnect-konghq-com-v1alpha1-konnectcloudgatewaydataplanegroupconfiguration) - [KonnectCloudGatewayNetwork](#konnect-konghq-com-v1alpha1-konnectcloudgatewaynetwork) - [KonnectCloudGatewayTransitGateway](#konnect-konghq-com-v1alpha1-konnectcloudgatewaytransitgateway) +- [KonnectEventGateway](#konnect-konghq-com-v1alpha1-konnecteventgateway) - [KonnectExtension](#konnect-konghq-com-v1alpha1-konnectextension) - [KonnectGatewayControlPlane](#konnect-konghq-com-v1alpha1-konnectgatewaycontrolplane) @@ -76,6 +77,22 @@ KonnectCloudGatewayTransitGateway is the Schema for the Konnect Transit Gateway | `spec` _[KonnectCloudGatewayTransitGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnectcloudgatewaytransitgatewayspec)_ | Spec defines the desired state of KonnectCloudGatewayTransitGateway. | | `status` _[KonnectCloudGatewayTransitGatewayStatus](#konnect-konghq-com-v1alpha1-types-konnectcloudgatewaytransitgatewaystatus)_ | Status defines the observed state of KonnectCloudGatewayTransitGateway. | +### KonnectEventGateway + + +KonnectEventGateway is the Schema for the Konnect Event Gateways API. +It represents an Event Gateway in Konnect, backed by the /v1/event-gateways API. + + + +| Field | Description | +| --- | --- | +| `apiVersion` _string_ | `konnect.konghq.com/v1alpha1` +| `kind` _string_ | `KonnectEventGateway` +| `metadata` _k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta_ | Refer to Kubernetes API documentation for fields of `metadata`. | +| `spec` _[KonnectEventGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnecteventgatewayspec)_ | Spec defines the desired state of KonnectEventGateway. | +| `status` _[KonnectEventGatewayStatus](#konnect-konghq-com-v1alpha1-types-konnecteventgatewaystatus)_ | Status defines the observed state of KonnectEventGateway. | + ### KonnectExtension @@ -307,6 +324,24 @@ _Appears in:_ - [KonnectGatewayControlPlaneSpec](#konnect-konghq-com-v1alpha1-types-konnectgatewaycontrolplanespec) +#### CreateEventGatewayRequest + + +CreateEventGatewayRequest maps to the Konnect CreateGatewayRequest / UpdateGatewayRequest schema. + + + +| Field | Description | +| --- | --- | +| `name` _string_ | Name is the human-readable name of the Event Gateway. | +| `description` _*string_ | Description is a human-readable description of the Event Gateway. | +| `minRuntimeVersion` _*string_ | MinRuntimeVersion is the minimum keg version that can connect to this gateway. Must match the pattern X.Y (e.g. "1.1"). | +| `labels` _map[string]string_ | Labels are metadata key-value pairs for filtering and searching. | + +_Appears in:_ + +- [KonnectEventGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnecteventgatewayspec) + #### DataPlaneClientAuthStatus @@ -335,6 +370,36 @@ _Appears in:_ - [KonnectExtensionDataPlane](#konnect-konghq-com-v1alpha1-types-konnectextensiondataplane) +#### EventGatewayMirrorKonnect + + +EventGatewayMirrorKonnect contains the Konnect ID of an existing Event Gateway. + + + +| Field | Description | +| --- | --- | +| `id` _[KonnectIDType](#common-konghq-com-v1alpha1-types-konnectidtype)_ | ID is the UUID of the existing Event Gateway in Konnect. | + +_Appears in:_ + +- [EventGatewayMirrorSpec](#konnect-konghq-com-v1alpha1-types-eventgatewaymirrorspec) + +#### EventGatewayMirrorSpec + + +EventGatewayMirrorSpec holds the configuration for a mirrored Event Gateway. + + + +| Field | Description | +| --- | --- | +| `konnect` _[EventGatewayMirrorKonnect](#konnect-konghq-com-v1alpha1-types-eventgatewaymirrorkonnect)_ | Konnect contains the ID of the existing Event Gateway in Konnect. | + +_Appears in:_ + +- [KonnectEventGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnecteventgatewayspec) + #### KonnectAPIAuthConfigurationSpec @@ -566,6 +631,42 @@ _Appears in:_ - [KonnectExtensionControlPlaneStatus](#konnect-konghq-com-v1alpha1-types-konnectextensioncontrolplanestatus) - [KonnectGatewayControlPlaneStatus](#konnect-konghq-com-v1alpha1-types-konnectgatewaycontrolplanestatus) +#### KonnectEventGatewaySpec + + +KonnectEventGatewaySpec defines the desired state of KonnectEventGateway. + + + +| Field | Description | +| --- | --- | +| `source` _[EntitySource](#common-konghq-com-v1alpha1-types-entitysource)_ | Source represents the source type of the Konnect entity. Origin means the operator owns the lifecycle — it creates, updates, and deletes the Event Gateway in Konnect. Mirror means the Event Gateway already exists in Konnect and the operator only reads its state and populates the status. | +| `mirror` _[EventGatewayMirrorSpec](#konnect-konghq-com-v1alpha1-types-eventgatewaymirrorspec)_ | Mirror holds the configuration for a mirrored Event Gateway. Only applicable when source is Mirror. | +| `createGatewayRequest` _[CreateEventGatewayRequest](#konnect-konghq-com-v1alpha1-types-createeventgatewayrequest)_ | CreateGatewayRequest groups all fields sent to POST /v1/event-gateways. Only applicable when source is Origin. | +| `konnect` _[ControlPlaneKonnectAPIAuthConfigurationRef](#konnect-konghq-com-v1alpha2-types-controlplanekonnectapiauthconfigurationref)_ | KonnectConfiguration contains the Konnect API authentication configuration. | + +_Appears in:_ + +- [KonnectEventGateway](#konnect-konghq-com-v1alpha1-konnecteventgateway) + +#### KonnectEventGatewayStatus + + +KonnectEventGatewayStatus defines the observed state of KonnectEventGateway. + + + +| Field | Description | +| --- | --- | +| `conditions` _[]k8s.io/apimachinery/pkg/apis/meta/v1.Condition_ | Conditions describe the current conditions of the KonnectEventGateway.

Known condition types are:

* "Programmed" * "APIAuthValid" | +| `id` _string_ | ID is the unique identifier of the Konnect entity as assigned by Konnect API. If it's unset (empty string), it means the Konnect entity hasn't been created yet. | +| `serverURL` _string_ | ServerURL is the URL of the Konnect server in which the entity exists. | +| `organizationID` _string_ | OrgID is ID of Konnect Org that this entity has been created in. | + +_Appears in:_ + +- [KonnectEventGateway](#konnect-konghq-com-v1alpha1-konnecteventgateway) + #### KonnectExtensionClientAuth @@ -942,6 +1043,7 @@ in the control plane. _Appears in:_ - [ControlPlaneKonnectConfiguration](#konnect-konghq-com-v1alpha2-types-controlplanekonnectconfiguration) +- [KonnectEventGatewaySpec](#konnect-konghq-com-v1alpha1-types-konnecteventgatewayspec) - [KonnectExtensionControlPlaneStatus](#konnect-konghq-com-v1alpha2-types-konnectextensioncontrolplanestatus) #### ControlPlaneKonnectConfiguration @@ -1061,6 +1163,7 @@ _Appears in:_ - [KonnectEntityStatusWithControlPlaneAndUpstreamRefs](#konnect-konghq-com-v1alpha2-types-konnectentitystatuswithcontrolplaneandupstreamrefs) - [KonnectEntityStatusWithControlPlaneRef](#konnect-konghq-com-v1alpha2-types-konnectentitystatuswithcontrolplaneref) - [KonnectEntityStatusWithNetworkRef](#konnect-konghq-com-v1alpha2-types-konnectentitystatuswithnetworkref) +- [KonnectEventGatewayStatus](#konnect-konghq-com-v1alpha1-types-konnecteventgatewaystatus) - [KonnectGatewayControlPlaneStatus](#konnect-konghq-com-v1alpha1-types-konnectgatewaycontrolplanestatus) - [KonnectGatewayControlPlaneStatus](#konnect-konghq-com-v1alpha2-types-konnectgatewaycontrolplanestatus) diff --git a/internal/utils/index/konnecteventgateway.go b/internal/utils/index/konnecteventgateway.go new file mode 100644 index 0000000000..afcb0be2ae --- /dev/null +++ b/internal/utils/index/konnecteventgateway.go @@ -0,0 +1,35 @@ +package index + +import ( + "sigs.k8s.io/controller-runtime/pkg/client" + + konnectv1alpha1 "github.com/kong/kong-operator/v2/api/konnect/v1alpha1" +) + +const ( + // IndexFieldKonnectEventGatewayOnAPIAuthConfiguration is the index field for KonnectEventGateway -> APIAuthConfiguration. + IndexFieldKonnectEventGatewayOnAPIAuthConfiguration = "konnectEventGatewayAPIAuthConfigurationRef" +) + +// OptionsForKonnectEventGateway returns required Index options for KonnectEventGateway reconciler. +func OptionsForKonnectEventGateway() []Option { + return []Option{ + { + Object: &konnectv1alpha1.KonnectEventGateway{}, + Field: IndexFieldKonnectEventGatewayOnAPIAuthConfiguration, + ExtractValueFn: konnectEventGatewayAPIAuthConfigurationRef, + }, + } +} + +func konnectEventGatewayAPIAuthConfigurationRef(object client.Object) []string { + eg, ok := object.(*konnectv1alpha1.KonnectEventGateway) + if !ok { + return nil + } + ns := eg.GetNamespace() + if eg.Spec.KonnectConfiguration.Namespace != nil { + ns = *eg.Spec.KonnectConfiguration.Namespace + } + return []string{ns + "/" + eg.Spec.KonnectConfiguration.Name} +} diff --git a/internal/utils/index/konnecteventgateway_test.go b/internal/utils/index/konnecteventgateway_test.go new file mode 100644 index 0000000000..4aac632195 --- /dev/null +++ b/internal/utils/index/konnecteventgateway_test.go @@ -0,0 +1,68 @@ +package index + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" + + konnectv1alpha1 "github.com/kong/kong-operator/v2/api/konnect/v1alpha1" + konnectv1alpha2 "github.com/kong/kong-operator/v2/api/konnect/v1alpha2" +) + +func TestKonnectEventGatewayAPIAuthConfigurationRef(t *testing.T) { + tests := []struct { + name string + input client.Object + expected []string + }{ + { + name: "returns nil for non-KonnectEventGateway object", + input: &konnectv1alpha1.KonnectAPIAuthConfiguration{}, + expected: nil, + }, + { + name: "defaults to gateway namespace when no namespace override", + input: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "my-auth", + }, + }, + }, + expected: []string{"default/my-auth"}, + }, + { + name: "uses explicit namespace when set", + input: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "my-auth", + Namespace: func() *string { s := "other-ns"; return &s }(), + }, + }, + }, + expected: []string{"other-ns/my-auth"}, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := konnectEventGatewayAPIAuthConfigurationRef(tt.input) + assert.Equal(t, tt.expected, result) + }) + } +} + +func TestOptionsForKonnectEventGateway(t *testing.T) { + options := OptionsForKonnectEventGateway() + require.Len(t, options, 1) + opt := options[0] + require.IsType(t, &konnectv1alpha1.KonnectEventGateway{}, opt.Object) + require.Equal(t, IndexFieldKonnectEventGatewayOnAPIAuthConfiguration, opt.Field) + require.NotNil(t, opt.ExtractValueFn) +} diff --git a/modules/manager/controller_setup.go b/modules/manager/controller_setup.go index 90e6f883a9..62a3605444 100644 --- a/modules/manager/controller_setup.go +++ b/modules/manager/controller_setup.go @@ -130,6 +130,7 @@ func SetupCacheIndexes(ctx context.Context, mgr manager.Manager, cfg Config) err index.OptionsForKonnectGatewayControlPlane(), index.OptionsForKonnectAPIAuthConfiguration(), index.OptionsForKonnectCloudGatewayNetwork(), + index.OptionsForKonnectEventGateway(), index.OptionsForKonnectExtension(), index.OptionsForKonnectCloudGatewayDataPlaneGroupConfiguration(cl), ) @@ -618,6 +619,7 @@ func SetupControllers(mgr manager.Manager, c *Config, cpsMgr *multiinstance.Mana newKonnectEntityController[konnectv1alpha1.KonnectCloudGatewayNetwork](controllerFactory), newKonnectEntityController[konnectv1alpha1.KonnectCloudGatewayDataPlaneGroupConfiguration](controllerFactory), newKonnectEntityController[konnectv1alpha1.KonnectCloudGatewayTransitGateway](controllerFactory), + newKonnectEntityController[konnectv1alpha1.KonnectEventGateway](controllerFactory), newKonnectEntityController[configurationv1alpha1.KongService](controllerFactory), newKonnectEntityController[configurationv1alpha1.KongRoute](controllerFactory), newKonnectEntityController[configurationv1.KongConsumer](controllerFactory), diff --git a/modules/manager/controller_setup_test.go b/modules/manager/controller_setup_test.go index 8bdd89d9f5..8ff8b0d8ba 100644 --- a/modules/manager/controller_setup_test.go +++ b/modules/manager/controller_setup_test.go @@ -23,7 +23,7 @@ func TestSetupControllers(t *testing.T) { controllerDefs, err := manager.SetupControllers(mgr, &cfg, nil) require.NoError(t, err) - const expectedControllerCount = 45 + const expectedControllerCount = 46 require.Len(t, controllerDefs, expectedControllerCount) seenControllerTypes := make(map[string]int, expectedControllerCount) diff --git a/scripts/apitypes-funcs/supportedtypes.go b/scripts/apitypes-funcs/supportedtypes.go index e44f7b3bad..86e9eeae0b 100644 --- a/scripts/apitypes-funcs/supportedtypes.go +++ b/scripts/apitypes-funcs/supportedtypes.go @@ -204,6 +204,12 @@ var supportedKonnectTypesStandalone = []supportedTypesT{ KonnectStatusEmbedded: true, GetKonnectStatusReturnType: "*konnectv1alpha2.KonnectEntityStatus", }, + { + Type: "KonnectEventGateway", + KonnectStatusType: "KonnectEntityStatus", + KonnectStatusEmbedded: true, + GetKonnectStatusReturnType: "*konnectv1alpha2.KonnectEntityStatus", + }, }, }, { diff --git a/test/crdsvalidation/konnect.konghq.com/konnecteventgateway_test.go b/test/crdsvalidation/konnect.konghq.com/konnecteventgateway_test.go new file mode 100644 index 0000000000..1619e532da --- /dev/null +++ b/test/crdsvalidation/konnect.konghq.com/konnecteventgateway_test.go @@ -0,0 +1,518 @@ +package crdsvalidation_test + +import ( + "fmt" + "testing" + + "github.com/samber/lo" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + commonv1alpha1 "github.com/kong/kong-operator/v2/api/common/v1alpha1" + konnectv1alpha1 "github.com/kong/kong-operator/v2/api/konnect/v1alpha1" + konnectv1alpha2 "github.com/kong/kong-operator/v2/api/konnect/v1alpha2" + "github.com/kong/kong-operator/v2/modules/manager/scheme" + common "github.com/kong/kong-operator/v2/test/crdsvalidation/common" + "github.com/kong/kong-operator/v2/test/envtest" +) + +func TestKonnectEventGateway(t *testing.T) { + t.Parallel() + + ctx := t.Context() + scheme := scheme.Get() + cfg, ns := envtest.Setup(t, ctx, scheme) + + validKonnectConfig := konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "auth-1", + } + + t.Run("source and mirror constraints", func(t *testing.T) { + common.TestCasesGroup[*konnectv1alpha1.KonnectEventGateway]{ + { + Name: "Origin source with createGatewayRequest is valid", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + }, + { + Name: "Origin source without createGatewayRequest is invalid", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest with name must be set when source is Origin"), + }, + { + Name: "Origin source with mirror field is invalid", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + Mirror: &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ + ID: "8ae65120-cdec-4310-84c1-4b19caf67967", + }, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.mirror cannot be set when source is Origin"), + }, + { + Name: "Mirror source with valid Konnect ID is valid", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceMirror), + Mirror: &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ + ID: "8ae65120-cdec-4310-84c1-4b19caf67967", + }, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + }, + { + Name: "Mirror source without mirror field is invalid", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceMirror), + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.mirror must be set when source is Mirror"), + }, + { + Name: "Mirror source with createGatewayRequest set is invalid", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceMirror), + Mirror: &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ + ID: "8ae65120-cdec-4310-84c1-4b19caf67967", + }, + }, + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest cannot be set when source is Mirror"), + }, + { + Name: "Mirror source with malformed Konnect ID is invalid", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceMirror), + Mirror: &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ + ID: "not-a-uuid", + }, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.mirror.konnect.id in body should match"), + }, + { + Name: "source is immutable", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + Update: func(eg *konnectv1alpha1.KonnectEventGateway) { + eg.Spec.Source = new(commonv1alpha1.EntitySourceMirror) + eg.Spec.CreateGatewayRequest = nil + eg.Spec.Mirror = &konnectv1alpha1.EventGatewayMirrorSpec{ + Konnect: konnectv1alpha1.EventGatewayMirrorKonnect{ + ID: "8ae65120-cdec-4310-84c1-4b19caf67967", + }, + } + }, + ExpectedUpdateErrorMessage: new("spec.source is immutable"), + }, + }. + RunWithConfig(t, cfg, scheme) + }) + + t.Run("konnect ref immutability", func(t *testing.T) { + common.TestCasesGroup[*konnectv1alpha1.KonnectEventGateway]{ + { + Name: "spec.konnect change is not allowed when Programmed=True", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + }, + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "auth-1", + }, + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + Conditions: []metav1.Condition{ + { + Type: "Programmed", + Status: metav1.ConditionTrue, + Reason: "Programmed", + LastTransitionTime: metav1.Now(), + }, + }, + }, + }, + Update: func(eg *konnectv1alpha1.KonnectEventGateway) { + eg.Spec.KonnectConfiguration.Name = "auth-2" + }, + ExpectedUpdateErrorMessage: new("spec.konnect is immutable when an entity is already Programmed"), + }, + { + Name: "spec.konnect change is not allowed when APIAuthValid=True", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + }, + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "auth-1", + }, + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + Conditions: []metav1.Condition{ + { + Type: "APIAuthValid", + Status: metav1.ConditionTrue, + Reason: "Valid", + LastTransitionTime: metav1.Now(), + }, + }, + }, + }, + Update: func(eg *konnectv1alpha1.KonnectEventGateway) { + eg.Spec.KonnectConfiguration.Name = "auth-2" + }, + ExpectedUpdateErrorMessage: new("spec.konnect is immutable when an entity refers to a Valid API Auth Configuration"), + }, + { + Name: "spec.konnect change is allowed when not Programmed and not APIAuthValid", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + }, + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "auth-1", + }, + }, + Status: konnectv1alpha1.KonnectEventGatewayStatus{ + Conditions: []metav1.Condition{ + { + Type: "Programmed", + Status: metav1.ConditionFalse, + Reason: "Pending", + LastTransitionTime: metav1.Now(), + }, + }, + }, + }, + Update: func(eg *konnectv1alpha1.KonnectEventGateway) { + eg.Spec.KonnectConfiguration.Name = "auth-2" + }, + }, + { + Name: "spec.konnect change is allowed when status is not set", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + }, + KonnectConfiguration: konnectv1alpha2.ControlPlaneKonnectAPIAuthConfigurationRef{ + Name: "auth-1", + }, + }, + }, + Update: func(eg *konnectv1alpha1.KonnectEventGateway) { + eg.Spec.KonnectConfiguration.Name = "auth-2" + }, + }, + }. + RunWithConfig(t, cfg, scheme) + }) + + t.Run("labels constraints", func(t *testing.T) { + common.TestCasesGroup[*konnectv1alpha1.KonnectEventGateway]{ + { + Name: "labels of length 40 is allowed", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: func() map[string]string { + labels := make(map[string]string) + for i := range 40 { + labels[fmt.Sprintf("label-%d", i)] = fmt.Sprintf("value-%d", i) + } + return labels + }(), + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + }, + { + Name: "labels length must not exceed 40", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: func() map[string]string { + labels := make(map[string]string) + for i := range 41 { + labels[fmt.Sprintf("label-%d", i)] = fmt.Sprintf("value-%d", i) + } + return labels + }(), + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels must not have more than 40 entries"), + }, + { + Name: "label key length must not exceed 63 characters", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{ + lo.RandomString(64, lo.LowerCaseLettersCharset): "value", + }, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels keys must be of length 1-63 characters"), + }, + { + Name: "label key must be at least 1 character long", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{"": "value"}, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels keys must be of length 1-63 characters"), + }, + { + Name: "label value length must not exceed 63 characters", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{ + "key": lo.RandomString(64, lo.LowerCaseLettersCharset), + }, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels values must be of length 1-63 characters"), + }, + { + Name: "label value must be at least 1 character long", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{"key": ""}, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels values must be of length 1-63 characters"), + }, + { + Name: "label key must not start with 'kong'", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{"kong_key": "value"}, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_'"), + }, + { + Name: "label key must not start with 'konnect'", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{"konnect_key": "value"}, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_'"), + }, + { + Name: "label key must not start with 'mesh'", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{"mesh_key": "value"}, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_'"), + }, + { + Name: "label key must not start with 'kic'", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{"kic_key": "value"}, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_'"), + }, + { + Name: "label key must not start with underscore", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + Labels: map[string]string{"_key": "value"}, + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.labels keys must not start with 'kong', 'konnect', 'mesh', 'kic' or '_'"), + }, + }. + RunWithConfig(t, cfg, scheme) + }) + + t.Run("minRuntimeVersion format", func(t *testing.T) { + common.TestCasesGroup[*konnectv1alpha1.KonnectEventGateway]{ + { + Name: "valid minRuntimeVersion '1.1' is accepted", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + MinRuntimeVersion: new("1.1"), + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + }, + { + Name: "valid minRuntimeVersion '10.20' is accepted", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + MinRuntimeVersion: new("10.20"), + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + }, + { + Name: "minRuntimeVersion without a dot is rejected", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + MinRuntimeVersion: new("1"), + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.minRuntimeVersion in body should match"), + }, + { + Name: "minRuntimeVersion with letters is rejected", + TestObject: &konnectv1alpha1.KonnectEventGateway{ + ObjectMeta: common.CommonObjectMeta(ns.Name), + Spec: konnectv1alpha1.KonnectEventGatewaySpec{ + Source: new(commonv1alpha1.EntitySourceOrigin), + CreateGatewayRequest: &konnectv1alpha1.CreateEventGatewayRequest{ + Name: "eg-1", + MinRuntimeVersion: new("v1.1"), + }, + KonnectConfiguration: validKonnectConfig, + }, + }, + ExpectedErrorMessage: new("spec.createGatewayRequest.minRuntimeVersion in body should match"), + }, + }. + RunWithConfig(t, cfg, scheme) + }) +} diff --git a/test/e2e/chainsaw/common/_step_templates/apply-assert-konnectEventGateway.yaml b/test/e2e/chainsaw/common/_step_templates/apply-assert-konnectEventGateway.yaml new file mode 100644 index 0000000000..1131459685 --- /dev/null +++ b/test/e2e/chainsaw/common/_step_templates/apply-assert-konnectEventGateway.yaml @@ -0,0 +1,43 @@ +# Template for creating and asserting a KonnectEventGateway. +# +# Required bindings: +# - event_gateway_name: Name of the KonnectEventGateway to create. +# - namespace: Namespace where the KonnectEventGateway will be created. +# - konnect_auth_name: Name of the KonnectAPIAuthConfiguration to reference. +apiVersion: chainsaw.kyverno.io/v1alpha1 +kind: StepTemplate +metadata: + name: apply-assert-konnect-event-gateway +spec: + try: + - apply: + resource: + apiVersion: konnect.konghq.com/v1alpha1 + kind: KonnectEventGateway + metadata: + name: ($event_gateway_name) + namespace: ($namespace) + spec: + source: Origin + createGatewayRequest: + name: ($event_gateway_name) + konnect: + name: ($konnect_auth_name) + - assert: + resource: + apiVersion: konnect.konghq.com/v1alpha1 + kind: KonnectEventGateway + metadata: + name: ($event_gateway_name) + namespace: ($namespace) + status: + (conditions[?type == 'APIAuthResolvedRef']): + - status: 'True' + reason: ResolvedRef + (conditions[?type == 'Programmed']): + - status: 'True' + reason: Programmed + # Logic: Ensure all KonnectEntityStatus fields are populated. + (id != null): true + (organizationID != null): true + (serverURL != null): true diff --git a/test/e2e/chainsaw/common/scripts/assert_konnect_event_gateway_exists.sh b/test/e2e/chainsaw/common/scripts/assert_konnect_event_gateway_exists.sh new file mode 100644 index 0000000000..c90fecfb63 --- /dev/null +++ b/test/e2e/chainsaw/common/scripts/assert_konnect_event_gateway_exists.sh @@ -0,0 +1,77 @@ +#!/usr/bin/env bash +# Asserts that an Event Gateway still exists in Konnect via the REST API. +# Retries to account for eventual consistency. Fails if the gateway is not found. +# +# Variables (from environment): +# KONNECT_TOKEN: Konnect PAT / system account token. +# KONNECT_SERVER_URL: Konnect API server hostname (e.g. "eu.api.konghq.tech"). +# GATEWAY_ID_FILE: Path to the file containing the Event Gateway UUID. +# MAX_RETRIES: (optional) Maximum number of retry attempts. Default: 180. +# RETRY_DELAY: (optional) Delay in seconds between retries. Default: 1. + +set -o errexit +set -o nounset +set -o pipefail + +KONNECT_TOKEN="${KONNECT_TOKEN}" +KONNECT_SERVER_URL="${KONNECT_SERVER_URL}" +GATEWAY_ID_FILE="${GATEWAY_ID_FILE}" +MAX_RETRIES="${MAX_RETRIES:-180}" +RETRY_DELAY="${RETRY_DELAY:-1}" + +GATEWAY_ID=$(cat "${GATEWAY_ID_FILE}") +API_URL="https://${KONNECT_SERVER_URL}/v1/event-gateways/${GATEWAY_ID}" +# Redact token from any logged curl command. +CURL_CMD="curl --silent --show-error --request GET ${API_URL} --header 'Authorization: Bearer [REDACTED]'" + +RESPONSE_BODY_FILE="/tmp/konnect_assert_response.json" +CURL_STDERR_FILE="/tmp/konnect_assert_stderr.txt" + +LAST_HTTP_STATUS="" +LAST_RESPONSE="" +LAST_CURL_STDERR="" + +for ATTEMPT in $(seq 1 "${MAX_RETRIES}"); do + LAST_HTTP_STATUS=$(curl --silent --show-error \ + --request GET "${API_URL}" \ + --header "Authorization: Bearer ${KONNECT_TOKEN}" \ + --output "${RESPONSE_BODY_FILE}" \ + --write-out '%{http_code}' \ + 2>"${CURL_STDERR_FILE}") || true + + LAST_RESPONSE=$(cat "${RESPONSE_BODY_FILE}" 2>/dev/null || echo '{}') + LAST_CURL_STDERR=$(cat "${CURL_STDERR_FILE}" 2>/dev/null || echo '') + + if [ "${LAST_HTTP_STATUS}" = "200" ]; then + cat <"${CURL_STDERR_FILE}") || true + + LAST_RESPONSE=$(cat "${RESPONSE_BODY_FILE}" 2>/dev/null || echo '{}') + LAST_CURL_STDERR=$(cat "${CURL_STDERR_FILE}" 2>/dev/null || echo '') + + if [ "${LAST_HTTP_STATUS}" = "201" ]; then + GATEWAY_ID=$(echo "${LAST_RESPONSE}" | jq -r '.id // empty') + if [ -n "${GATEWAY_ID}" ]; then + break + fi + fi + + if [ "${ATTEMPT}" -lt "${MAX_RETRIES}" ]; then + sleep "${RETRY_DELAY}" + fi +done + +if [ -z "${GATEWAY_ID}" ]; then + cat < "${GATEWAY_ID_FILE}" + +cat </dev/null || echo '') +fi + +if [ -z "${GATEWAY_ID}" ]; then + echo '{"skipped": true, "reason": "no gateway ID provided"}' + exit 0 +fi + +API_URL="https://${KONNECT_SERVER_URL}/v1/event-gateways/${GATEWAY_ID}" +# Redact token from any logged curl command. +CURL_CMD="curl --silent --show-error --request DELETE ${API_URL} --header 'Authorization: Bearer [REDACTED]'" + +CURL_STDERR_FILE="/tmp/konnect_delete_stderr.txt" + +LAST_HTTP_STATUS="" +LAST_CURL_STDERR="" + +for ATTEMPT in $(seq 1 "${MAX_RETRIES}"); do + LAST_HTTP_STATUS=$(curl --silent --show-error \ + --request DELETE "${API_URL}" \ + --header "Authorization: Bearer ${KONNECT_TOKEN}" \ + --output /dev/null \ + --write-out '%{http_code}' \ + 2>"${CURL_STDERR_FILE}") || true + + LAST_CURL_STDERR=$(cat "${CURL_STDERR_FILE}" 2>/dev/null || echo '') + + # 204 = deleted, 404 = already gone; both are success. + if [ "${LAST_HTTP_STATUS}" = "204" ] || [ "${LAST_HTTP_STATUS}" = "404" ]; then + break + fi + + if [ "${ATTEMPT}" -lt "${MAX_RETRIES}" ]; then + sleep "${RETRY_DELAY}" + fi +done + +if [ "${LAST_HTTP_STATUS}" != "204" ] && [ "${LAST_HTTP_STATUS}" != "404" ]; then + cat <