From 10dba6a9d8743ac99754d5e44cacb069269d6fcf Mon Sep 17 00:00:00 2001 From: ashing Date: Thu, 10 Apr 2025 16:58:28 +0800 Subject: [PATCH 1/2] chore: GatewayProxy support provider Signed-off-by: ashing --- api/v1alpha1/gatewayproxy_types.go | 84 ++++++++++++ api/v1alpha1/zz_generated.deepcopy.go | 126 ++++++++++++++++++ .../gateway.apisix.io_gatewayproxies.yaml | 71 ++++++++++ go.mod | 2 +- 4 files changed, 282 insertions(+), 1 deletion(-) diff --git a/api/v1alpha1/gatewayproxy_types.go b/api/v1alpha1/gatewayproxy_types.go index 411dff07d..df364f6de 100644 --- a/api/v1alpha1/gatewayproxy_types.go +++ b/api/v1alpha1/gatewayproxy_types.go @@ -29,10 +29,94 @@ type GatewayProxySpec struct { // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster // Important: Run "make" to regenerate code after modifying this file + PublishService string `json:"publishService,omitempty"` + StatusAddress []string `json:"statusAddress,omitempty"` + Provider *Provider `json:"provider,omitempty"` Plugins []GatewayProxyPlugin `json:"plugins,omitempty"` PluginMetadata map[string]apiextensionsv1.JSON `json:"pluginMetadata,omitempty"` } +// ProviderType defines the type of provider +// +kubebuilder:validation:Enum=ControlPlane +type ProviderType string + +const ( + // ProviderTypeControlPlane represents the control plane provider type + ProviderTypeControlPlane ProviderType = "ControlPlane" +) + +// Provider defines the provider configuration for GatewayProxy +type Provider struct { + // Type specifies the type of provider + // +kubebuilder:validation:Required + Type ProviderType `json:"type"` + + // ControlPlane specifies the configuration for control plane provider + // +optional + ControlPlane *ControlPlaneProvider `json:"controlPlane,omitempty"` +} + +// AuthType defines the type of authentication +// +kubebuilder:validation:Enum=AdminKey +type AuthType string + +const ( + // AuthTypeAdminKey represents the admin key authentication type + AuthTypeAdminKey AuthType = "AdminKey" +) + +// SecretKeySelector defines a reference to a specific key within a Secret +type SecretKeySelector struct { + // Name is the name of the secret + // +kubebuilder:validation:Required + Name string `json:"name"` + + // Key is the key in the secret + // +kubebuilder:validation:Required + Key string `json:"key"` +} + +// AdminKeyAuth defines the admin key authentication configuration +type AdminKeyAuth struct { + // Value specifies the admin key value directly (not recommended for production) + // +optional + Value string `json:"value,omitempty"` + + // ValueFrom specifies the source of the admin key + // +optional + ValueFrom *AdminKeyValueFrom `json:"valueFrom,omitempty"` +} + +// AdminKeyValueFrom defines the source of the admin key +type AdminKeyValueFrom struct { + // SecretKeyRef references a key in a Secret + // +optional + SecretKeyRef *SecretKeySelector `json:"secretKeyRef,omitempty"` +} + +// ControlPlaneAuth defines the authentication configuration for control plane +type ControlPlaneAuth struct { + // Type specifies the type of authentication + // +kubebuilder:validation:Required + Type AuthType `json:"type"` + + // AdminKey specifies the admin key authentication configuration + // +optional + AdminKey *AdminKeyAuth `json:"adminKey,omitempty"` +} + +// ControlPlaneProvider defines the configuration for control plane provider +type ControlPlaneProvider struct { + // Endpoints specifies the list of control plane endpoints + // +kubebuilder:validation:Required + // +kubebuilder:validation:MinItems=1 + Endpoints []string `json:"endpoints"` + + // Auth specifies the authentication configuration + // +kubebuilder:validation:Required + Auth ControlPlaneAuth `json:"auth"` +} + // +kubebuilder:object:root=true // GatewayProxy is the Schema for the gatewayproxies API type GatewayProxy struct { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 562df618a..6eb35c571 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -26,6 +26,46 @@ import ( runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdminKeyAuth) DeepCopyInto(out *AdminKeyAuth) { + *out = *in + if in.ValueFrom != nil { + in, out := &in.ValueFrom, &out.ValueFrom + *out = new(AdminKeyValueFrom) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdminKeyAuth. +func (in *AdminKeyAuth) DeepCopy() *AdminKeyAuth { + if in == nil { + return nil + } + out := new(AdminKeyAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *AdminKeyValueFrom) DeepCopyInto(out *AdminKeyValueFrom) { + *out = *in + if in.SecretKeyRef != nil { + in, out := &in.SecretKeyRef, &out.SecretKeyRef + *out = new(SecretKeySelector) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AdminKeyValueFrom. +func (in *AdminKeyValueFrom) DeepCopy() *AdminKeyValueFrom { + if in == nil { + return nil + } + out := new(AdminKeyValueFrom) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Consumer) DeepCopyInto(out *Consumer) { *out = *in @@ -115,6 +155,47 @@ func (in *ConsumerSpec) DeepCopy() *ConsumerSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneAuth) DeepCopyInto(out *ControlPlaneAuth) { + *out = *in + if in.AdminKey != nil { + in, out := &in.AdminKey, &out.AdminKey + *out = new(AdminKeyAuth) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneAuth. +func (in *ControlPlaneAuth) DeepCopy() *ControlPlaneAuth { + if in == nil { + return nil + } + out := new(ControlPlaneAuth) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ControlPlaneProvider) DeepCopyInto(out *ControlPlaneProvider) { + *out = *in + if in.Endpoints != nil { + in, out := &in.Endpoints, &out.Endpoints + *out = make([]string, len(*in)) + copy(*out, *in) + } + in.Auth.DeepCopyInto(&out.Auth) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ControlPlaneProvider. +func (in *ControlPlaneProvider) DeepCopy() *ControlPlaneProvider { + if in == nil { + return nil + } + out := new(ControlPlaneProvider) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Credential) DeepCopyInto(out *Credential) { *out = *in @@ -213,6 +294,16 @@ func (in *GatewayProxyPlugin) DeepCopy() *GatewayProxyPlugin { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GatewayProxySpec) DeepCopyInto(out *GatewayProxySpec) { *out = *in + if in.StatusAddress != nil { + in, out := &in.StatusAddress, &out.StatusAddress + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Provider != nil { + in, out := &in.Provider, &out.Provider + *out = new(Provider) + (*in).DeepCopyInto(*out) + } if in.Plugins != nil { in, out := &in.Plugins, &out.Plugins *out = make([]GatewayProxyPlugin, len(*in)) @@ -365,6 +456,41 @@ func (in *PluginConfigSpec) DeepCopy() *PluginConfigSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Provider) DeepCopyInto(out *Provider) { + *out = *in + if in.ControlPlane != nil { + in, out := &in.ControlPlane, &out.ControlPlane + *out = new(ControlPlaneProvider) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Provider. +func (in *Provider) DeepCopy() *Provider { + if in == nil { + return nil + } + out := new(Provider) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeySelector. +func (in *SecretKeySelector) DeepCopy() *SecretKeySelector { + if in == nil { + return nil + } + out := new(SecretKeySelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretReference) DeepCopyInto(out *SecretReference) { *out = *in diff --git a/config/crd/bases/gateway.apisix.io_gatewayproxies.yaml b/config/crd/bases/gateway.apisix.io_gatewayproxies.yaml index f71f38e2c..b7ca75244 100644 --- a/config/crd/bases/gateway.apisix.io_gatewayproxies.yaml +++ b/config/crd/bases/gateway.apisix.io_gatewayproxies.yaml @@ -54,6 +54,77 @@ spec: type: string type: object type: array + provider: + description: Provider defines the provider configuration for GatewayProxy + properties: + controlPlane: + description: ControlPlane specifies the configuration for control + plane provider + properties: + auth: + description: Auth specifies the authentication configuration + properties: + adminKey: + description: AdminKey specifies the admin key authentication + configuration + properties: + value: + description: Value specifies the admin key value directly + (not recommended for production) + type: string + valueFrom: + description: ValueFrom specifies the source of the + admin key + properties: + secretKeyRef: + description: SecretKeyRef references a key in + a Secret + properties: + key: + description: Key is the key in the secret + type: string + name: + description: Name is the name of the secret + type: string + required: + - key + - name + type: object + type: object + type: object + type: + description: Type specifies the type of authentication + enum: + - AdminKey + type: string + required: + - type + type: object + endpoints: + description: Endpoints specifies the list of control plane + endpoints + items: + type: string + minItems: 1 + type: array + required: + - auth + - endpoints + type: object + type: + description: Type specifies the type of provider + enum: + - ControlPlane + type: string + required: + - type + type: object + publishService: + type: string + statusAddress: + items: + type: string + type: array type: object type: object served: true diff --git a/go.mod b/go.mod index f4da1ae13..2f07151f5 100644 --- a/go.mod +++ b/go.mod @@ -29,7 +29,6 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/net v0.28.0 gopkg.in/yaml.v2 v2.4.0 - gopkg.in/yaml.v3 v3.0.1 gorm.io/gorm v1.25.11 helm.sh/helm/v3 v3.15.4 k8s.io/api v0.31.1 @@ -213,6 +212,7 @@ require ( gopkg.in/fsnotify.v1 v1.4.7 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/apiserver v0.31.1 // indirect k8s.io/cli-runtime v0.30.3 // indirect k8s.io/component-base v0.31.1 // indirect From 48f02ae09e90c3ac2ef5ba3447176f747fd69d33 Mon Sep 17 00:00:00 2001 From: ashing Date: Fri, 11 Apr 2025 16:01:22 +0800 Subject: [PATCH 2/2] fix: r Signed-off-by: ashing --- api/v1alpha1/gatewayproxy_types.go | 7 ++-- api/v1alpha1/zz_generated.deepcopy.go | 42 +++++++++---------- .../gateway.apisix.io_gatewayproxies.yaml | 7 +++- 3 files changed, 31 insertions(+), 25 deletions(-) diff --git a/api/v1alpha1/gatewayproxy_types.go b/api/v1alpha1/gatewayproxy_types.go index df364f6de..cb0404213 100644 --- a/api/v1alpha1/gatewayproxy_types.go +++ b/api/v1alpha1/gatewayproxy_types.go @@ -31,7 +31,7 @@ type GatewayProxySpec struct { PublishService string `json:"publishService,omitempty"` StatusAddress []string `json:"statusAddress,omitempty"` - Provider *Provider `json:"provider,omitempty"` + Provider *GatewayProxyProvider `json:"provider,omitempty"` Plugins []GatewayProxyPlugin `json:"plugins,omitempty"` PluginMetadata map[string]apiextensionsv1.JSON `json:"pluginMetadata,omitempty"` } @@ -45,8 +45,9 @@ const ( ProviderTypeControlPlane ProviderType = "ControlPlane" ) -// Provider defines the provider configuration for GatewayProxy -type Provider struct { +// GatewayProxyProvider defines the provider configuration for GatewayProxy +// +kubebuilder:validation:XValidation:rule="self.type == 'ControlPlane' ? has(self.controlPlane) : true",message="controlPlane must be specified when type is ControlPlane" +type GatewayProxyProvider struct { // Type specifies the type of provider // +kubebuilder:validation:Required Type ProviderType `json:"type"` diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 6eb35c571..d934f5ef4 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -291,6 +291,26 @@ func (in *GatewayProxyPlugin) DeepCopy() *GatewayProxyPlugin { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GatewayProxyProvider) DeepCopyInto(out *GatewayProxyProvider) { + *out = *in + if in.ControlPlane != nil { + in, out := &in.ControlPlane, &out.ControlPlane + *out = new(ControlPlaneProvider) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GatewayProxyProvider. +func (in *GatewayProxyProvider) DeepCopy() *GatewayProxyProvider { + if in == nil { + return nil + } + out := new(GatewayProxyProvider) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GatewayProxySpec) DeepCopyInto(out *GatewayProxySpec) { *out = *in @@ -301,7 +321,7 @@ func (in *GatewayProxySpec) DeepCopyInto(out *GatewayProxySpec) { } if in.Provider != nil { in, out := &in.Provider, &out.Provider - *out = new(Provider) + *out = new(GatewayProxyProvider) (*in).DeepCopyInto(*out) } if in.Plugins != nil { @@ -456,26 +476,6 @@ func (in *PluginConfigSpec) DeepCopy() *PluginConfigSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *Provider) DeepCopyInto(out *Provider) { - *out = *in - if in.ControlPlane != nil { - in, out := &in.ControlPlane, &out.ControlPlane - *out = new(ControlPlaneProvider) - (*in).DeepCopyInto(*out) - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Provider. -func (in *Provider) DeepCopy() *Provider { - if in == nil { - return nil - } - out := new(Provider) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SecretKeySelector) DeepCopyInto(out *SecretKeySelector) { *out = *in diff --git a/config/crd/bases/gateway.apisix.io_gatewayproxies.yaml b/config/crd/bases/gateway.apisix.io_gatewayproxies.yaml index b7ca75244..ccf228253 100644 --- a/config/crd/bases/gateway.apisix.io_gatewayproxies.yaml +++ b/config/crd/bases/gateway.apisix.io_gatewayproxies.yaml @@ -55,7 +55,8 @@ spec: type: object type: array provider: - description: Provider defines the provider configuration for GatewayProxy + description: GatewayProxyProvider defines the provider configuration + for GatewayProxy properties: controlPlane: description: ControlPlane specifies the configuration for control @@ -119,6 +120,10 @@ spec: required: - type type: object + x-kubernetes-validations: + - message: controlPlane must be specified when type is ControlPlane + rule: 'self.type == ''ControlPlane'' ? has(self.controlPlane) : + true' publishService: type: string statusAddress: