From 93aa7741bc2b420988dd56dac5178c55cef481ad Mon Sep 17 00:00:00 2001 From: luomengY <2938893385@qq.com> Date: Sun, 28 Apr 2024 11:25:28 +0800 Subject: [PATCH] Switch the keadm ctl client to client go and add the restful interface for restart pod. Signed-off-by: luomengY <2938893385@qq.com> --- common/types/types.go | 5 + .../metamanager/metaserver/common/types.go | 6 + .../metaserver/handlerfactory/ext_handler.go | 48 ++++++ .../metaserver/kubernetes/storage/storage.go | 72 +++++++++ edge/pkg/metamanager/metaserver/server.go | 6 +- keadm/cmd/keadm/app/cmd/ctl/client/pod.go | 67 ++++++++ keadm/cmd/keadm/app/cmd/ctl/client/request.go | 76 +++++++++ keadm/cmd/keadm/app/cmd/ctl/get/pod.go | 19 ++- keadm/cmd/keadm/app/cmd/ctl/restart/pod.go | 106 ++++++------ keadm/cmd/keadm/app/cmd/ctl/restful/pod.go | 73 --------- .../cmd/keadm/app/cmd/ctl/restful/request.go | 151 ------------------ 11 files changed, 346 insertions(+), 283 deletions(-) create mode 100644 edge/pkg/metamanager/metaserver/common/types.go create mode 100644 edge/pkg/metamanager/metaserver/handlerfactory/ext_handler.go create mode 100644 keadm/cmd/keadm/app/cmd/ctl/client/pod.go create mode 100644 keadm/cmd/keadm/app/cmd/ctl/client/request.go delete mode 100644 keadm/cmd/keadm/app/cmd/ctl/restful/pod.go delete mode 100644 keadm/cmd/keadm/app/cmd/ctl/restful/request.go diff --git a/common/types/types.go b/common/types/types.go index dfe14dad15f..412fc82c287 100644 --- a/common/types/types.go +++ b/common/types/types.go @@ -105,3 +105,8 @@ type ImagePrePullJobResponse struct { Reason string ImageStatus []v1alpha1.ImageStatus } + +type RestartResponse struct { + ErrMessages []string `json:"errMessages,omitempty"` + LogMessages []string `json:"LogMessages,omitempty"` +} diff --git a/edge/pkg/metamanager/metaserver/common/types.go b/edge/pkg/metamanager/metaserver/common/types.go new file mode 100644 index 00000000000..63c900c897e --- /dev/null +++ b/edge/pkg/metamanager/metaserver/common/types.go @@ -0,0 +1,6 @@ +package common + +type RestartInfo struct { + Namespace string + PodNames []string +} diff --git a/edge/pkg/metamanager/metaserver/handlerfactory/ext_handler.go b/edge/pkg/metamanager/metaserver/handlerfactory/ext_handler.go new file mode 100644 index 00000000000..d442435931d --- /dev/null +++ b/edge/pkg/metamanager/metaserver/handlerfactory/ext_handler.go @@ -0,0 +1,48 @@ +package handlerfactory + +import ( + "encoding/json" + "net/http" + + "github.com/kubeedge/kubeedge/edge/pkg/metamanager/metaserver/common" +) + +func (f *Factory) Restart(namespace string) http.Handler { + h := http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + podNameBytes, err := limitedReadBody(req, int64(3*1024*1024)) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + var podNames []string + err = json.Unmarshal(podNameBytes, &podNames) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + + restartInfo := common.RestartInfo{ + PodNames: podNames, + Namespace: namespace, + } + restartResponse := f.storage.Restart(req.Context(), restartInfo) + restartResBytes, err := json.Marshal(restartResponse) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(http.StatusOK) + _, err = w.Write(restartResBytes) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + }) + return h +} diff --git a/edge/pkg/metamanager/metaserver/kubernetes/storage/storage.go b/edge/pkg/metamanager/metaserver/kubernetes/storage/storage.go index 77254a8ff02..b3e42594daf 100644 --- a/edge/pkg/metamanager/metaserver/kubernetes/storage/storage.go +++ b/edge/pkg/metamanager/metaserver/kubernetes/storage/storage.go @@ -3,7 +3,10 @@ package storage import ( "context" "encoding/json" + "fmt" + "time" + oteltrace "go.opentelemetry.io/otel/trace" "k8s.io/apimachinery/pkg/api/errors" metainternalversion "k8s.io/apimachinery/pkg/apis/meta/internalversion" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -17,9 +20,14 @@ import ( genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" "k8s.io/apiserver/pkg/registry/rest" "k8s.io/apiserver/pkg/storage" + runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" "k8s.io/klog/v2" + "k8s.io/kubernetes/pkg/kubelet/cri/remote" + "github.com/kubeedge/kubeedge/common/types" + "github.com/kubeedge/kubeedge/edge/pkg/edged/config" "github.com/kubeedge/kubeedge/edge/pkg/metamanager/metaserver/agent" + "github.com/kubeedge/kubeedge/edge/pkg/metamanager/metaserver/common" "github.com/kubeedge/kubeedge/edge/pkg/metamanager/metaserver/kubernetes/storage/sqlite" "github.com/kubeedge/kubeedge/edge/pkg/metamanager/metaserver/kubernetes/storage/sqlite/imitator" "github.com/kubeedge/kubeedge/pkg/metaserver" @@ -312,3 +320,67 @@ func (r *REST) Patch(ctx context.Context, pi metaserver.PatchInfo) (runtime.Obje } return retObj, nil } + +func (r *REST) Restart(ctx context.Context, restartInfo common.RestartInfo) *types.RestartResponse { + namespace := restartInfo.Namespace + podNames := restartInfo.PodNames + restartResponse := &types.RestartResponse{ + ErrMessages: make([]string, 0), + LogMessages: make([]string, 0), + } + + endpoint := config.Config.Edged.TailoredKubeletConfig.ContainerRuntimeEndpoint + remoteRuntimeService, err := remote.NewRemoteRuntimeService(endpoint, time.Second*10, oteltrace.NewNoopTracerProvider()) + if err != nil { + errMessage := fmt.Sprintf("new remote runtimeservice with err: %v", err) + klog.Errorf("[metaserver/restart] %v", errMessage) + restartResponse.ErrMessages = append(restartResponse.ErrMessages, errMessage) + return restartResponse + } + for _, podName := range podNames { + var labelSelector = map[string]string{ + "io.kubernetes.pod.name": podName, + "io.kubernetes.pod.namespace": namespace, + } + + filter := &runtimeapi.ContainerFilter{ + LabelSelector: labelSelector, + } + containers, err := remoteRuntimeService.ListContainers(ctx, filter) + if err != nil { + errMessage := fmt.Sprintf("failed to list containers: %v", err) + klog.Warningf("[metaserver/restart] %v", errMessage) + restartResponse.ErrMessages = append(restartResponse.ErrMessages, errMessage) + continue + } + + if len(containers) == 0 { + errMessage := fmt.Sprintf("not found pod:\"/%s/%s\"", namespace, podName) + klog.Warningf("[metaserver/restart] %v", errMessage) + restartResponse.ErrMessages = append(restartResponse.ErrMessages, errMessage) + continue + } + + count := 0 + var errMessage string + for _, container := range containers { + containerID := container.Id + err := remoteRuntimeService.StopContainer(ctx, containerID, 3) + if err != nil { + errMessage += fmt.Sprintf("failed to stop container %s for pod \"/%s/%s\" with err:%v\n", container.Metadata.Name, namespace, podName, err) + } else { + count++ + } + } + + if count == len(containers) { + message := fmt.Sprintf("the pod \"%s/%s\" restart successful", namespace, podName) + klog.V(4).Infof("[metaserver/restart] %v", message) + restartResponse.LogMessages = append(restartResponse.LogMessages, message) + } else { + klog.Warningf("[metaserver/restart] %v", errMessage) + restartResponse.ErrMessages = append(restartResponse.ErrMessages, errMessage) + } + } + return restartResponse +} diff --git a/edge/pkg/metamanager/metaserver/server.go b/edge/pkg/metamanager/metaserver/server.go index 308c92bcc35..1f4bee38310 100644 --- a/edge/pkg/metamanager/metaserver/server.go +++ b/edge/pkg/metamanager/metaserver/server.go @@ -183,7 +183,11 @@ func (ls *MetaServer) BuildBasicHandler() http.Handler { case reqInfo.Verb == "list", reqInfo.Verb == "watch": ls.Factory.List().ServeHTTP(w, req) case reqInfo.Verb == "create": - ls.Factory.Create(reqInfo).ServeHTTP(w, req) + if reqInfo.Name == "restart" { + ls.Factory.Restart(reqInfo.Namespace).ServeHTTP(w, req) + } else { + ls.Factory.Create(reqInfo).ServeHTTP(w, req) + } case reqInfo.Verb == "delete": ls.Factory.Delete().ServeHTTP(w, req) case reqInfo.Verb == "update": diff --git a/keadm/cmd/keadm/app/cmd/ctl/client/pod.go b/keadm/cmd/keadm/app/cmd/ctl/client/pod.go new file mode 100644 index 00000000000..848cbf21771 --- /dev/null +++ b/keadm/cmd/keadm/app/cmd/ctl/client/pod.go @@ -0,0 +1,67 @@ +/* +Copyright 2024 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "context" + + corev1 "k8s.io/api/core/v1" + metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +type PodRequest struct { + Namespace string + LabelSelector string + AllNamespaces bool + PodName string +} + +func (podRequest *PodRequest) GetPod(ctx context.Context) (*corev1.Pod, error) { + kubeClient, err := KubeClient() + if err != nil { + return nil, err + } + pod, err := kubeClient.CoreV1().Pods(podRequest.Namespace).Get(ctx, podRequest.PodName, metaV1.GetOptions{}) + if err != nil { + return nil, err + } + return pod, nil +} + +func (podRequest *PodRequest) GetPods(ctx context.Context) (*corev1.PodList, error) { + kubeClient, err := KubeClient() + if err != nil { + return nil, err + } + if podRequest.AllNamespaces { + podList, err := kubeClient.CoreV1().Pods(metaV1.NamespaceAll).List(ctx, metaV1.ListOptions{ + LabelSelector: podRequest.LabelSelector, + }) + if err != nil { + return nil, err + } + return podList, nil + } + + podList, err := kubeClient.CoreV1().Pods(podRequest.Namespace).List(ctx, metaV1.ListOptions{ + LabelSelector: podRequest.LabelSelector, + }) + if err != nil { + return nil, err + } + return podList, nil +} diff --git a/keadm/cmd/keadm/app/cmd/ctl/client/request.go b/keadm/cmd/keadm/app/cmd/ctl/client/request.go new file mode 100644 index 00000000000..37038ee41fc --- /dev/null +++ b/keadm/cmd/keadm/app/cmd/ctl/client/request.go @@ -0,0 +1,76 @@ +/* +Copyright 2024 The KubeEdge Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package client + +import ( + "fmt" + "time" + + "k8s.io/client-go/kubernetes" + restclient "k8s.io/client-go/rest" + "k8s.io/client-go/tools/clientcmd" + + "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/common" + keadutil "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/util" +) + +func KubeClient() (*kubernetes.Clientset, error) { + kubeConfig, err := getKubeConfig() + if err != nil { + return nil, err + } + kubeClient, err := kubernetes.NewForConfig(kubeConfig) + if err != nil { + return nil, err + } + return kubeClient, nil +} + +func getKubeConfig() (*restclient.Config, error) { + config, err := keadutil.ParseEdgecoreConfig(common.EdgecoreConfigPath) + if err != nil { + return nil, fmt.Errorf("get edge config failed with err:%v", err) + } + + if !config.Modules.MetaManager.MetaServer.Enable { + return nil, fmt.Errorf("metaserver don't open") + } + + url := config.Modules.MetaManager.MetaServer.Server + ok, requireAuthorization := config.FeatureGates["requireAuthorization"] + if ok && requireAuthorization { + url = "https://" + url + } else { + url = "http://" + url + } + kubeConfig, err := clientcmd.BuildConfigFromFlags(url, "") + if err != nil { + return nil, err + } + + if ok && requireAuthorization { + serverCrt := config.Modules.MetaManager.MetaServer.TLSCertFile + serverKey := config.Modules.MetaManager.MetaServer.TLSPrivateKeyFile + tlsCaFile := config.Modules.MetaManager.MetaServer.TLSCaFile + + kubeConfig.TLSClientConfig.CAFile = tlsCaFile + kubeConfig.TLSClientConfig.CertFile = serverCrt + kubeConfig.TLSClientConfig.KeyFile = serverKey + } + kubeConfig.Timeout = 1 * time.Minute + return kubeConfig, nil +} diff --git a/keadm/cmd/keadm/app/cmd/ctl/get/pod.go b/keadm/cmd/keadm/app/cmd/ctl/get/pod.go index 745ee63a7a1..ce445d745ff 100644 --- a/keadm/cmd/keadm/app/cmd/ctl/get/pod.go +++ b/keadm/cmd/keadm/app/cmd/ctl/get/pod.go @@ -33,7 +33,7 @@ import ( "k8s.io/kubernetes/pkg/printers/storage" "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/common" - "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/ctl/restful" + "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/ctl/client" "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/util" ) @@ -72,18 +72,19 @@ func (o *PodGetOptions) getPods(args []string) error { } nodeName := config.Modules.Edged.HostnameOverride + ctx := context.Background() var podListFilter *api.PodList if len(args) > 0 { podListFilter = &api.PodList{ Items: make([]api.Pod, 0, len(args)), } - var podRequest *restful.PodRequest + var podRequest *client.PodRequest for _, podName := range args { - podRequest = &restful.PodRequest{ + podRequest = &client.PodRequest{ Namespace: o.Namespace, PodName: podName, } - pod, err := podRequest.GetPod() + pod, err := podRequest.GetPod(ctx) if err != nil { fmt.Println(err.Error()) continue @@ -101,12 +102,12 @@ func (o *PodGetOptions) getPods(args []string) error { } } } else { - podRequest := &restful.PodRequest{ + podRequest := &client.PodRequest{ Namespace: o.Namespace, AllNamespaces: o.AllNamespaces, LabelSelector: o.LabelSelector, } - podList, err := podRequest.GetPods() + podList, err := podRequest.GetPods(ctx) if err != nil { return err } @@ -130,7 +131,11 @@ func (o *PodGetOptions) getPods(args []string) error { if len(args) > 0 { return nil } - fmt.Printf("No resources found in %s namespace.\n", o.Namespace) + if o.AllNamespaces { + fmt.Println("No resources found in all namespace.") + } else { + fmt.Printf("No resources found in %s namespace.\n", o.Namespace) + } return nil } diff --git a/keadm/cmd/keadm/app/cmd/ctl/restart/pod.go b/keadm/cmd/keadm/app/cmd/ctl/restart/pod.go index cc77150d990..7a567d7f9bd 100644 --- a/keadm/cmd/keadm/app/cmd/ctl/restart/pod.go +++ b/keadm/cmd/keadm/app/cmd/ctl/restart/pod.go @@ -18,18 +18,16 @@ package restart import ( "context" + "encoding/json" "fmt" - "time" "github.com/spf13/cobra" - oteltrace "go.opentelemetry.io/otel/trace" - runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1" + "k8s.io/client-go/kubernetes" cmdutil "k8s.io/kubectl/pkg/cmd/util" - "k8s.io/kubernetes/pkg/kubelet/cri/remote" + "github.com/kubeedge/kubeedge/common/types" "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/common" - "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/ctl/restful" - "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/util" + "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/ctl/client" ) type PodRestartOptions struct { @@ -71,51 +69,57 @@ func AddRestartPodFlags(cmd *cobra.Command, RestartPodOptions *PodRestartOptions } func (o *PodRestartOptions) restartPod(podNames []string) error { - for _, podName := range podNames { - podRequest := &restful.PodRequest{ - Namespace: o.Namespace, - PodName: podName, - } - pod, err := podRequest.GetPod() - if err != nil { - fmt.Println(err.Error()) - continue - } - config, err := util.ParseEdgecoreConfig(common.EdgecoreConfigPath) - if err != nil { - fmt.Printf("get edge config failed with err:%v\n", err) - continue - } - nodeName := config.Modules.Edged.HostnameOverride - if nodeName != pod.Spec.NodeName { - fmt.Printf("can't to restart pod: \"%s\" for node: \"%s\"\n", pod.Name, pod.Spec.NodeName) - continue - } - endpoint := config.Modules.Edged.TailoredKubeletConfig.ContainerRuntimeEndpoint - remoteRuntimeService, err := remote.NewRemoteRuntimeService(endpoint, time.Second*10, oteltrace.NewNoopTracerProvider()) - - var labelSelector = map[string]string{ - "io.kubernetes.pod.name": pod.Name, - "io.kubernetes.pod.namespace": pod.Namespace, - } - - filter := &runtimeapi.ContainerFilter{ - LabelSelector: labelSelector, - } - containers, err := remoteRuntimeService.ListContainers(context.TODO(), filter) - if err != nil { - return err - } - - for _, container := range containers { - containerID := container.Id - err := remoteRuntimeService.StopContainer(context.TODO(), containerID, 3) - if err != nil { - fmt.Printf("stop containerID:%s with err:%v\n", containerID, err) - } else { - fmt.Println(containerID) - } - } + kubeClient, err := client.KubeClient() + if err != nil { + return err + } + ctx := context.Background() + restartResponse, err := podRestart(ctx, kubeClient, o.Namespace, podNames) + if err != nil { + return err + } + + for _, logMsg := range restartResponse.LogMessages { + fmt.Println(logMsg) + } + + for _, errMsg := range restartResponse.ErrMessages { + fmt.Println(errMsg) } return nil } + +func podRestart(ctx context.Context, clientSet *kubernetes.Clientset, namespace string, podNames []string) (*types.RestartResponse, error) { + bodyBytes, err := json.Marshal(podNames) + if err != nil { + return nil, err + } + result := clientSet.CoreV1().RESTClient().Post(). + Namespace(namespace). + Resource("pods"). + SubResource("restart"). + Body(bodyBytes). + Do(ctx) + + if result.Error() != nil { + return nil, result.Error() + } + + statusCode := -1 + result.StatusCode(&statusCode) + if statusCode != 200 { + return nil, fmt.Errorf("pod restart failed with status code: %d", statusCode) + } + + body, err := result.Raw() + if err != nil { + return nil, err + } + + var restartResponse types.RestartResponse + err = json.Unmarshal(body, &restartResponse) + if err != nil { + return nil, err + } + return &restartResponse, nil +} diff --git a/keadm/cmd/keadm/app/cmd/ctl/restful/pod.go b/keadm/cmd/keadm/app/cmd/ctl/restful/pod.go deleted file mode 100644 index 6b9eabda1b4..00000000000 --- a/keadm/cmd/keadm/app/cmd/ctl/restful/pod.go +++ /dev/null @@ -1,73 +0,0 @@ -/* -Copyright 2024 The KubeEdge Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package restful - -import ( - "net/url" - - corev1 "k8s.io/api/core/v1" -) - -type PodRequest struct { - Namespace string - LabelSelector string - AllNamespaces bool - PodName string -} - -func (podRequest *PodRequest) GetPod() (*corev1.Pod, error) { - request := Request{ - Method: "GET", - Path: "/" + CoreAPIPrefix + "/" + CoreAPIGroupVersion.Version + - "/namespaces/" + podRequest.Namespace + "/pods/" + podRequest.PodName, - } - - pod, err := request.ResponseToPod() - if err != nil { - return nil, err - } - return pod, nil -} - -func (podRequest *PodRequest) GetPods() (*corev1.PodList, error) { - var request Request - if podRequest.AllNamespaces { - request = Request{ - Method: "GET", - Path: "/" + CoreAPIPrefix + "/" + CoreAPIGroupVersion.Version + "/pods", - } - } else { - request = Request{ - Method: "GET", - Path: "/" + CoreAPIPrefix + "/" + CoreAPIGroupVersion.Version + - "/namespaces/" + podRequest.Namespace + "/pods", - } - } - - if podRequest.LabelSelector != "" { - values := url.Values{} - values.Set("labelSelector", podRequest.LabelSelector) - queryParams := values.Encode() - request.Path += "?" + queryParams - } - - podList, err := request.ResponseToPodList() - if err != nil { - return nil, err - } - return podList, nil -} diff --git a/keadm/cmd/keadm/app/cmd/ctl/restful/request.go b/keadm/cmd/keadm/app/cmd/ctl/restful/request.go deleted file mode 100644 index 0e0f2c73b6d..00000000000 --- a/keadm/cmd/keadm/app/cmd/ctl/restful/request.go +++ /dev/null @@ -1,151 +0,0 @@ -/* -Copyright 2024 The KubeEdge Authors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package restful - -import ( - "crypto/tls" - "crypto/x509" - "encoding/json" - "fmt" - "io" - "net/http" - "os" - - corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/runtime/schema" - - "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/common" - util2 "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/ctl/util" - keadutil "github.com/kubeedge/kubeedge/keadm/cmd/keadm/app/cmd/util" -) - -var ( - CoreAPIPrefix = "api" - CoreAPIGroupVersion = schema.GroupVersion{Group: "", Version: "v1"} - Prefix = "apis" -) - -type Request struct { - Method string - Path string - Body io.Reader -} - -func (req *Request) RestfulRequest() (*http.Response, error) { - var client http.Client - config, err := keadutil.ParseEdgecoreConfig(common.EdgecoreConfigPath) - if err != nil { - return nil, fmt.Errorf("get edge config failed with err:%v", err) - } - if config.Modules.MetaManager.MetaServer.Enable { - url := config.Modules.MetaManager.MetaServer.Server - ok, requireAuthorization := config.FeatureGates["requireAuthorization"] - if ok && requireAuthorization { - serverCrt := config.Modules.MetaManager.MetaServer.TLSCertFile - serverKey := config.Modules.MetaManager.MetaServer.TLSPrivateKeyFile - cert, err := tls.LoadX509KeyPair(serverCrt, serverKey) - if err != nil { - return nil, fmt.Errorf("failed to load server certificate and private key with err:%v", err) - } - - tlsCaFile := config.Modules.MetaManager.MetaServer.TLSCaFile - caCert, err := os.ReadFile(tlsCaFile) - if err != nil { - return nil, fmt.Errorf("failed to load tlsCaFile with err:%v", err) - } - - caCertPool := x509.NewCertPool() - caCertPool.AppendCertsFromPEM(caCert) - - tlsConfig := &tls.Config{ - Certificates: []tls.Certificate{cert}, - //ClientAuth: tls.RequireAndVerifyClientCert, - RootCAs: caCertPool, - } - - url = "https://" + url - client = http.Client{ - Transport: &http.Transport{ - TLSClientConfig: tlsConfig, - }, - } - } else { - url = "http://" + url - client = http.Client{} - } - - request, err := http.NewRequest(req.Method, url+req.Path, req.Body) - if err != nil { - return nil, fmt.Errorf("restful format failed with err:%v", err) - } - response, err := client.Do(request) - if err != nil { - return nil, fmt.Errorf("restful failed with err:%v", err) - } - - return response, nil - } - return nil, fmt.Errorf("metaserver don't open") -} - -func (req *Request) ResponseToPodList() (*corev1.PodList, error) { - response, err := req.RestfulRequest() - if err != nil { - return nil, err - } - - bodyBytes, err := io.ReadAll(response.Body) - if err != nil { - return nil, fmt.Errorf("read response's body failed with err:%v", err) - } - - if response.StatusCode != http.StatusOK { - return nil, util2.GetErrMessage(bodyBytes) - } - - var podList *corev1.PodList - err = json.Unmarshal(bodyBytes, &podList) - if err != nil { - return nil, fmt.Errorf("parsing response's body failed with err:%v", err) - } - - return podList, err -} - -func (req *Request) ResponseToPod() (*corev1.Pod, error) { - response, err := req.RestfulRequest() - if err != nil { - return nil, err - } - - bodyBytes, err := io.ReadAll(response.Body) - if err != nil { - return nil, fmt.Errorf("read response's body failed with err:%v", err) - } - - if response.StatusCode != http.StatusOK { - return nil, util2.GetErrMessage(bodyBytes) - } - - var pod *corev1.Pod - err = json.Unmarshal(bodyBytes, &pod) - if err != nil { - return nil, fmt.Errorf("parsing response's body failed with err:%v", err) - } - - return pod, err -}