From 75ac085efcaa73dae8f656714f6cdfe1b538ad88 Mon Sep 17 00:00:00 2001 From: Yunkang Ren Date: Mon, 21 Apr 2025 11:19:37 +0800 Subject: [PATCH] feat: multicluster config API (#6474) Signed-off-by: renyunkang --- pkg/constants/constants.go | 3 + pkg/kapis/config/v1alpha2/handler.go | 85 ++++++++++++++++++++++++++- pkg/kapis/config/v1alpha2/register.go | 12 ++++ 3 files changed, 98 insertions(+), 2 deletions(-) diff --git a/pkg/constants/constants.go b/pkg/constants/constants.go index a1af0c82c..5af124c16 100644 --- a/pkg/constants/constants.go +++ b/pkg/constants/constants.go @@ -33,6 +33,9 @@ const ( SecretTypeGenericPlatformConfig corev1.SecretType = KubeSphereConfigGroup + "/generic-platform-config" GenericPlatformConfigNameFmt = "io.kubesphere.config.platformconfig.%s" GenericPlatformConfigFileName = "configuration.yaml" + + SecretTypeClusterConnectionConfig corev1.SecretType = KubeSphereConfigGroup + "/cluster-connection-config" + ClusterConnectionConfigFileName = "configuration.yaml" ) var ( diff --git a/pkg/kapis/config/v1alpha2/handler.go b/pkg/kapis/config/v1alpha2/handler.go index 2442b06b8..7f46119d8 100644 --- a/pkg/kapis/config/v1alpha2/handler.go +++ b/pkg/kapis/config/v1alpha2/handler.go @@ -8,6 +8,7 @@ package v1alpha2 import ( "encoding/json" "fmt" + "sort" "strings" "github.com/emicklei/go-restful/v3" @@ -33,8 +34,9 @@ import ( ) const ( - themeConfigurationName = "platform-configuration-theme" - GenericPlatformConfigurationKind = "GenericPlatformConfiguration" + themeConfigurationName = "platform-configuration-theme" + GenericPlatformConfigurationKind = "GenericPlatformConfiguration" + ClusterConnectionConfigurationKind = "ClusterConnectionConfiguration" ) type GenericPlatformConfiguration struct { @@ -123,6 +125,85 @@ func (h *handler) getOAuthConfiguration(req *restful.Request, resp *restful.Resp _ = resp.WriteEntity(configuration) } +type ClusterConnectionConfiguration struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Data runtime.RawExtension `json:"data,omitempty"` +} + +func (h *handler) listClusterConnectionConfiguration(req *restful.Request, resp *restful.Response) { + secretList := &corev1.SecretList{} + if err := h.client.List(req.Request.Context(), secretList, client.InNamespace(constants.KubeSphereNamespace)); err != nil { + api.HandleError(resp, req, err) + return + } + + lists := []ClusterConnectionConfiguration{} + for _, s := range secretList.Items { + if s.Type == constants.SecretTypeClusterConnectionConfig { + config := ClusterConnectionConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: ClusterConnectionConfigurationKind, + APIVersion: APIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + UID: s.UID, + Name: s.Name, + ResourceVersion: s.ResourceVersion, + CreationTimestamp: s.CreationTimestamp, + }, + } + _ = yaml.Unmarshal(s.Data[constants.ClusterConnectionConfigFileName], &config.Data) + lists = append(lists, config) + } + } + + sort.Slice(lists, func(i, j int) bool { + return lists[i].Name < lists[j].Name + }) + _ = resp.WriteEntity(lists) +} + +func (h *handler) getClusterConnectionConfiguration(req *restful.Request, resp *restful.Response) { + configName := req.PathParameter("config") + if len(validation.IsDNS1123Label(configName)) > 0 { + api.HandleNotFound(resp, req, fmt.Errorf("platform config %s not found", configName)) + return + } + + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: constants.KubeSphereNamespace, + Name: configName, + }, + } + if err := h.client.Get(req.Request.Context(), client.ObjectKeyFromObject(secret), secret); err != nil { + if apierrors.IsNotFound(err) { + api.HandleNotFound(resp, req, fmt.Errorf("cluster connection config %s not found", configName)) + return + } + api.HandleError(resp, req, err) + return + } + + config := ClusterConnectionConfiguration{ + TypeMeta: metav1.TypeMeta{ + Kind: ClusterConnectionConfigurationKind, + APIVersion: APIVersion, + }, + ObjectMeta: metav1.ObjectMeta{ + UID: secret.UID, + Name: secret.Name, + ResourceVersion: secret.ResourceVersion, + CreationTimestamp: secret.CreationTimestamp, + }, + } + _ = yaml.Unmarshal(secret.Data[constants.ClusterConnectionConfigFileName], &config.Data) + + _ = resp.WriteEntity(config) +} + func (h *handler) getConfigz(_ *restful.Request, response *restful.Response) { _ = response.WriteAsJson(h.config) } diff --git a/pkg/kapis/config/v1alpha2/register.go b/pkg/kapis/config/v1alpha2/register.go index 157616c14..277b1b9d7 100644 --- a/pkg/kapis/config/v1alpha2/register.go +++ b/pkg/kapis/config/v1alpha2/register.go @@ -51,6 +51,18 @@ func (h *handler) AddToContainer(c *restful.Container) error { Operation("updateThemeConfiguration"). To(h.updateThemeConfiguration)) + webservice.Route(webservice.GET("/clusterconnectionconfigurations"). + Doc("Retrieve all configurations for cluster connection"). + Notes("Provides information about all cluster connection plugins"). + Operation("listClusterConnectionConfiguration"). + To(h.listClusterConnectionConfiguration)) + + webservice.Route(webservice.GET("/clusterconnectionconfigurations/{config}"). + Doc("Retrieve the configuration for cluster connection"). + Notes("Provides information about the cluster connection plugin"). + Operation("getClusterConnectionConfiguration"). + To(h.getClusterConnectionConfiguration)) + webservice.Route(webservice.POST("/platformconfigs"). Doc("Create a new platform configuration"). Notes("Allows the user to create a new configuration for the specified platform.").