diff --git a/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/component.go b/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/component.go index fed30e0aa3..1669308d3d 100644 --- a/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/component.go +++ b/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/component.go @@ -16,7 +16,6 @@ import ( "context" "encoding/json" "fmt" - "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/remote/install" "time" "github.com/Tencent/bk-bcs/bcs-common/common/blog" @@ -30,6 +29,7 @@ import ( "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/cloudprovider/component/watch" "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/common" ioptions "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/options" + "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/remote/install" "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/remote/log/bklog" "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/remote/loop" "github.com/Tencent/bk-bcs/bcs-services/bcs-cluster-manager/internal/store/options" diff --git a/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/module.go b/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/module.go index 488223f9c9..39452ddc54 100644 --- a/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/module.go +++ b/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/module.go @@ -43,6 +43,12 @@ var ( StepName: "转移主机模块", } + // removeDataFromCmdbStep remove data from cmdb step + removeDataFromCmdbStep = cloudprovider.StepInfo{ + StepMethod: cloudprovider.RemoveDataFromCmdbAction, + StepName: "移除主机数据", + } + // removeHostFromCmdbStep remove host from cmdb step removeHostFromCmdbStep = cloudprovider.StepInfo{ StepMethod: cloudprovider.RemoveHostFromCmdbAction, @@ -68,6 +74,18 @@ func BuildTransferHostModuleStep(task *proto.Task, businessID string, moduleID s task.StepSequence = append(task.StepSequence, transferHostModuleStep.StepMethod) } +// BuildRemoveCmdbDataStep build common remove data from cmdb step +func BuildRemoveCmdbDataStep(task *proto.Task, bizID string, clusterID string, nodeNames []string) { + removeStep := cloudprovider.InitTaskStep(removeDataFromCmdbStep, cloudprovider.WithStepSkipFailed(true)) + + removeStep.Params[cloudprovider.BKBizIDKey.String()] = bizID + removeStep.Params[cloudprovider.ClusterIDKey.String()] = clusterID + removeStep.Params[cloudprovider.NodeNamesKey.String()] = strings.Join(nodeNames, ",") + + task.Steps[removeDataFromCmdbStep.StepMethod] = removeStep + task.StepSequence = append(task.StepSequence, removeDataFromCmdbStep.StepMethod) +} + // BuildRemoveHostStep build common remove host from cmdb step func BuildRemoveHostStep(task *proto.Task, bizID string, nodeIPs []string) { removeStep := cloudprovider.InitTaskStep(removeHostFromCmdbStep, cloudprovider.WithStepSkipFailed(true)) @@ -717,3 +735,236 @@ func handleNotInCmdbNodeIps(ctx context.Context, notInCmdbIps []HostInfo) error return nil } + +// RemoveDataFromCMDBTask remove data from cmdb task +func RemoveDataFromCMDBTask(taskID string, stepName string) error { // nolint + cloudprovider.GetStorageModel().CreateTaskStepLogInfo(context.Background(), taskID, stepName, + "remove cmdb data from cmdb") + start := time.Now() + // get task information and validate + state, step, err := cloudprovider.GetTaskStateAndCurrentStep(taskID, stepName) + if err != nil { + return err + } + if step == nil { + return nil + } + + // get bkBizID + bkBizIDString := step.Params[cloudprovider.BKBizIDKey.String()] + // get nodeIPs + clusterID := step.Params[cloudprovider.ClusterIDKey.String()] + nodeNamesString := step.Params[cloudprovider.NodeNamesKey.String()] + + nodeNames := strings.Split(nodeNamesString, ",") + if len(nodeNames) == 0 { + blog.Errorf("RemoveDataFromCMDBTask %s failed, nodeNames empty", taskID) + _ = state.SkipFailure(start, stepName, fmt.Errorf("nodeNames empty")) + return nil + } + + bkBizID, err := strconv.ParseInt(bkBizIDString, 10, 64) + if err != nil { + blog.Errorf("RemoveDataFromCMDBTask %s failed, invalid bkBizID, err %s", taskID, err.Error()) + _ = state.SkipFailure(start, stepName, fmt.Errorf("invalid bkBizID, err %s", err.Error())) + return nil + } + + bkNodeIDs := make([]int64, 0) + err = retry.Do(func() error { + var errLocal error + if bkNodeIDs, errLocal = getAllNodeID(bkBizID, clusterID, nodeNames); errLocal != nil { + return errLocal + } + + return nil + }, retry.Attempts(3), retry.DelayType(retry.FixedDelay), retry.Delay(time.Millisecond*500)) + if err != nil { + cloudprovider.GetStorageModel().CreateTaskStepLogError(context.Background(), taskID, stepName, + fmt.Sprintf("getAllNodeID failed [%s]", err)) + blog.Errorf("RemoveDataFromCMDBTask[%s] failed: %v", taskID, err) + _ = state.SkipFailure(start, stepName, err) + return nil + } + + if len(bkNodeIDs) > 0 { + err = retry.Do(func() error { + if errLocal := deleteAll2IDPod(bkBizID, bkNodeIDs); errLocal != nil { + return errLocal + } + + return nil + }, retry.Attempts(3), retry.DelayType(retry.FixedDelay), retry.Delay(time.Millisecond*500)) + if err != nil { + cloudprovider.GetStorageModel().CreateTaskStepLogError(context.Background(), taskID, stepName, + fmt.Sprintf("deleteAll2IDPod failed [%s]", err)) + blog.Errorf("RemoveDataFromCMDBTask[%s] failed: %v", taskID, err) + _ = state.SkipFailure(start, stepName, err) + return nil + } + + err = retry.Do(func() error { + if errLocal := deleteAll2IDIDNode(bkBizID, bkNodeIDs); errLocal != nil { + return errLocal + } + + return nil + }, retry.Attempts(3), retry.DelayType(retry.FixedDelay), retry.Delay(time.Millisecond*500)) + if err != nil { + cloudprovider.GetStorageModel().CreateTaskStepLogError(context.Background(), taskID, stepName, + fmt.Sprintf("deleteAll2IDIDNode failed [%s]", err)) + blog.Errorf("RemoveDataFromCMDBTask[%s] failed: %v", taskID, err) + _ = state.SkipFailure(start, stepName, err) + return nil + } + } + + blog.Infof("RemoveDataFromCMDBTask %s successful", taskID) + + cloudprovider.GetStorageModel().CreateTaskStepLogInfo(context.Background(), taskID, stepName, + "remove cmdb data from cmdb successful") + + // update step + _ = state.UpdateStepSucc(start, stepName) + + return nil +} + +func deleteAll2IDPod(bkBizID int64, bkNodeID []int64) error { + blog.Info("start delete all pod") + + cmdbClient := cmdb.GetCmdbClient() + if cmdbClient == nil { + return fmt.Errorf("cmdb client is not init") + } + + for { + got, err := cmdbClient.GetBcsPod(&cmdb.GetBcsPodReq{ + BKBizID: bkBizID, + Fields: []string{"id"}, + Page: cmdb.Page{ + Start: 0, + Limit: 200, + }, + Filter: &cmdb.HostPropertyFilter{ + Condition: "AND", + Rules: []cmdb.Rule{ + { + Field: "bk_node_id", + Operator: "in", + Value: bkNodeID, + }, + }, + }, + }) + if err != nil { + return err + } + + podToDelete := make([]int64, 0) + for _, pod := range *got { + podToDelete = append(podToDelete, pod.ID) + } + + if len(podToDelete) == 0 { + break + } + + blog.Info("delete pod %v", podToDelete) + err = cmdbClient.DeleteBcsPod(&cmdb.DeleteBcsPodReq{ + Data: &[]cmdb.DeleteBcsPodReqData{ + { + BKBizID: &bkBizID, + IDs: &podToDelete, + }, + }, + }) + if err != nil { + blog.Errorf("DeleteBcsPod err: %v", err) + return err + } + } + + blog.Info("delete all pod success") + + return nil +} + +func deleteAll2IDIDNode(bkBizID int64, bkNodeID []int64) error { + blog.Info("start delete all node") + + cmdbClient := cmdb.GetCmdbClient() + if cmdbClient == nil { + return fmt.Errorf("cmdb client is not init") + } + + blog.Infof("delete node: %v", bkNodeID) + err := cmdbClient.DeleteBcsNode(&cmdb.DeleteBcsNodeReq{ + BKBizID: &bkBizID, + IDs: &bkNodeID, + }) + if err != nil { + blog.Errorf("DeleteBcsNode err: %v", err) + return err + } + + blog.Info("delete all node success") + + return nil +} + +func getAllNodeID(bkBizID int64, bcsClusterID string, bcsNodeNames []string) ([]int64, error) { + blog.Info("start get all node ID") + + cmdbClient := cmdb.GetCmdbClient() + if cmdbClient == nil { + return nil, fmt.Errorf("cmdb client is not init") + } + + start := 0 + limit := 100 + nodeIDs := make([]int64, 0) + for { + got, err := cmdbClient.GetBcsNode(&cmdb.GetBcsNodeReq{ + BKBizID: bkBizID, + Page: cmdb.Page{ + Limit: limit, + Start: start, + }, + Filter: &cmdb.HostPropertyFilter{ + Condition: "AND", + Rules: []cmdb.Rule{ + { + Field: "cluster_uid", + Operator: "in", + Value: []string{bcsClusterID}, + }, + { + Field: "name", + Operator: "in", + Value: bcsNodeNames, + }, + }, + }, + }) + if err != nil { + blog.Errorf("GetBcsNode err: %v", err) + return nil, err + } + nodeToDelete := make([]int64, 0) + for _, node := range *got { + nodeToDelete = append(nodeToDelete, node.ID) + nodeIDs = append(nodeIDs, node.ID) + } + + if len(nodeToDelete) == 0 { + break + } + + start += limit + } + + blog.Info("get all node ID success") + + return nodeIDs, nil +} diff --git a/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/task.go b/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/task.go index a97b4f359e..6fc270f199 100644 --- a/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/task.go +++ b/bcs-services/bcs-cluster-manager/internal/cloudprovider/common/task.go @@ -38,6 +38,7 @@ func RegisterCommonActions() map[string]interface{} { cloudprovider.InstallImagePullSecretAddonAction: EnsureInstallImageSecretTask, cloudprovider.InstallGseAgentAction: InstallGSEAgentTask, cloudprovider.TransferHostModuleAction: TransferHostModuleTask, + cloudprovider.RemoveDataFromCmdbAction: RemoveDataFromCMDBTask, cloudprovider.RemoveHostFromCmdbAction: RemoveHostFromCMDBTask, cloudprovider.JobFastExecuteScriptAction: JobExecuteScriptTask, cloudprovider.EnsureAutoScalerAction: EnsureAutoScalerTask, diff --git a/bcs-services/bcs-cluster-manager/internal/cloudprovider/google/taskmgr.go b/bcs-services/bcs-cluster-manager/internal/cloudprovider/google/taskmgr.go index 81288923a9..39bbf2a7d8 100644 --- a/bcs-services/bcs-cluster-manager/internal/cloudprovider/google/taskmgr.go +++ b/bcs-services/bcs-cluster-manager/internal/cloudprovider/google/taskmgr.go @@ -526,7 +526,10 @@ func (t *Task) BuildCleanNodesInGroupTask(nodes []*proto.Node, group *proto.Node // step3: check cluster delete nodes common.BuildCheckClusterCleanNodesTaskStep(task, group.Provider, opt.Cluster.ClusterID, nodeIDs) - // step5: remove host from cmdb + // step5: remove data from cmdb + common.BuildRemoveCmdbDataStep(task, opt.Cluster.BusinessID, opt.Cluster.ClusterID, nodeIDs) + + // step6: remove host from cmdb common.BuildRemoveHostStep(task, opt.Cluster.BusinessID, nodeIPs) // set current step diff --git a/bcs-services/bcs-cluster-manager/internal/cloudprovider/utils.go b/bcs-services/bcs-cluster-manager/internal/cloudprovider/utils.go index 8e86a963f1..b473e0674a 100644 --- a/bcs-services/bcs-cluster-manager/internal/cloudprovider/utils.go +++ b/bcs-services/bcs-cluster-manager/internal/cloudprovider/utils.go @@ -57,6 +57,8 @@ const ( WatchTask = "watchjob" // InstallImagePullSecretAddonAction imagePull component common job InstallImagePullSecretAddonAction = "installImagePullSecret" + // RemoveDataFromCmdbAction remove cmdb data action + RemoveDataFromCmdbAction = "removeDataFromCmdb" // RemoveHostFromCmdbAction remove host action RemoveHostFromCmdbAction = "removeHostFromCmdb" // CheckNodeIpsInCmdbAction check node if in cmdb @@ -106,7 +108,7 @@ const ( // NodeDrainPodAction 节点驱逐pod NodeDrainPodAction = "nodeDrainPod" // InstallLogCollectorAddonAction 安装日志采集组件 - InstallLogCollectorAddonAction = "installLogCollectorAddon" + InstallLogCollectorAddonAction = "installLogCollectorAddon" // nolint ) var ( diff --git a/bcs-services/bcs-cluster-manager/internal/remote/cmdb/client.go b/bcs-services/bcs-cluster-manager/internal/remote/cmdb/client.go index ea9c6f62e1..4ca389721b 100644 --- a/bcs-services/bcs-cluster-manager/internal/remote/cmdb/client.go +++ b/bcs-services/bcs-cluster-manager/internal/remote/cmdb/client.go @@ -1147,3 +1147,336 @@ func (c *Client) SyncHostInfoFromCmpy(bkCloudId int, bkHostIds []int64) error { return nil } + +// GetBcsPod get pod +func (c *Client) GetBcsPod(req *GetBcsPodReq) (*[]Pod, error) { + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/findmany/kube/pod", c.server) + respData := &GetBcsPodResp{} + + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Post(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + if len(errs) > 0 { + blog.Errorf("call api list_pod failed: %v", errs[0]) + return nil, errs[0] + } + + if !respData.Result { + blog.Errorf("call api list_pod failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return nil, fmt.Errorf(respData.Message) + } + + blog.Infof("call api list_pod with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return respData.Data.Info, nil +} + +// DeleteBcsPod delete pod +func (c *Client) DeleteBcsPod(req *DeleteBcsPodReq) error { + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/deletemany/kube/pod", c.server) + respData := &DeleteBcsPodResp{} + + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Delete(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + if len(errs) > 0 { + blog.Errorf("call api batch_delete_kube_pod failed: %v", errs[0]) + return errs[0] + } + + if !respData.Result { + blog.Errorf("call api batch_delete_kube_pod failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return fmt.Errorf(respData.Message) + } + + blog.Infof("call api batch_delete_kube_pod with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return nil +} + +// GetBcsWorkload get workload +func (c *Client) GetBcsWorkload(req *GetBcsWorkloadReq) (*[]interface{}, error) { + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/findmany/kube/workload/%s", c.server, req.Kind) + respData := &GetBcsWorkloadResp{} + + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Post(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + if len(errs) > 0 { + blog.Errorf("call api list_workload failed: %v, rid: %s", errs[0], respData.RequestID) + return nil, errs[0] + } + + if !respData.Result { + blog.Errorf("call api list_workload failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return nil, fmt.Errorf(respData.Message) + } + + blog.Infof("call api list_workload with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return &respData.Data.Info, nil +} + +// DeleteBcsWorkload delete workload +func (c *Client) DeleteBcsWorkload(req *DeleteBcsWorkloadReq) error { + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/deletemany/kube/workload/%s", c.server, *req.Kind) + respData := &DeleteBcsWorkloadResp{} + + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Delete(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + if len(errs) > 0 { + blog.Errorf("call api batch_delete_workload failed: %v", errs[0]) + return errs[0] + } + + if !respData.Result { + blog.Errorf( + "call api batch_delete_workload failed: %v, rid: %s, request: bkbizid: %d, kind: %s, ids: %v", + respData.Message, resp.Header.Get("X-Request-Id"), *req.BKBizID, *req.Kind, *req.IDs) + return fmt.Errorf(respData.Message) + } + + blog.Infof("call api batch_delete_workload with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return nil +} + +// GetBcsNamespace get namespace +func (c *Client) GetBcsNamespace(req *GetBcsNamespaceReq) (*[]Namespace, error) { + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/findmany/kube/namespace", c.server) + respData := &GetBcsNamespaceResp{} + + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Post(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + if len(errs) > 0 { + blog.Errorf("call api list_namespace failed: %v", errs[0]) + return nil, errs[0] + } + + if !respData.Result { + blog.Errorf("call api list_namespace failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return nil, fmt.Errorf(respData.Message) + } + + blog.Infof("call api list_namespace with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return respData.Data.Info, nil +} + +// DeleteBcsNamespace delete namespace +func (c *Client) DeleteBcsNamespace(req *DeleteBcsNamespaceReq) error { + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/deletemany/kube/namespace", c.server) + respData := &DeleteBcsNamespaceResp{} + + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Delete(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + if len(errs) > 0 { + blog.Errorf("call api batch_delete_namespace failed: %v", errs[0]) + return errs[0] + } + + if !respData.Result { + blog.Errorf("call api batch_delete_namespace failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return fmt.Errorf(respData.Message) + } + + blog.Infof("call api batch_delete_namespace with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return nil +} + +// GetBcsNode get node +func (c *Client) GetBcsNode(req *GetBcsNodeReq) (*[]Node, error) { + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/findmany/kube/node", c.server) + respData := &GetBcsNodeResp{} + + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Post(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + if len(errs) > 0 { + blog.Errorf("call api list_kube_node failed: %v", errs[0]) + return nil, errs[0] + } + + if !respData.Result { + blog.Errorf("call api list_kube_node failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return nil, fmt.Errorf(respData.Message) + } + + blog.Infof("call api list_kube_node with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return respData.Data.Info, nil +} + +// DeleteBcsNode delete node +func (c *Client) DeleteBcsNode(req *DeleteBcsNodeReq) error { + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/deletemany/kube/node", c.server) + respData := &DeleteBcsNodeResp{} + + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Delete(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + if len(errs) > 0 { + blog.Errorf("call api batch_delete_kube_node failed: %v", errs[0]) + return errs[0] + } + + if !respData.Result { + blog.Errorf("call api batch_delete_kube_node failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return fmt.Errorf(respData.Message) + } + + blog.Infof("call api batch_delete_kube_node with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return nil +} + +// GetBcsCluster get cluster +func (c *Client) GetBcsCluster(req *GetBcsClusterReq) (*[]Cluster, error) { + // 如果没有通过数据库查询,则通过API调用获取集群信息 + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/findmany/kube/cluster", c.server) + respData := &GetBcsClusterResp{} + // 使用gorequest库发送POST请求,并处理响应 + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Post(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + // 检查是否有错误发生 + if len(errs) > 0 { + blog.Errorf("call api list_kube_cluster failed: %v", errs[0]) + return nil, errs[0] + } + + // 检查API响应是否成功 + if !respData.Result { + blog.Errorf("call api list_kube_cluster failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return nil, fmt.Errorf(respData.Message) + } + + blog.Infof("call api list_kube_cluster with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return &respData.Data.Info, nil +} + +// DeleteBcsCluster delete bcs cluster +func (c *Client) DeleteBcsCluster(req *DeleteBcsClusterReq) error { + // 构造请求的 URL + reqURL := fmt.Sprintf("%s/api/bk-cmdb/prod/api/v3/delete/kube/cluster", c.server) + // 初始化响应数据结构 + respData := &DeleteBcsClusterResp{} + + // 使用 gorequest 库发送 HTTP DELETE 请求 + // 设置请求超时时间、内容类型、接受类型、授权头等信息 + // 发送请求体并尝试重试,最多重试3次,每次间隔3秒,如果遇到429状态码也会重试 + resp, _, errs := gorequest.New(). + Timeout(defaultTimeOut). + Delete(reqURL). + Set("Content-Type", "application/json"). + Set("Accept", "application/json"). + Set("X-Bkapi-Authorization", c.userAuth). + SetDebug(c.serverDebug). + Send(req). + Retry(3, 3*time.Second, 429). + EndStruct(&respData) + + // 如果请求过程中出现错误,则记录错误并返回 + if len(errs) > 0 { + blog.Errorf("call api batch_delete_kube_cluster failed: %v", errs[0]) + return errs[0] + } + + // 如果响应结果指示操作失败,则记录错误信息并返回错误 + if !respData.Result { + blog.Errorf("call api batch_delete_kube_cluster failed: %v, rid: %s", + respData.Message, resp.Header.Get("X-Request-Id")) + return fmt.Errorf(respData.Message) + } + + // 如果操作成功,则记录成功的日志信息 + blog.Infof("call api batch_delete_kube_cluster with url(%s) (%v) successfully, X-Request-Id: %s", + reqURL, req, resp.Header.Get("X-Request-Id")) + + return nil +} diff --git a/bcs-services/bcs-cluster-manager/internal/remote/cmdb/types.go b/bcs-services/bcs-cluster-manager/internal/remote/cmdb/types.go index e3b9c03ccf..2e58252ce6 100644 --- a/bcs-services/bcs-cluster-manager/internal/remote/cmdb/types.go +++ b/bcs-services/bcs-cluster-manager/internal/remote/cmdb/types.go @@ -518,3 +518,249 @@ type SyncHostInfoFromCmpyReq struct { type SyncHostInfoFromCmpyResp struct { BaseResponse } + +// GetBcsPodReq defines the structure of the request for getting BCS pods. +type GetBcsPodReq struct { + BKBizID int64 `json:"bk_biz_id"` + Page Page `json:"page"` + Fields []string `json:"fields"` + Filter *HostPropertyFilter `json:"filter"` +} + +// GetBcsPodResp defines the structure of the response for getting BCS pods. +type GetBcsPodResp struct { + BaseResponse + Data *GetBcsPodRespData `json:"data"` +} + +// GetBcsPodRespData defines the structure of the response data for getting BCS pods. +type GetBcsPodRespData struct { + Count int `json:"count"` + Info *[]Pod `json:"info"` +} + +// Pod pod details +type Pod struct { + // cc的自增主键 + ID int64 `json:"id"` + Name *string `json:"name"` + Priority *int32 `json:"priority"` + Labels *map[string]string `json:"labels"` + IP *string `json:"ip"` + NodeSelectors *map[string]string `json:"node_selectors"` + Operator *[]string `json:"operator"` +} + +// DeleteBcsPodReq defines the request structure for deleting a BCS pod. +type DeleteBcsPodReq struct { + Data *[]DeleteBcsPodReqData `json:"data"` +} + +// DeleteBcsPodReqData defines the data structure in the DeleteBcsPodRequest. +type DeleteBcsPodReqData struct { + BKBizID *int64 `json:"bk_biz_id"` + IDs *[]int64 `json:"ids"` +} + +// DeleteBcsPodResp defines the response structure for deleting a BCS pod. +type DeleteBcsPodResp struct { + BaseResponse + Data interface{} `json:"data"` +} + +// GetBcsWorkloadReq represents a request for getting BCS workload +type GetBcsWorkloadReq struct { + BKBizID int64 `json:"bk_biz_id"` + Page Page `json:"page"` + Fields []string `json:"fields"` + Filter *HostPropertyFilter `json:"filter"` + Kind string `json:"kind"` +} + +// GetBcsWorkloadResp represents a response for getting BCS workload +type GetBcsWorkloadResp struct { + BaseResponse + Data *GetBcsWorkloadRespData `json:"data"` +} + +// GetBcsWorkloadRespData represents the data structure of the response for getting BCS workload +type GetBcsWorkloadRespData struct { + Count int64 `json:"count"` + Info []interface{} `json:"info"` +} + +// DeleteBcsWorkloadReq defines the structure of the request for deleting a BCS workload. +type DeleteBcsWorkloadReq struct { + BKBizID *int64 `json:"bk_biz_id"` + Kind *string `json:"kind"` + IDs *[]int64 `json:"ids"` +} + +// DeleteBcsWorkloadResp defines the structure of the response for deleting a BCS workload. +type DeleteBcsWorkloadResp struct { + BaseResponse + Data interface{} `json:"data"` +} + +// GetBcsNamespaceReq represents the request for getting a BCS namespace +type GetBcsNamespaceReq struct { + BKBizID int64 `json:"bk_biz_id"` + Page Page `json:"page"` + Fields []string `json:"fields"` + Filter *HostPropertyFilter `json:"filter"` +} + +// Namespace define the namespace struct. +type Namespace struct { + ID int64 `json:"id"` + Name string `json:"name"` + Labels *map[string]string `json:"labels"` + SupplierAccount string `json:"bk_supplier_account"` +} + +// GetBcsNamespaceResp represents the response for getting a BCS namespace +type GetBcsNamespaceResp struct { + BaseResponse + Data *GetBcsNamespaceRespData `json:"data"` +} + +// GetBcsNamespaceRespData represents the data for getting a BCS namespace +type GetBcsNamespaceRespData struct { + Count int64 `json:"count"` + Info *[]Namespace `json:"info"` +} + +// DeleteBcsNamespaceReq represents the request for deleting a BCS namespace +type DeleteBcsNamespaceReq struct { + BKBizID *int64 `json:"bk_biz_id"` + IDs *[]int64 `json:"ids"` +} + +// DeleteBcsNamespaceResp represents the response for deleting a BCS namespace +type DeleteBcsNamespaceResp struct { + BaseResponse + Data interface{} `json:"data"` +} + +// GetBcsNodeReq defines the structure of the request for getting BCS nodes. +type GetBcsNodeReq struct { + BKBizID int64 `json:"bk_biz_id"` + Page Page `json:"page"` + Fields []string `json:"fields"` + Filter *HostPropertyFilter `json:"filter"` +} + +// Node node structural description. +type Node struct { + // ID cluster auto-increment ID in cc + ID int64 `json:"id,omitempty" bson:"id"` + // BizID the business ID to which the cluster belongs + BizID int64 `json:"bk_biz_id,omitempty" bson:"bk_biz_id"` + // SupplierAccount the supplier account that this resource belongs to. + SupplierAccount string `json:"bk_supplier_account,omitempty" bson:"bk_supplier_account"` + // HostID the node ID to which the host belongs + HostID int64 `json:"bk_host_id,omitempty" bson:"bk_host_id"` + // ClusterID the node ID to which the cluster belongs + ClusterID int64 `json:"bk_cluster_id,omitempty" bson:"bk_cluster_id"` + // ClusterUID the node ID to which the cluster belongs + ClusterUID string `json:"cluster_uid,omitempty" bson:"cluster_uid"` + // HasPod this field indicates whether there is a pod in the node. + // if there is a pod, this field is true. If there is no pod, this + // field is false. this field is false when node is created by default. + HasPod *bool `json:"has_pod,omitempty" bson:"has_pod"` + Name *string `json:"name,omitempty" bson:"name"` + Roles *string `json:"roles,omitempty" bson:"roles"` + Unschedulable *bool `json:"unschedulable,omitempty" bson:"unschedulable"` + InternalIP *[]string `json:"internal_ip,omitempty" bson:"internal_ip"` + ExternalIP *[]string `json:"external_ip,omitempty" bson:"external_ip"` + HostName *string `json:"hostname,omitempty" bson:"hostname"` + RuntimeComponent *string `json:"runtime_component,omitempty" bson:"runtime_component"` + KubeProxyMode *string `json:"kube_proxy_mode,omitempty" bson:"kube_proxy_mode"` + PodCidr *string `json:"pod_cidr,omitempty" bson:"pod_cidr"` +} + +// GetBcsNodeResp defines the structure of the response for getting BCS nodes. +type GetBcsNodeResp struct { + BaseResponse + Data *GetBcsNodeRespData `json:"data"` +} + +// GetBcsNodeRespData defines the structure of the response data for getting BCS nodes. +type GetBcsNodeRespData struct { + Count int64 `json:"count"` + Info *[]Node `json:"info"` +} + +// DeleteBcsNodeReq defines the structure of the request for deleting BCS nodes. +type DeleteBcsNodeReq struct { + BKBizID *int64 `json:"bk_biz_id"` + IDs *[]int64 `json:"ids"` +} + +// DeleteBcsNodeResp defines the structure of the response for deleting BCS nodes. +type DeleteBcsNodeResp struct { + BaseResponse + Data interface{} `json:"data"` +} + +// GetBcsClusterReq defines the request structure for getting BCS cluster information. +type GetBcsClusterReq struct { + BKBizID int64 `json:"bk_biz_id"` + Page Page `json:"page"` + Fields []string `json:"fields"` + Filter *HostPropertyFilter `json:"filter"` +} + +// Cluster container cluster table structure +type Cluster struct { + // ID cluster auto-increment ID in cc + ID int64 `json:"id" bson:"id"` + // BizID the business ID to which the cluster belongs + BizID int64 `json:"bk_biz_id" bson:"bk_biz_id"` + // SupplierAccount the supplier account that this resource belongs to. + SupplierAccount string `json:"bk_supplier_account" bson:"bk_supplier_account"` + // Name cluster name. + Name *string `json:"name,omitempty" bson:"name"` + // SchedulingEngine scheduling engines, such as k8s, tke, etc. + SchedulingEngine *string `json:"scheduling_engine,omitempty" bson:"scheduling_engine"` + // Uid ID of the cluster itself + Uid *string `json:"uid,omitempty" bson:"uid"` + // Xid The underlying cluster ID it depends on + Xid *string `json:"xid,omitempty" bson:"xid"` + // Version cluster version + Version *string `json:"version,omitempty" bson:"version"` + // NetworkType network type, such as overlay or underlay + NetworkType *string `json:"network_type,omitempty" bson:"network_type"` + // Region the region where the cluster is located + Region *string `json:"region,omitempty" bson:"region"` + // Vpc vpc network + Vpc *string `json:"vpc,omitempty" bson:"vpc"` + // Environment cluster environment + Environment *string `json:"environment,omitempty" bson:"environment"` + // NetWork global routing network address (container overlay network) For example: ["1.1.1.0/21"] + NetWork *[]string `json:"network,omitempty" bson:"network"` +} + +// GetBcsClusterResp defines the response structure for getting BCS cluster information. +type GetBcsClusterResp struct { + BaseResponse + Data GetBcsClusterRespData `json:"data"` +} + +// GetBcsClusterRespData defines the data structure for getting BCS cluster information. +type GetBcsClusterRespData struct { + Count int64 `json:"count"` + Info []Cluster `json:"info"` +} + +// DeleteBcsClusterReq represents the request for deleting a BCS cluster +type DeleteBcsClusterReq struct { + BKBizID *int64 `json:"bk_biz_id"` + IDs *[]int64 `json:"ids"` +} + +// DeleteBcsClusterResp represents the response for deleting a BCS cluster +type DeleteBcsClusterResp struct { + BaseResponse + Data interface{} `json:"data"` +} diff --git a/bcs-services/bcs-cluster-manager/internal/remote/log/bklog/bk_log.go b/bcs-services/bcs-cluster-manager/internal/remote/log/bklog/bk_log.go index c8ad4b4522..afb48f0c31 100644 --- a/bcs-services/bcs-cluster-manager/internal/remote/log/bklog/bk_log.go +++ b/bcs-services/bcs-cluster-manager/internal/remote/log/bklog/bk_log.go @@ -80,7 +80,7 @@ func EnableMonitorAudit(projectID, clusterID string) error { // nolint if err := json.Unmarshal([]byte(body), respData); err != nil { metrics.ReportLibRequestMetric("bklog", "EnableMonitorAudit", "http", metrics.LibCallStatusErr, start) - errMsg := fmt.Errorf("parse EnableMonitorAudit response failed: %v, raw body: %s", err, string(body)) + errMsg := fmt.Errorf("parse EnableMonitorAudit response failed: %v, raw body: %s", err, body) blog.Errorf("EnableMonitorAudit failed: %v", errMsg) return errMsg }