From e713da1627d2ab60807e1c70de08ecc5da2e8c89 Mon Sep 17 00:00:00 2001 From: wubijie Date: Tue, 26 Nov 2024 17:24:29 +0800 Subject: [PATCH] Implement the interface of path_config --- configmanage/server/internal/pathfile.go | 16 ++ configmanage/server/service/path.go | 204 +++++++++++++++++++++++ configmanage/server/service/path_test.go | 11 ++ 3 files changed, 231 insertions(+) diff --git a/configmanage/server/internal/pathfile.go b/configmanage/server/internal/pathfile.go index af71fff7..3f7d2cab 100644 --- a/configmanage/server/internal/pathfile.go +++ b/configmanage/server/internal/pathfile.go @@ -61,6 +61,22 @@ func GetPathFileByInfoUUID(uuid string, isindex interface{}) (PathFile, error) { return file, err } +func GetPathFileByUUID(uuid string) (PathFile, error) { + var file PathFile + err := db.MySQL().Model(&PathFile{}).Where("uuid=?", uuid).Find(&file).Error + return file, err +} + +func (pf *PathFile) UpdateByuuid() error { + // 将同类配置的所有标志修改为未使用 + err := db.MySQL().Model(&PathFile{}).Where("config_info_uuid=?", pf.ConfigInfoUUID).Update("is_index", 0).Error + if err != nil { + return err + } + // 将成功下发的具体某一个配置状态修改为已使用 + return db.MySQL().Model(&PathFile{}).Where("uuid=?", pf.UUID).Update("is_index", 1).Error +} + // 根据配置uuid获取所有配置文件 func GetPathFilesByConfigUUID(uuid string) ([]PathFile, error) { var files []PathFile diff --git a/configmanage/server/service/path.go b/configmanage/server/service/path.go index 94ea93ed..7fef6d8e 100644 --- a/configmanage/server/service/path.go +++ b/configmanage/server/service/path.go @@ -2,9 +2,18 @@ package service import ( "encoding/json" + "errors" "fmt" + "net/http" + "strconv" "time" + "gitee.com/openeuler/PilotGo/sdk/common" + "gitee.com/openeuler/PilotGo/sdk/logger" + "gitee.com/openeuler/PilotGo/sdk/plugin/client" + "gitee.com/openeuler/PilotGo/sdk/utils/httputils" + "github.com/google/uuid" + "openeuler.org/PilotGo/configmanage-plugin/global" "openeuler.org/PilotGo/configmanage-plugin/internal" ) @@ -74,6 +83,201 @@ func (pc *PathConfig) Load() error { return nil } +func (pc *PathConfig) Apply() ([]NodeResult, error) { + //从数据库获取下发的信息 + pf, err := internal.GetPathFileByUUID(pc.UUID) + if err != nil { + return nil, err + } + if pf.ConfigInfoUUID != pc.ConfigInfoUUID || pf.UUID != pc.UUID { + return nil, errors.New("数据库不存在此配置") + } + + batchids, err := internal.GetConfigBatchByUUID(pc.ConfigInfoUUID) + if err != nil { + return nil, err + } + departids, err := internal.GetConfigDepartByUUID(pc.ConfigInfoUUID) + if err != nil { + return nil, err + } + nodes, err := internal.GetConfigNodesByUUID(pc.ConfigInfoUUID) + if err != nil { + return nil, err + } + + //从pc中解析下发的文件内容,逐一进行下发 + pathfile := common.File{} + err = json.Unmarshal([]byte(pf.Content), &pathfile) + if err != nil { + return nil, err + } + results := []NodeResult{} + de := Deploy{ + DeployBatch: common.Batch{ + BatchIds: batchids, + DepartmentIDs: departids, + MachineUUIDs: nodes, + }, + DeployPath: pathfile.Path, + DeployFileName: pathfile.Name, + DeployText: pathfile.Content, + } + url := "http://" + client.GetClient().Server() + "/api/v1/pluginapi/file_deploy" + r, err := httputils.Post(url, &httputils.Params{ + Body: de, + }) + if err != nil { + return nil, err + } + if r.StatusCode != http.StatusOK { + return nil, errors.New("server process error:" + strconv.Itoa(r.StatusCode)) + } + + resp := &common.CommonResult{} + if err := json.Unmarshal(r.Body, resp); err != nil { + return nil, err + } + if resp.Code != http.StatusOK { + return nil, errors.New(resp.Message) + } + + data := []common.NodeResult{} + if err := resp.ParseData(&data); err != nil { + return nil, err + } + // 将执行失败的文件、机器信息和原因添加到结果字符串中 + for _, d := range data { + // 存储每一台机器的执行结果 + pfNode := PathFile{ + UUID: pf.UUID, + ConfigInfoUUID: pf.ConfigInfoUUID, + Path: pf.Path, + Name: pf.Name, + Content: pf.Content, + Version: pf.Version, + IsActive: true, + IsFromHost: false, + Hostuuid: d.UUID, + CreatedAt: time.Now(), + } + + // 返回执行失败的机器详情 + if d.Error != "" { + pfNode.IsActive = false + results = append(results, NodeResult{ + Type: global.PATH, + NodeUUID: d.UUID, + Detail: pathfile.Content, + Result: false, + Err: d.Error, + }) + } + err = pfNode.Add() + if err != nil { + results = append(results, NodeResult{ + Type: global.PATH, + NodeUUID: d.UUID, + Detail: "failed to collect path config to db", + Result: false, + Err: err.Error(), + }) + } + } + + // 全部下发成功直接修改数据库是否激活字段 + if results == nil { + //下发成功修改数据库应用版本 + err = pf.UpdateByuuid() + return nil, err + } + return results, errors.New("failed to apply path config") +} + +func (pc *PathConfig) Collect() ([]NodeResult, error) { + ci, err := GetConfigByUUID(pc.ConfigInfoUUID) + if err != nil { + return nil, err + } + + //发请求获取配置详情 + url := "http://" + client.GetClient().Server() + "/api/v1/pluginapi/getnodefiles" + p := struct { + DeployBatch common.Batch `json:"deploybatch"` + Path string `json:"path"` + FileName string `json:"filename"` + }{ + DeployBatch: common.Batch{ + BatchIds: ci.BatchIds, + DepartmentIDs: ci.DepartIds, + MachineUUIDs: ci.Nodes, + }, + Path: pc.Path, + FileName: pc.Name, + } + r, err := httputils.Post(url, &httputils.Params{ + Body: p, + }) + if err != nil { + return nil, err + } + if r.StatusCode != http.StatusOK { + return nil, errors.New("server process error:" + strconv.Itoa(r.StatusCode)) + } + + resp := &common.CommonResult{} + if err := json.Unmarshal(r.Body, resp); err != nil { + return nil, err + } + if resp.Code != http.StatusOK { + return nil, errors.New(resp.Message) + } + + data := []common.NodeResult{} + if err := resp.ParseData(&data); err != nil { + return nil, err + } + results := []NodeResult{} + for _, v := range data { + if v.Error == "" { + file, _ := json.Marshal(v.Data) + pf := PathFile{ + UUID: uuid.New().String(), + ConfigInfoUUID: pc.ConfigInfoUUID, + Path: pc.Path, + Name: pc.Name, + Content: file, + Version: fmt.Sprintf("v%s", time.Now().Format("2006-01-02-15-04-05")), + IsActive: true, + IsFromHost: true, + Hostuuid: v.UUID, + CreatedAt: time.Now(), + } + err = pf.Add() + if err != nil { + logger.Error("failed to add pathconfig: %s", err.Error()) + results = append(results, NodeResult{ + Type: global.PATH, + NodeUUID: v.UUID, + Detail: "failed to collect path config to db", + Result: false, + Err: err.Error()}) + } + } else { + results = append(results, NodeResult{ + Type: global.PATH, + NodeUUID: v.UUID, + Detail: "failed to collect path config:" + v.Data.(string), + Result: false, + Err: v.Error}) + } + } + if results != nil { + return results, errors.New("failed to collect path config") + } + return nil, nil +} + // 根据配置uuid获取所有配置文件 func GetPathFilesByConfigUUID(uuid string) ([]PathFile, error) { return internal.GetPathFilesByConfigUUID(uuid) diff --git a/configmanage/server/service/path_test.go b/configmanage/server/service/path_test.go index fa53b86a..515e67ee 100644 --- a/configmanage/server/service/path_test.go +++ b/configmanage/server/service/path_test.go @@ -7,6 +7,7 @@ import ( "testing" "github.com/google/uuid" + "openeuler.org/PilotGo/configmanage-plugin/internal" ) func TestPathConfig_Record(t *testing.T) { @@ -41,6 +42,16 @@ func TestPathConfig_Load(t *testing.T) { fmt.Printf("pc: %v\n", pc) } +func TestGetPathFileByUUID(t *testing.T) { + uuid := "4254b485-8e8a-427c-bed1-5da05e363657" + hf, err := internal.GetPathFileByUUID(uuid) + if err != nil { + fmt.Printf("get pathfile error: %s\n", err) + os.Exit(-1) + } + fmt.Printf("hc: %v\n", hf) +} + func TestGetPathFilesByConfigUUID(t *testing.T) { // 设置测试数据 testUUID := "158e0acf-159b-4876-83b1-fa5f3d6460b1" -- Gitee