From 55fe1d534db30c8262a5ea0a458147f1fc1a0b54 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Thu, 12 Oct 2023 09:49:34 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E8=AE=B8=E5=8F=AF=E8=AF=81=E5=92=8C?= =?UTF-8?q?=E7=BD=91=E5=85=83=E5=BC=80=E5=85=B3=E6=9C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/cm/license.go | 198 ++++++++++++++++++++++++++++++++++++++-- features/cm/ne.go | 4 +- features/cm/software.go | 2 +- lib/dborm/dborm.go | 17 +++- lib/routes/routes.go | 14 +-- 5 files changed, 211 insertions(+), 24 deletions(-) diff --git a/features/cm/license.go b/features/cm/license.go index e691a90..ad2cf1e 100644 --- a/features/cm/license.go +++ b/features/cm/license.go @@ -1,8 +1,14 @@ package cm import ( + "fmt" + "io" "net/http" + "os" + "os/exec" + "strings" + "ems.agt/lib/dborm" "ems.agt/lib/log" "ems.agt/lib/services" "ems.agt/restagent/config" @@ -11,12 +17,12 @@ import ( ) var ( - // License - LicenseUri = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/{neType}/license" - NeLicenseUri = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/{neType}/license/{neId}" + // General License URI + UriLicense = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/{elementTypeValue}/license" + UriLicenseExt = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/license" - CustomLicenseUri = config.UriPrefix + "/systemManagement/{apiVersion}/{neType}/license" - CustomNeLicenseUri = config.UriPrefix + "/systemManagement/{apiVersion}/{neType}/license/{neId}" + CustomUriLicense = config.UriPrefix + "/systemManagement/{apiVersion}/{elementTypeValue}/license" + CustomUriLicenseExt = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/license" ) func UploadLicenseFile(w http.ResponseWriter, r *http.Request) { @@ -39,7 +45,6 @@ func UploadLicenseFile(w http.ResponseWriter, r *http.Request) { // neTypeLower := strings.ToLower(neType) services.ResponseStatusOK204NoContent(w) - return } func DownloadLicenseFile(w http.ResponseWriter, r *http.Request) { @@ -86,7 +91,6 @@ func DownloadLicenseFile(w http.ResponseWriter, r *http.Request) { // md5Sum := (*neSoftware)[0]["md5_sum"] // services.ResponseFileWithNameAndMD5(w, http.StatusOK, fileName, path, md5Sum) - return } func DeleteLcenseFile(w http.ResponseWriter, r *http.Request) { @@ -147,5 +151,183 @@ func DeleteLcenseFile(w http.ResponseWriter, r *http.Request) { // } services.ResponseStatusOK204NoContent(w) - return +} + +func UploadLicenseFileData(w http.ResponseWriter, r *http.Request) { + log.Info("UploadLicenseFileData processing... ") + + _, err := services.CheckFrontValidRequest(w, r) + if err != nil { + log.Error("Http request error:", err) + return + } + + vars := mux.Vars(r) + neType := vars["elementTypeValue"] + if neType == "" { + log.Error("elementTypeValue is empty") + services.ResponseNotFound404UriNotExist(w, r) + return + } + neTypeUpper := strings.ToUpper(neType) + neTypeLower := strings.ToLower(neType) + + //md5Param := services.GetUriParamString(r, "md5Sum", ",", false, false) + + neId := services.GetUriParamString(r, "neId", ",", false, false) + + neInfo, err := dborm.XormGetNeInfo(neType, neId) + if err != nil { + log.Errorf("Failed to get ne_info:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + log.Debug("neInfo:", neInfo) + + licensePath := fmt.Sprintf("%s/%s", config.GetYamlConfig().OMC.License, neTypeLower) + err = os.MkdirAll(licensePath, os.ModePerm) + if err != nil { + log.Error("Failed to Mkdir:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + //fileName, err := services.HandleUploadFile(r, softwarePath, "") + + // 解析multipart/form-data请求 + err = r.ParseMultipartForm(10 << 20) // 10MB + if err != nil { + log.Error("Faile to ParseMultipartForm:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + + // 获取文件和数据 + licFile := r.MultipartForm.File["file"] + data := r.MultipartForm.Value["comment"] + + var licenseFileName, comment string + + // 处理软件rpm/deb文件 + if len(licFile) > 0 { + file := licFile[0] + // 打开文件 + f, err := file.Open() + if err != nil { + log.Error("Faile to Open:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + defer f.Close() + + // 创建本地文件 + dst, err := os.Create(licensePath + "/" + file.Filename) + if err != nil { + log.Error("Faile to Create:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + defer dst.Close() + + licenseFileName = file.Filename + // 将文件内容拷贝到本地文件 + _, err = io.Copy(dst, f) + if err != nil { + log.Error("Faile to Copy:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + } + + // 处理数据 + if len(data) > 0 { + comment = data[0] + } + + neLicensePath := strings.ReplaceAll(config.GetYamlConfig().NE.LicenseDir, "{neType}", neTypeLower) + + srcFile := fmt.Sprintf("%s/%s", licensePath, licenseFileName) + scpDir := fmt.Sprintf("%s@%s:%s", config.GetYamlConfig().NE.User, neInfo.Ip, config.GetYamlConfig().NE.ScpDir) + cmd := exec.Command("scp", "-r", srcFile, scpDir) + out, err := cmd.CombinedOutput() + log.Debugf("Exec output: %v", string(out)) + if err != nil { + log.Errorf("Faile to scp NF: neType=%s, neId=%s, ip=%s", neType, neId, neInfo.Ip) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + // backup system.ini to system.ini.bak + sshHost := fmt.Sprintf("%s@%s", config.GetYamlConfig().NE.User, neInfo.Ip) + cpCmd := fmt.Sprintf("sudo cp -f %s/system.ini %s/system.ini.bak", neLicensePath, neLicensePath) + cmd = exec.Command("ssh", sshHost, cpCmd) + out, err = cmd.CombinedOutput() + log.Debugf("Exec output: %v", string(out)) + if err != nil { + log.Error("Faile to execute cp command:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + + // replace system.ini + neFilePath := config.GetYamlConfig().NE.ScpDir + "/" + licenseFileName + cpCmd = fmt.Sprintf("sudo mv -f %s %s/system.ini", neFilePath, neLicensePath) + cmd = exec.Command("ssh", sshHost, cpCmd) + out, err = cmd.CombinedOutput() + log.Debugf("Exec output: %v", string(out)) + if err != nil { + log.Error("Faile to execute cp command:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + + switch neTypeLower { + case "omc": + restartCmd := fmt.Sprintf("sudo %s/bin/omcsvc.sh restart", config.GetYamlConfig().NE.OmcDir) + cmd := exec.Command("ssh", sshHost, restartCmd) + out, err := cmd.CombinedOutput() + log.Debugf("Exec output: %v", string(out)) + if err != nil { + log.Error("Faile to execute ssh restart omc:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + case "ims": + restartCmd := "sudo ims-stop && sudo ims-start" + cmd := exec.Command("ssh", sshHost, restartCmd) + out, err := cmd.CombinedOutput() + log.Debugf("Exec output: %v", string(out)) + if err != nil { + log.Error("Faile to execute ssh sudo systemctl command:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + default: + restartCmd := fmt.Sprintf("sudo systemctl restart %s.service", neTypeLower) + cmd := exec.Command("ssh", sshHost, restartCmd) + out, err := cmd.CombinedOutput() + log.Debugf("Exec output: %v", string(out)) + if err != nil { + log.Error("Faile to execute ssh sudo systemctl command:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + } + + neLicense := dborm.NeLicense{ + NeType: neTypeUpper, + NeID: neId, + Status: "ACTIVE", + Path: licensePath, + FileName: licenseFileName, + Comment: comment, + } + + log.Debug("neLicense:", neLicense) + _, err = dborm.XormInsertTableOne("ne_license", neLicense) + if err != nil { + log.Error("Faile to XormInsertTableOne:", err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + + services.ResponseStatusOK204NoContent(w) } diff --git a/features/cm/ne.go b/features/cm/ne.go index 3ecf8eb..22c6586 100644 --- a/features/cm/ne.go +++ b/features/cm/ne.go @@ -766,7 +766,7 @@ func PostNeServiceAction(w http.ResponseWriter, r *http.Request) { neTypeLower := strings.ToLower(neType) action := vars["action"] - neId := services.GetUriParamString(r, "ne_id", ",", false, false) + neId := services.GetUriParamString(r, "neId", ",", false, false) // neInfo := new(dborm.NeInfo) neInfo, err := dborm.XormGetNeInfo(neType, neId) @@ -852,7 +852,7 @@ func PostNeInstanceAction(w http.ResponseWriter, r *http.Request) { //neTypeLower := strings.ToLower(neType) action := vars["action"] - neId := services.GetUriParamString(r, "ne_id", ",", false, false) + neId := services.GetUriParamString(r, "neId", ",", false, false) // neInfo := new(dborm.NeInfo) neInfo, err := dborm.XormGetNeInfo(neType, neId) diff --git a/features/cm/software.go b/features/cm/software.go index d65ff53..d264b9c 100644 --- a/features/cm/software.go +++ b/features/cm/software.go @@ -564,7 +564,7 @@ func DistributeSoftwareToNF(w http.ResponseWriter, r *http.Request) { return } neFilePath := config.GetYamlConfig().NE.ScpDir + "/" + fileName - cpCmd := fmt.Sprintf("sudo cp -f %s %s/software/%s", neFilePath, + cpCmd := fmt.Sprintf("sudo mv -f %s %s/software/%s", neFilePath, config.GetYamlConfig().NE.OmcDir, neTypeLower) cmd = exec.Command("ssh", sshHost, cpCmd) out, err = cmd.CombinedOutput() diff --git a/lib/dborm/dborm.go b/lib/dborm/dborm.go index 58f4356..4c132a7 100644 --- a/lib/dborm/dborm.go +++ b/lib/dborm/dborm.go @@ -1630,9 +1630,20 @@ func IsPermissionAllowed(token, method, module, dbname, tbname, pack string) (bo } type NeLicense struct { - NeType string `json:"neType" xorm:"ne_type"` - NeID string `json:"neID" xorm:"ne_id"` - Capability int `json:"capability"` + NeType string `json:"neType" xorm:"ne_type"` + NeID string `json:"neID" xorm:"ne_id"` + SerialNo string `json:"serialNo" xorm:"serial_no"` + Capcity int `json:"capcity" xorm:"capcity"` + Used int `json:"used" xorm:"used"` + FeatureEnabled string `json:"featureEnabled" xorm:"feature_enabled"` + ExpirationDate string `json:"expirationDate" xorm:"expiration_date"` + Status string `json:"status" xorm:"status"` + Path string `json:"path" xorm:"path"` + FileName string `json:"file_name" xorm:"file_name"` + Comment string `json:"comment" xorm:"comment"` + CreatedAt string `json:"createdAt" xorm:"-"` + UpdatedAt string `json:"updatedAt" xorm:"-"` + DeletedAt string `json:"deletedAt" xorm:"-"` } func XormAdjustmentNeLicense(neType, neID string, value int) (int64, error) { diff --git a/lib/routes/routes.go b/lib/routes/routes.go index d371e5b..b0e187e 100644 --- a/lib/routes/routes.go +++ b/lib/routes/routes.go @@ -220,17 +220,11 @@ func init() { Register("PATCH", cm.CustomUriSoftwareNE, cm.RollBackSoftwareToNF, nil) // License management - Register("GET", cm.LicenseUri, cm.ExportCmFromNF, nil) - Register("POST", cm.LicenseUri, cm.ImportCmToNF, nil) - Register("DELETE", cm.LicenseUri, cm.ImportCmToNF, nil) + Register("POST", cm.UriLicense, cm.UploadLicenseFileData, nil) + Register("POST", cm.UriLicenseExt, cm.UploadLicenseFileData, nil) - Register("POST", cm.NeLicenseUri, cm.ExportCmFromNF, nil) - Register("PUT", cm.NeLicenseUri, cm.ImportCmToNF, nil) - Register("PATCH", cm.NeLicenseUri, cm.ImportCmToNF, nil) - - Register("POST", cm.CustomNeLicenseUri, cm.ExportCmFromNF, nil) - Register("PUT", cm.CustomNeLicenseUri, cm.ImportCmToNF, nil) - Register("PATCH", cm.CustomNeLicenseUri, cm.ImportCmToNF, nil) + Register("POST", cm.CustomUriLicense, cm.UploadLicenseFileData, nil) + Register("POST", cm.CustomUriLicenseExt, cm.UploadLicenseFileData, nil) // Trace management Register("POST", trace.UriTraceTask, trace.PostTraceTaskToNF, nil)