feat: omc原始代码
This commit is contained in:
95
features/cm/exec_linux.go
Normal file
95
features/cm/exec_linux.go
Normal file
@@ -0,0 +1,95 @@
|
||||
//go:build linux
|
||||
// +build linux
|
||||
|
||||
package cm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"nms_nbi/lib/log"
|
||||
)
|
||||
|
||||
func ExecCmd(command string) error {
|
||||
log.Debug("Exec command:", command)
|
||||
|
||||
cmd := exec.Command("/bin/bash", "-c", command)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Tracef("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("exe cmd error: ", err)
|
||||
return err
|
||||
}
|
||||
/*
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.Error("Start error: ", err)
|
||||
return err
|
||||
}
|
||||
if err := cmd.Wait(); err != nil {
|
||||
log.Error("Wait error: ", err)
|
||||
return err
|
||||
}
|
||||
*/
|
||||
return nil
|
||||
}
|
||||
|
||||
func ExecShell(command string) error {
|
||||
in := bytes.NewBuffer(nil)
|
||||
cmd := exec.Command("sh")
|
||||
cmd.Stdin = in
|
||||
in.WriteString(command)
|
||||
in.WriteString("exit\n")
|
||||
if err := cmd.Start(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ExecOsCmd(command, os string) error {
|
||||
log.Debugf("Exec %s command:%s", os, command)
|
||||
|
||||
var cmd *exec.Cmd
|
||||
switch os {
|
||||
case "Linux":
|
||||
cmd = exec.Command(command)
|
||||
case "Windows":
|
||||
cmd = exec.Command("cmd", "/C", command)
|
||||
}
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Tracef("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("exe cmd error: ", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func StartSSHCmdWithTimeout(duration int, sshHost, cmdStr string) error {
|
||||
timeout := time.Duration(duration) * time.Second
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout) // 设置超时
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, "ssh", sshHost, cmdStr)
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RunSSHCmd(sshHost, cmdStr string) error {
|
||||
cmd := exec.Command("ssh", sshHost, cmdStr)
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
83
features/cm/exec_windows.go
Normal file
83
features/cm/exec_windows.go
Normal file
@@ -0,0 +1,83 @@
|
||||
//go:build windows
|
||||
// +build windows
|
||||
|
||||
package cm
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"os/exec"
|
||||
"time"
|
||||
|
||||
"nms_nbi/lib/log"
|
||||
)
|
||||
|
||||
func ExecCmd(command string) error {
|
||||
log.Debug("Exec command:", command)
|
||||
|
||||
cmd := exec.Command("cmd", "/C", command)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Tracef("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("exe cmd error: ", err)
|
||||
return err
|
||||
}
|
||||
/*
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.Error("Start error: ", err)
|
||||
return err
|
||||
}
|
||||
if err := cmd.Wait(); err != nil {
|
||||
log.Error("Wait error: ", err)
|
||||
return err
|
||||
}
|
||||
*/
|
||||
return nil
|
||||
}
|
||||
|
||||
func ExecOsCmd(command, os string) error {
|
||||
log.Debugf("Exec %s command:%s", os, command)
|
||||
|
||||
var cmd *exec.Cmd
|
||||
switch os {
|
||||
case "Linux":
|
||||
cmd = exec.Command(command)
|
||||
case "Windows":
|
||||
cmd = exec.Command("cmd", "/C", command)
|
||||
}
|
||||
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Tracef("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("exe cmd error: ", err)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func StartSSHCmdWithTimeout(duration int, sshHost, cmdStr string) error {
|
||||
timeout := time.Duration(duration) * time.Second
|
||||
ctx, cancel := context.WithTimeout(context.Background(), timeout) // 设置超时
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, "ssh", sshHost, cmdStr)
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Start()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func RunSSHCmd(sshHost, cmdStr string) error {
|
||||
cmd := exec.Command("ssh", sshHost, cmdStr)
|
||||
var stdout, stderr bytes.Buffer
|
||||
cmd.Stdout = &stdout
|
||||
cmd.Stderr = &stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
524
features/cm/license.go
Normal file
524
features/cm/license.go
Normal file
@@ -0,0 +1,524 @@
|
||||
package cm
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"nms_nbi/lib/dborm"
|
||||
"nms_nbi/lib/log"
|
||||
"nms_nbi/lib/services"
|
||||
"nms_nbi/restagent/config"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var (
|
||||
// General License URI
|
||||
UriLicense = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/{elementTypeValue}/license"
|
||||
UriLicenseExt = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/license"
|
||||
|
||||
CustomUriLicense = config.UriPrefix + "/systemManagement/{apiVersion}/{elementTypeValue}/license"
|
||||
CustomUriLicenseExt = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/license"
|
||||
)
|
||||
|
||||
func UploadLicenseFile(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("UploadLicenseFile processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Http request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["neType"]
|
||||
if neType == "" {
|
||||
log.Error("neType is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
// neTypeUpper := strings.ToUpper(neType)
|
||||
// neTypeLower := strings.ToLower(neType)
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
}
|
||||
|
||||
func DownloadLicenseFile(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("DownloadLicenseFile processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["neType"]
|
||||
if neType == "" {
|
||||
log.Error("neType is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
// // neTypeUpper := strings.ToUpper(neType)
|
||||
// //neTypeLower := strings.ToLower(neType)
|
||||
|
||||
// version := vars["version"]
|
||||
// if version == "" {
|
||||
// log.Error("version is empty")
|
||||
// services.ResponseNotFound404UriNotExist(w, r)
|
||||
// return
|
||||
// }
|
||||
|
||||
// sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version)
|
||||
// neSoftware, err := dborm.XormGetDataBySQL(sql)
|
||||
// if err != nil {
|
||||
// log.Error("Faile to XormGetDataBySQL:", err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// } else if len(*neSoftware) == 0 {
|
||||
// err := global.ErrCMNotFoundTargetSoftware
|
||||
// log.Error(err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
|
||||
// fileName := (*neSoftware)[0]["file_name"]
|
||||
// path := (*neSoftware)[0]["path"]
|
||||
// md5Sum := (*neSoftware)[0]["md5_sum"]
|
||||
|
||||
// services.ResponseFileWithNameAndMD5(w, http.StatusOK, fileName, path, md5Sum)
|
||||
}
|
||||
|
||||
func DeleteLcenseFile(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("DeleteLcenseFile processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["neType"]
|
||||
if neType == "" {
|
||||
log.Error("neType is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
// neTypeUpper := strings.ToUpper(neType)
|
||||
// //neTypeLower := strings.ToLower(neType)
|
||||
|
||||
// version := vars["version"]
|
||||
// if version == "" {
|
||||
// log.Error("version is empty")
|
||||
// services.ResponseNotFound404UriNotExist(w, r)
|
||||
// return
|
||||
// }
|
||||
|
||||
// sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version)
|
||||
// neSoftware, err := dborm.XormGetDataBySQL(sql)
|
||||
// if err != nil {
|
||||
// log.Error("Faile to XormGetDataBySQL:", err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// } else if len(*neSoftware) == 0 {
|
||||
// err := global.ErrCMNotFoundTargetSoftware
|
||||
// log.Error(err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
|
||||
// where := fmt.Sprintf("ne_type='%s' and version='%s'", neTypeUpper, version)
|
||||
// affected, err := dborm.XormDeleteDataByWhere(where, "ne_software")
|
||||
// if err != nil || affected == 0 {
|
||||
// log.Error("Faile to XormGetDataBySQL:", err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
|
||||
// fileName := (*neSoftware)[0]["file_name"]
|
||||
// path := (*neSoftware)[0]["path"]
|
||||
// filePath := fmt.Sprintf("%s/%s", path, fileName)
|
||||
// err = os.Remove(filePath)
|
||||
// if err != nil {
|
||||
// log.Error("Faile to Remove:", err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
}
|
||||
|
||||
type MMLRequest struct {
|
||||
MML []string `json:"mml"`
|
||||
}
|
||||
|
||||
var TIME_DELAY_AFTER_WRITE time.Duration = 200
|
||||
var TIME_DEAD_LINE time.Duration = 10
|
||||
|
||||
func init() {
|
||||
if config.GetYamlConfig().MML.Sleep != 0 {
|
||||
TIME_DELAY_AFTER_WRITE = time.Duration(config.GetYamlConfig().MML.Sleep)
|
||||
}
|
||||
if config.GetYamlConfig().MML.DeadLine != 0 {
|
||||
TIME_DEAD_LINE = time.Duration(config.GetYamlConfig().MML.DeadLine)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
// 处理license文件
|
||||
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
|
||||
}
|
||||
|
||||
/*
|
||||
// judge license if expired
|
||||
isRestart := false
|
||||
hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
|
||||
requestURI2NF := fmt.Sprintf("%s/api/rest/systemManagement/v1/elementType/%s/objectType/systemState",
|
||||
hostUri, neTypeLower)
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
resp, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
|
||||
//SetHeaders(map[string]string{"accessToken": token}).
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
Get(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to get system state:", err)
|
||||
isRestart = true
|
||||
} else {
|
||||
systemState := make(map[string]interface{})
|
||||
_ = json.Unmarshal(resp.Body(), &systemState)
|
||||
expiryDate := fmt.Sprintf("%v", systemState["expiryDate"])
|
||||
t1_expiry, _ := time.ParseInLocation(time.DateOnly, expiryDate, time.Local)
|
||||
nowDate := time.Now().Local()
|
||||
nowDate.Format(time.DateOnly)
|
||||
isRestart = t1_expiry.Before(nowDate)
|
||||
}
|
||||
// case non-expired license: send NE reload license MML
|
||||
if !isRestart {
|
||||
// send reload license MML
|
||||
var buf [20 * 1024]byte
|
||||
//buf := make([]byte, 0)
|
||||
var n int
|
||||
if neInfo != nil {
|
||||
switch strings.ToLower(neType) {
|
||||
case "ims":
|
||||
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
|
||||
conn, err := net.Dial("tcp", hostMML)
|
||||
if err != nil {
|
||||
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
|
||||
log.Error(errMsg)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second))
|
||||
|
||||
_, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\r\n"))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Trace(string(buf[0:n]))
|
||||
|
||||
_, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\r\n"))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Trace(string(buf[0 : n-len(neType)-2]))
|
||||
|
||||
mmlCommand := "check lic\r\n"
|
||||
|
||||
_, err = conn.Write([]byte(mmlCommand))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Trace(string(buf[0 : n-len(neType)-2]))
|
||||
|
||||
re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符
|
||||
//re2 := regexp.MustCompile(`\x00`) // 匹配空字符
|
||||
re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
|
||||
//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
|
||||
// upf telnet buffer只能读取一次,需要去掉前面的多余字符
|
||||
result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
|
||||
result = re2.ReplaceAllString(result, "")
|
||||
if !strings.Contains(result, "COMMAND OK") {
|
||||
err = fmt.Errorf("failed to check license, %s", result)
|
||||
log.Error(err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
default:
|
||||
hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, config.GetYamlConfig().MML.Port)
|
||||
conn, err := net.Dial("tcp", hostMML)
|
||||
if err != nil {
|
||||
errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err)
|
||||
log.Error(errMsg)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
defer conn.Close()
|
||||
|
||||
conn.SetDeadline(time.Now().Add(TIME_DEAD_LINE * time.Second))
|
||||
loginStr := fmt.Sprintf("%s\n%s\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
|
||||
_, err = conn.Write([]byte(loginStr))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Trace(string(buf[0:n]))
|
||||
|
||||
mmlCommand := "check lic\n"
|
||||
_, err = conn.Write([]byte(mmlCommand))
|
||||
if err != nil {
|
||||
log.Error("Failed to write:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
|
||||
|
||||
n, err = conn.Read(buf[0:])
|
||||
if err != nil {
|
||||
log.Error("Failed to read:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Trace(string(buf[0 : n-len(neType)-2]))
|
||||
re1 := regexp.MustCompile(`\x1B\[[0-9;]*[a-zA-Z]`) // 匹配包含␛的控制字符
|
||||
//re2 := regexp.MustCompile(`\x00`) // 匹配空字符
|
||||
re2 := regexp.MustCompile(`[\x00-\x08\x0B\x0C\x0E-\x1F\x7F\x1B]`) // 匹配空字符和包含␛的控制字符
|
||||
//re := regexp.MustCompile(`[\x00-\x1F\x7F]`)
|
||||
result := re1.ReplaceAllString(string(buf[0:n-len(neType)-2]), "")
|
||||
result = re2.ReplaceAllString(result, "")
|
||||
if !strings.Contains(result, "COMMAND OK") {
|
||||
err = fmt.Errorf("failed to check license, %s", result)
|
||||
log.Error(err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// case expired license: restart NE service
|
||||
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)
|
||||
}
|
||||
983
features/cm/ne.go
Normal file
983
features/cm/ne.go
Normal file
@@ -0,0 +1,983 @@
|
||||
package cm
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"nms_nbi/lib/dborm"
|
||||
"nms_nbi/lib/global"
|
||||
"nms_nbi/lib/log"
|
||||
"nms_nbi/lib/services"
|
||||
"nms_nbi/restagent/config"
|
||||
tokenConst "nms_nbi/src/framework/constants/token"
|
||||
neService "nms_nbi/src/modules/network_element/service"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var (
|
||||
// NE CM export/import
|
||||
NeCmUri = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/cm"
|
||||
// NE info
|
||||
UriNeInfo = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/neInfo"
|
||||
// NE backup file
|
||||
UriNeCmFile = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/{neType}/neBackup/{fileName}"
|
||||
// service action uri, action: start/stop/restart
|
||||
UriNeService = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/service/{action}"
|
||||
// nf instance action uri, action: start/stop/restart
|
||||
UriNeInstance = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/instance/{action}"
|
||||
|
||||
CustomNeCmUri = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/cm"
|
||||
CustomUriNeInfo = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/neInfo"
|
||||
CustomUriNeCmFile = config.UriPrefix + "/systemManagement/{apiVersion}/{neType}/neBackup/{fileName}"
|
||||
// service action uri, action: start/stop/restart
|
||||
CustomUriNeService = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/service/{action}"
|
||||
// nf instance action uri, action: start/stop/restart
|
||||
CustomUriNeInstance = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/instance/{action}"
|
||||
)
|
||||
|
||||
const (
|
||||
NEStatusActive = 0
|
||||
NEStatusOffline = 1
|
||||
NEStatusStandby = 2
|
||||
NEStatusMaintain = 3
|
||||
)
|
||||
|
||||
var client = resty.New()
|
||||
|
||||
func init() {
|
||||
/*
|
||||
client.
|
||||
SetTimeout(10 * time.Second).
|
||||
SetRetryCount(1).
|
||||
SetRetryWaitTime(1 * time.Second).
|
||||
SetRetryMaxWaitTime(2 * time.Second).
|
||||
SetRetryAfter(func(client *resty.Client, resp *resty.Response) (time.Duration, error) {
|
||||
return 0, errors.New("quota exceeded")
|
||||
})
|
||||
*/
|
||||
client.
|
||||
SetTimeout(time.Duration(1 * time.Second))
|
||||
}
|
||||
|
||||
func GetNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("GetNeInfo processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["elementTypeValue"]
|
||||
if neType == "" {
|
||||
log.Error("elementTypeValue is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
neId := services.GetUriParamString(r, "ne_id", ",", false, false)
|
||||
|
||||
// no, _ := strconv.ParseInt(neId, 10, 64)
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Error("dborm.XormGetNeInfo is failed:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
var response services.DataResponse
|
||||
response.Data = neInfo
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
type OmcNeConfig struct {
|
||||
NeId string `json:"neId" xorm:"ne_id"` // 网元标识(内部),
|
||||
RmUID string `json:"rmUID" xorm:"rm_uid"` // rmUID 网元唯一标识
|
||||
NeName string `json:"neName" xorm:"ne_name"` // 网元名称(内部)/友好名称(北向资源/性能等使用)
|
||||
PvFlag string `json:"pvFlag" xorm:"pv_flag"` // 网元虚实性标识 VNF/PNF: 虚拟/物理
|
||||
Province string `json:"province" xorm:"province"` // 网元所在省份
|
||||
VendorName string `json:"vendorName" xorm:"vendor_name"` // 厂商名称
|
||||
// ManagedBy string `json:"managedBy" xorm:"managed_by"` // 管理ManagedElement的ManagementNode对象类的DN值
|
||||
Dn string `json:"dn" xorm:"dn"` // 资源里边的ManagedBy,性能的Dn,网络唯一标识
|
||||
}
|
||||
|
||||
func PostNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("PostNeInfo processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("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)
|
||||
syncFlag := services.GetUriParamString(r, "sync2ne", ",", false, false)
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
if err != nil {
|
||||
log.Error("Failed to o.ReadAll:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
log.Trace("Body:", string(body))
|
||||
|
||||
neInfo := new(dborm.NeInfo)
|
||||
err = json.Unmarshal(body, neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to json.Unmarshal:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
neInfo.UpdateTime = time.Now().Format(time.DateTime)
|
||||
log.Debug("NE info:", neInfo)
|
||||
|
||||
//if !config.GetYamlConfig().OMC.Chk2Ne {
|
||||
if syncFlag == "false" || neTypeUpper == config.GetYamlConfig().OMC.NeType {
|
||||
neInfo.Status = NEStatusMaintain
|
||||
affected, err := dborm.XormInsertNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to insert Ne info:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 刷新缓存,不存在结构体网元Id空字符串
|
||||
neService.NewNeInfoImpl.RefreshByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
|
||||
mapRow := make(map[string]interface{})
|
||||
row := map[string]interface{}{"affectedRows": affected}
|
||||
mapRow["data"] = row
|
||||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||||
return
|
||||
} else {
|
||||
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
|
||||
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
|
||||
apiUri := fmt.Sprintf("%s/systemManagement/v1/elementType/%s/objectType/config/omcNeConfig", config.DefaultUriPrefix, strings.ToLower(neInfo.NeType))
|
||||
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
omcNeConfig := &OmcNeConfig{
|
||||
NeId: neInfo.NeId,
|
||||
RmUID: neInfo.RmUID,
|
||||
NeName: neInfo.NeName,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
Province: neInfo.Province,
|
||||
VendorName: neInfo.VendorName,
|
||||
Dn: neInfo.Dn,
|
||||
}
|
||||
body, _ = json.Marshal(omcNeConfig)
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Put(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Put:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Info("StatusCode: ", response.StatusCode())
|
||||
|
||||
respMsg := make(map[string]interface{})
|
||||
switch response.StatusCode() {
|
||||
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
||||
neInfo.Status = NEStatusActive
|
||||
affected, err := dborm.XormInsertNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to dborm.XormInsertNeInfo:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else if affected <= 0 {
|
||||
log.Infof("Not record affected to insert ne_info")
|
||||
}
|
||||
|
||||
// 刷新缓存,不存在结构体网元Id空字符串
|
||||
neService.NewNeInfoImpl.RefreshByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
return
|
||||
default:
|
||||
log.Info("response body:", string(response.Body()))
|
||||
body := new(map[string]interface{})
|
||||
_ = json.Unmarshal(response.Body(), &body)
|
||||
respMsg["error"] = body
|
||||
}
|
||||
|
||||
services.ResponseWithJson(w, response.StatusCode(), respMsg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func PutNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("PutNeInfo processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["elementTypeValue"]
|
||||
if neType == "" {
|
||||
log.Error("elementTypeValue is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
neTypeLower := strings.ToLower(neType)
|
||||
neTypeUpper := strings.ToUpper(neType)
|
||||
syncFlag := services.GetUriParamString(r, "sync2ne", ",", false, false)
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
if err != nil {
|
||||
log.Error("Failed to io.ReadAll:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
neInfo := new(dborm.NeInfo)
|
||||
_ = json.Unmarshal(body, neInfo)
|
||||
neInfo.NeType = strings.ToUpper(neType)
|
||||
neInfo.UpdateTime = time.Now().Format(time.DateTime)
|
||||
log.Debug("NE info:", neInfo)
|
||||
|
||||
//if !config.GetYamlConfig().OMC.Chk2Ne {
|
||||
if syncFlag == "false" || neTypeUpper == config.GetYamlConfig().OMC.NeType {
|
||||
neInfo.Status = NEStatusMaintain
|
||||
affected, err := dborm.XormUpdateNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to update Ne info:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 刷新缓存,不存在结构体网元Id空字符串
|
||||
neService.NewNeInfoImpl.RefreshByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
|
||||
mapRow := make(map[string]interface{})
|
||||
row := map[string]interface{}{"affectedRows": affected}
|
||||
mapRow["data"] = row
|
||||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||||
return
|
||||
} else {
|
||||
hostUri := global.CombineHostUri(neInfo.Ip, neInfo.Port)
|
||||
//hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
|
||||
apiUri := fmt.Sprintf("%s/systemManagement/v1/elementType/%s/objectType/config/omcNeConfig", config.DefaultUriPrefix, neTypeLower)
|
||||
requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri)
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
omcNeConfig := &OmcNeConfig{
|
||||
NeId: neInfo.NeId,
|
||||
RmUID: neInfo.RmUID,
|
||||
NeName: neInfo.NeName,
|
||||
PvFlag: neInfo.PvFlag,
|
||||
Province: neInfo.Province,
|
||||
VendorName: neInfo.VendorName,
|
||||
Dn: neInfo.Dn,
|
||||
}
|
||||
body, _ = json.Marshal(omcNeConfig)
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Put(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Put:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Info("StatusCode: ", response.StatusCode())
|
||||
|
||||
respMsg := make(map[string]interface{})
|
||||
switch response.StatusCode() {
|
||||
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
||||
neInfo.Status = NEStatusActive
|
||||
affected, err := dborm.XormUpdateNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to dborm.XormUpdateNeInfo:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else if affected <= 0 {
|
||||
log.Infof("Not record affected to insert ne_info")
|
||||
}
|
||||
|
||||
// 刷新缓存,不存在结构体网元Id空字符串
|
||||
neService.NewNeInfoImpl.RefreshByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
return
|
||||
default:
|
||||
log.Info("response body:", string(response.Body()))
|
||||
body := new(map[string]interface{})
|
||||
_ = json.Unmarshal(response.Body(), &body)
|
||||
respMsg["error"] = body
|
||||
}
|
||||
|
||||
services.ResponseWithJson(w, response.StatusCode(), respMsg)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func DeleteNeInfo(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("DeleteNeInfo processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["elementTypeValue"]
|
||||
if neType == "" {
|
||||
log.Error("elementTypeValue is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
neInfo := new(dborm.NeInfo)
|
||||
_ = json.Unmarshal(body, neInfo)
|
||||
neInfo.NeType = strings.ToUpper(neType)
|
||||
neInfo.NeId = services.GetUriParamString(r, "ne_id", ",", false, false)
|
||||
neInfo, err = dborm.XormGetNeInfo(neInfo.NeType, neInfo.NeId)
|
||||
if err != nil || neInfo == nil {
|
||||
log.Error("Failed to delete Ne info:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Debug("NE info:", neInfo)
|
||||
|
||||
// if NE in active status, can't delete NE
|
||||
if !IsActiveNF(neInfo) {
|
||||
affected, err := dborm.XormDeleteNeInfo(neInfo)
|
||||
if err != nil {
|
||||
log.Error("Failed to delete Ne info:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
// 刷新缓存,不存在结构体网元Id空字符串
|
||||
neService.NewNeInfoImpl.RefreshByNeTypeAndNeID(neInfo.NeType, neInfo.NeId)
|
||||
|
||||
mapRow := make(map[string]interface{})
|
||||
row := map[string]interface{}{"affectedRows": affected}
|
||||
mapRow["data"] = row
|
||||
services.ResponseWithJson(w, http.StatusOK, mapRow)
|
||||
return
|
||||
}
|
||||
err = global.ErrCMCannotDeleteActiveNE
|
||||
log.Error(err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
}
|
||||
|
||||
func IsActiveNF(neInfo *dborm.NeInfo) bool {
|
||||
log.Debug("IsActiveNF processing... ")
|
||||
|
||||
hostUri := fmt.Sprintf("http://%s:%v", neInfo.Ip, neInfo.Port)
|
||||
requestURI := fmt.Sprintf(config.UriPrefix+"/systemManagement/v1/elementType/%s/objectType/systemState",
|
||||
strings.ToLower(neInfo.NeType))
|
||||
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
Get(hostUri + requestURI)
|
||||
if err != nil {
|
||||
log.Error("Failed to Get:", err)
|
||||
return false
|
||||
}
|
||||
|
||||
switch response.StatusCode() {
|
||||
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func ExportCmFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("ExportCmFromNF processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("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)
|
||||
|
||||
neId := services.GetUriParamString(r, "ne_id", ",", false, false)
|
||||
|
||||
// neInfo := new(dborm.NeInfo)
|
||||
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)
|
||||
nePath := fmt.Sprintf("%s/etc/%s", config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
isExist, err := global.PathExists(nePath)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to stat:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
if isExist {
|
||||
err = os.RemoveAll(nePath)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to RemoveAll:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
err = os.MkdirAll(nePath, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Errorf("Failed to MkdirAll:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
var scpCmd string
|
||||
ipType := global.ParseIPAddr(neInfo.Ip)
|
||||
omcNetypeLower := strings.ToLower(config.GetYamlConfig().OMC.NeType)
|
||||
etcListIMS := "{*.yaml,mmtel,vars.cfg}"
|
||||
if config.GetYamlConfig().NE.EtcListIMS != "" {
|
||||
etcListIMS = config.GetYamlConfig().NE.EtcListIMS
|
||||
}
|
||||
switch neTypeLower {
|
||||
case omcNetypeLower:
|
||||
if ipType == global.IsIPv4 {
|
||||
scpCmd = fmt.Sprintf("scp -r %s@%s:%s/etc/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
|
||||
neInfo.Ip, config.GetYamlConfig().NE.OmcDir, config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
} else {
|
||||
scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/etc/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
|
||||
neInfo.Ip, config.GetYamlConfig().NE.OmcDir, config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
}
|
||||
|
||||
case "ims":
|
||||
if ipType == global.IsIPv4 {
|
||||
scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/%s %s/etc/%s", config.GetYamlConfig().NE.User,
|
||||
neInfo.Ip, config.GetYamlConfig().NE.EtcDir, neTypeLower,
|
||||
etcListIMS, config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
} else {
|
||||
scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/%s %s/etc/%s", config.GetYamlConfig().NE.User,
|
||||
neInfo.Ip, config.GetYamlConfig().NE.EtcDir, neTypeLower,
|
||||
etcListIMS, config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
}
|
||||
|
||||
case "mme":
|
||||
if ipType == global.IsIPv4 {
|
||||
scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.conf %s/etc/%s", config.GetYamlConfig().NE.User,
|
||||
neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
|
||||
neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
} else {
|
||||
scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/*.conf %s/etc/%s", config.GetYamlConfig().NE.User,
|
||||
neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
|
||||
neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
}
|
||||
|
||||
default:
|
||||
if ipType == global.IsIPv4 {
|
||||
scpCmd = fmt.Sprintf("scp -r %s@%s:%s/%s/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
|
||||
neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
|
||||
neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
} else {
|
||||
scpCmd = fmt.Sprintf("scp -r %s@[%s]:%s/%s/*.yaml %s/etc/%s", config.GetYamlConfig().NE.User,
|
||||
neInfo.Ip, config.GetYamlConfig().NE.EtcDir,
|
||||
neTypeLower, config.GetYamlConfig().OMC.Backup, neTypeLower)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
zipFile := fmt.Sprintf("%s-%s-etc-%s.zip", neTypeLower, strings.ToLower(neInfo.NeId), time.Now().Format(global.DateData))
|
||||
zipFilePath := config.GetYamlConfig().OMC.Backup + "/" + zipFile
|
||||
zipCmd := fmt.Sprintf("cd %s/etc && zip -r %s %s/*", config.GetYamlConfig().OMC.Backup, zipFilePath, neTypeLower)
|
||||
|
||||
command := fmt.Sprintf("%s&&%s", scpCmd, zipCmd)
|
||||
|
||||
log.Debug("command:", command)
|
||||
err = ExecCmd(command)
|
||||
if err != nil {
|
||||
log.Error("Faile to exec command:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
md5Sum, err := global.GetFileMD5Sum(zipFilePath)
|
||||
if err != nil {
|
||||
log.Error("Faile to md5sum:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
//log.Debug("md5Str:", md5Sum)
|
||||
path := config.GetYamlConfig().OMC.Backup
|
||||
neBackup := dborm.NeBackup{NeType: neTypeUpper, NeId: neId, FileName: zipFile, Path: path, Md5Sum: md5Sum}
|
||||
_, err = dborm.XormInsertTableOne("ne_backup", neBackup)
|
||||
if err != nil {
|
||||
log.Error("Faile to XormInsertTableOne:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
//services.ResponseFileWithNameAndMD5(w, http.StatusOK, zipFile, path, md5Sum)
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
}
|
||||
|
||||
type ImportCMJson struct {
|
||||
FileName string `json:"fileName"`
|
||||
}
|
||||
|
||||
func ImportCmToNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("ImportCmToNF processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("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)
|
||||
|
||||
neId := services.GetUriParamString(r, "ne_id", ",", false, false)
|
||||
|
||||
var fileName, path string
|
||||
if services.IsJsonContentType(r) {
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
log.Debug("Body:", string(body))
|
||||
|
||||
importCMJson := new(ImportCMJson)
|
||||
_ = json.Unmarshal(body, importCMJson)
|
||||
fileName = importCMJson.FileName
|
||||
path = config.GetYamlConfig().OMC.Backup
|
||||
} else {
|
||||
path = config.GetYamlConfig().OMC.Upload
|
||||
fileName, err = services.HandleUploadFile(r, path, "")
|
||||
if err != nil {
|
||||
log.Error("Faile to HandleUploadFile:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
filePath := fmt.Sprintf("%s/%s", path, fileName)
|
||||
|
||||
// neInfo := new(dborm.NeInfo)
|
||||
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)
|
||||
|
||||
md5Sum, err := global.GetFileMD5Sum(filePath)
|
||||
if err != nil {
|
||||
log.Error("Faile to GetFileMD5Sum:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
//neBackup := dborm.NeBackup{NeType: neType, NeId: neId, Md5Sum: md5Sum}
|
||||
//log.Debug("neBackup:", neBackup)
|
||||
where := fmt.Sprintf("ne_type='%s' and ne_id='%s' and md5_sum='%s'", neTypeUpper, neId, md5Sum)
|
||||
has, err := dborm.XormExistTableOne("ne_backup", where)
|
||||
if err != nil {
|
||||
log.Error("Faile to XormInsertTableOne:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else if !has {
|
||||
err = global.ErrCMInvalidBackupFile
|
||||
log.Error(err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
// nePath := fmt.Sprintf("%s/etc/%s", config.GetYamlConfig().OMC.Upload, neTypeLower)
|
||||
// isExist, err := global.PathExists(nePath)
|
||||
// if err != nil {
|
||||
// log.Errorf("Failed to stat:", err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
// if isExist {
|
||||
// err = os.RemoveAll(nePath)
|
||||
// if err != nil {
|
||||
// log.Errorf("Failed to remove:", err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
// unzipCmd := fmt.Sprintf("unzip -o %s -d %s", filePath, config.GetYamlConfig().OMC.Upload)
|
||||
|
||||
// var scpCmd string
|
||||
// ipType := global.ParseIPAddr(neInfo.Ip)
|
||||
// if ipType == global.IsIPv4 {
|
||||
// scpCmd = fmt.Sprintf("scp -r %s/etc/%s %s@%s:%s", config.GetYamlConfig().OMC.Upload,
|
||||
// neTypeLower, config.GetYamlConfig().NE.User, neInfo.Ip, config.GetYamlConfig().NE.EtcDir)
|
||||
// } else {
|
||||
// scpCmd = fmt.Sprintf("scp -r %s/etc/%s %s@[%s]:%s", config.GetYamlConfig().OMC.Upload,
|
||||
// neTypeLower, config.GetYamlConfig().NE.User, neInfo.Ip, config.GetYamlConfig().NE.EtcDir)
|
||||
// }
|
||||
|
||||
// err = ExecCmd(fmt.Sprintf("%s && %s", unzipCmd, scpCmd))
|
||||
// if err != nil {
|
||||
// log.Errorf("Faile to scp NF: neType=%s, neId=%s, ip=%s", neType, neId, neInfo.Ip)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
|
||||
// nePath := fmt.Sprintf("%s/etc/%s", config.GetYamlConfig().OMC.Upload, neTypeLower)
|
||||
// isExist, err := global.PathExists(nePath)
|
||||
// if err != nil {
|
||||
// log.Errorf("Failed to stat:", err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
// if isExist {
|
||||
// err = os.RemoveAll(nePath)
|
||||
// if err != nil {
|
||||
// log.Errorf("Failed to remove:", err)
|
||||
// services.ResponseInternalServerError500ProcessError(w, err)
|
||||
// return
|
||||
// }
|
||||
// }
|
||||
var scpZipCmd string
|
||||
ipType := global.ParseIPAddr(neInfo.Ip)
|
||||
if ipType == global.IsIPv4 {
|
||||
scpZipCmd = fmt.Sprintf("scp -r %s %s@%s:%s", filePath,
|
||||
config.GetYamlConfig().NE.User, neInfo.Ip, config.GetYamlConfig().NE.ScpDir)
|
||||
} else {
|
||||
scpZipCmd = fmt.Sprintf("scp -r %s %s@[%s]:%s", filePath,
|
||||
config.GetYamlConfig().NE.User, neInfo.Ip, config.GetYamlConfig().NE.ScpDir)
|
||||
}
|
||||
err = ExecCmd(scpZipCmd)
|
||||
if err != nil {
|
||||
log.Errorf("Faile to scp NF: neType=%s, neId=%s, ip=%s", neType, neId, neInfo.Ip)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
neFilePath := config.GetYamlConfig().NE.ScpDir + "/" + fileName
|
||||
var unzipCmd string
|
||||
if neTypeLower != "omc" {
|
||||
unzipCmd = fmt.Sprintf("sudo unzip -o %s -d %s", neFilePath, config.GetYamlConfig().NE.EtcDir)
|
||||
} else {
|
||||
unzipCmd = fmt.Sprintf("sudo unzip -oj %s -d %s/etc", neFilePath, config.GetYamlConfig().NE.OmcDir)
|
||||
}
|
||||
sshHost := fmt.Sprintf("%s@%s", config.GetYamlConfig().NE.User, neInfo.Ip)
|
||||
cmd := exec.Command("ssh", sshHost, unzipCmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Tracef("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("Faile to execute command:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
}
|
||||
|
||||
func DownloadNeBackupFile(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("DownloadNeBackupFile processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["neType"]
|
||||
if neType == "" {
|
||||
log.Error("neType is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
neTypeUpper := strings.ToUpper(neType)
|
||||
//neTypeLower := strings.ToLower(neType)
|
||||
|
||||
fileName := vars["fileName"]
|
||||
if fileName == "" {
|
||||
log.Error("fileName is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("select * from ne_backup where ne_type='%s' and file_name='%s'", neTypeUpper, fileName)
|
||||
neBackup, err := dborm.XormGetDataBySQL(sql)
|
||||
if err != nil {
|
||||
log.Error("Faile to XormGetDataBySQL:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else if len(*neBackup) == 0 {
|
||||
err := global.ErrCMNotFoundTargetBackupFile
|
||||
log.Error(err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
path := (*neBackup)[0]["path"]
|
||||
md5Sum := (*neBackup)[0]["md5_sum"]
|
||||
|
||||
services.ResponseFileWithNameAndMD5(w, http.StatusOK, fileName, path, md5Sum)
|
||||
}
|
||||
|
||||
func DeleteNeBackupFile(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("DeleteNeBackupFile processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["neType"]
|
||||
if neType == "" {
|
||||
log.Error("neType is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
neTypeUpper := strings.ToUpper(neType)
|
||||
//neTypeLower := strings.ToLower(neType)
|
||||
|
||||
fileName := vars["fileName"]
|
||||
if fileName == "" {
|
||||
log.Error("fileName is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
sql := fmt.Sprintf("select * from ne_backup where ne_type='%s' and file_name='%s'", neTypeUpper, fileName)
|
||||
neBackup, err := dborm.XormGetDataBySQL(sql)
|
||||
if err != nil {
|
||||
log.Error("Faile to XormGetDataBySQL:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else if len(*neBackup) == 0 {
|
||||
err := global.ErrCMNotFoundTargetBackupFile
|
||||
log.Error(err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
where := fmt.Sprintf("ne_type='%s' and file_name='%s'", neTypeUpper, fileName)
|
||||
affected, err := dborm.XormDeleteDataByWhere(where, "ne_backup")
|
||||
if err != nil || affected == 0 {
|
||||
log.Error("Faile to XormGetDataBySQL:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
path := (*neBackup)[0]["path"]
|
||||
filePath := fmt.Sprintf("%s/%s", path, fileName)
|
||||
err = os.Remove(filePath)
|
||||
if err != nil {
|
||||
log.Error("Faile to Remove:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
}
|
||||
|
||||
func PostNeServiceAction(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("PostNeServiceAction processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("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)
|
||||
action := vars["action"]
|
||||
|
||||
neId := services.GetUriParamString(r, "neId", ",", false, false)
|
||||
|
||||
// neInfo := new(dborm.NeInfo)
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Error("Failed to get ne_info:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Debug("neInfo:", neInfo)
|
||||
|
||||
sshHost := fmt.Sprintf("%s@%s", config.GetYamlConfig().NE.User, neInfo.Ip)
|
||||
switch neTypeLower {
|
||||
case "omc":
|
||||
actionCmd := fmt.Sprintf("sudo %s/bin/omcsvc.sh %s", config.GetYamlConfig().NE.OmcDir, action)
|
||||
cmd := exec.Command("ssh", sshHost, actionCmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Debugf("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Errorf("Faile to execute ssh %s omc:%v", action, err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
case "ims":
|
||||
switch action {
|
||||
case "start", "stop":
|
||||
actionCmd := fmt.Sprintf("sudo ims-%s", action)
|
||||
cmd := exec.Command("ssh", sshHost, actionCmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Debugf("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Errorf("Faile to execute %s command:%v", actionCmd, err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
case "restart":
|
||||
actionCmd := "sudo ims-stop && sudo ims-start"
|
||||
cmd := exec.Command("ssh", sshHost, actionCmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Debugf("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Errorf("Faile to execute %s command:%v", actionCmd, err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = global.ErrCMUnknownServiceAction
|
||||
log.Errorf("%v, action:%s", err, action)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
default:
|
||||
actionCmd := fmt.Sprintf("sudo systemctl %s %s.service", action, neTypeLower)
|
||||
cmd := exec.Command("ssh", sshHost, actionCmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Debugf("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("Faile to execute command:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
}
|
||||
|
||||
func PostNeInstanceAction(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("PostNeInstanceAction processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("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)
|
||||
action := vars["action"]
|
||||
|
||||
neId := services.GetUriParamString(r, "neId", ",", false, false)
|
||||
|
||||
// neInfo := new(dborm.NeInfo)
|
||||
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)
|
||||
|
||||
sshHost := fmt.Sprintf("%s@%s", config.GetYamlConfig().NE.User, neInfo.Ip)
|
||||
switch action {
|
||||
case "poweron":
|
||||
actionCmd := "sudo poweron"
|
||||
cmd := exec.Command("ssh", sshHost, actionCmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Debugf("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("Faile to execute ssh %s omc:", action, err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
case "poweroff":
|
||||
actionCmd := "sudo poweroff"
|
||||
cmd := exec.Command("ssh", sshHost, actionCmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Debugf("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("Faile to execute ssh sudo poweroff:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
case "reboot":
|
||||
actionCmd := "sudo reboot"
|
||||
cmd := exec.Command("ssh", sshHost, actionCmd)
|
||||
out, err := cmd.CombinedOutput()
|
||||
log.Debugf("Exec output: %v", string(out))
|
||||
if err != nil {
|
||||
log.Error("Faile to execute ssh sudo reboot:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
default:
|
||||
err = global.ErrCMUnknownInstanceAction
|
||||
log.Errorf("%v, action:%s", err, action)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
}
|
||||
278
features/cm/param.go
Normal file
278
features/cm/param.go
Normal file
@@ -0,0 +1,278 @@
|
||||
package cm
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"nms_nbi/lib/dborm"
|
||||
"nms_nbi/lib/global"
|
||||
"nms_nbi/lib/log"
|
||||
"nms_nbi/lib/services"
|
||||
"nms_nbi/restagent/config"
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
|
||||
tokenConst "nms_nbi/src/framework/constants/token"
|
||||
|
||||
"github.com/go-resty/resty/v2"
|
||||
"github.com/gorilla/mux"
|
||||
)
|
||||
|
||||
var (
|
||||
// parameter config management
|
||||
ParamConfigUri = config.DefaultUriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/config/{paraName}"
|
||||
|
||||
CustomParamConfigUri = config.UriPrefix + "/systemManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/config/{paraName}"
|
||||
)
|
||||
|
||||
func GetParamConfigFromNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("GetParamConfigFromNF processing... ")
|
||||
|
||||
// data := make([]map[string]interface{}, 1)
|
||||
var response services.DataResponse
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["elementTypeValue"]
|
||||
if neType == "" {
|
||||
log.Error("elementTypeValue is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
token, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
restHostPort := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port)
|
||||
getNeInfoPattern := fmt.Sprintf(config.DefaultUriPrefix+"/databaseManagement/v1/%s/ne_info", config.GetYamlConfig().Database.Name)
|
||||
getNeInfoURI := restHostPort + getNeInfoPattern
|
||||
neId := services.GetUriParamString(r, "ne_id", ",", true, true)
|
||||
if neId == "" {
|
||||
getNeInfoURI = getNeInfoURI + fmt.Sprintf("?WHERE=status+in+('0','3')+and+ne_type='%s'", neType)
|
||||
} else {
|
||||
getNeInfoURI = getNeInfoURI + fmt.Sprintf("?WHERE=status+in+('0','3')+and+ne_type='%v'+and+ne_id+in+%v", neType, neId)
|
||||
}
|
||||
log.Debug("getNeInfoURI:", getNeInfoURI)
|
||||
|
||||
client := resty.New()
|
||||
resp, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{tokenConst.HEADER_KEY: r.Header.Get(tokenConst.HEADER_KEY)}).
|
||||
SetHeaders(map[string]string{"accessToken": token}).
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
Get(getNeInfoURI)
|
||||
if err != nil {
|
||||
log.Error("Failed to Get:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
log.Trace("NE info:", string(resp.Body()))
|
||||
|
||||
// var neList []dborm.NeInfo
|
||||
neList, _ := dborm.XormParseResult(resp.Body())
|
||||
|
||||
if len(neList) >= 1 {
|
||||
s := neList[0]
|
||||
requestURI2NF := fmt.Sprintf("http://%s:%v%s", s.Ip, s.Port, r.RequestURI)
|
||||
log.Debug("requestURI2NF:", requestURI2NF)
|
||||
|
||||
resp, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
Get(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Get from NF:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
} else {
|
||||
_ = json.Unmarshal(resp.Body(), &response)
|
||||
}
|
||||
log.Debug("response:", response)
|
||||
}
|
||||
|
||||
services.ResponseWithJson(w, http.StatusOK, response)
|
||||
}
|
||||
|
||||
func PostParamConfigToNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("PostParamConfigToNF processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["elementTypeValue"]
|
||||
if neType == "" {
|
||||
log.Error("elementTypeValue is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
neId := services.GetUriParamString(r, "ne_id", ",", false, false)
|
||||
|
||||
// no, _ := strconv.ParseInt(neId, 10, 64)
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Error("dborm.XormGetNeInfo is failed:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
return
|
||||
}
|
||||
|
||||
requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
|
||||
log.Debug("requestURI2NF: POST ", requestURI2NF)
|
||||
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
client := resty.New()
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Post(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to POST to NF:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
services.ResponseWithJson(w, http.StatusNoContent, response)
|
||||
}
|
||||
|
||||
func PutParamConfigToNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("PutParamConfigToNF processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["elementTypeValue"]
|
||||
if neType == "" {
|
||||
log.Error("elementTypeValue is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// OMC配置接口 /api/rest/systemManagement/v1/elementType/omc/objectType/config/omcNeConfig
|
||||
if v, ok := vars["paraName"]; ok && v == "omcNeConfig" && strings.ToLower(neType) == "omc" {
|
||||
PutOMCNeConfig(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
neId := services.GetUriParamString(r, "ne_id", ",", false, false)
|
||||
// no, _ := strconv.ParseInt(neId, 10, 64)
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Error("dborm.XormGetNeInfo is failed:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
return
|
||||
}
|
||||
|
||||
requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
|
||||
log.Debug("requestURI2NF: PUT ", requestURI2NF)
|
||||
|
||||
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小
|
||||
if err != nil {
|
||||
log.Error("io.ReadAll is failed:", err)
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
client := resty.New()
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
SetBody(body).
|
||||
Put(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to Put to NF:", err)
|
||||
services.ResponseInternalServerError500ProcessError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
services.ResponseWithJson(w, http.StatusNoContent, response)
|
||||
}
|
||||
|
||||
// PutOMCNeConfig 网元OMC配置
|
||||
//
|
||||
// 目前没配置,返回204
|
||||
func PutOMCNeConfig(w http.ResponseWriter, r *http.Request) {
|
||||
// vars := mux.Vars(r)
|
||||
// neType := vars["elementTypeValue"]
|
||||
// if neType == "" {
|
||||
// log.Error("elementTypeValue is empty")
|
||||
// services.ResponseNotFound404UriNotExist(w, r)
|
||||
// return
|
||||
// }
|
||||
// body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
|
||||
// if err != nil {
|
||||
// log.Error("Failed to io.ReadAll:", err)
|
||||
// services.ResponseNotFound404UriNotExist(w, r)
|
||||
// return
|
||||
// }
|
||||
|
||||
// neInfo := new(dborm.NeInfo)
|
||||
// _ = json.Unmarshal(body, neInfo)
|
||||
// neInfo.NeType = strings.ToUpper(neType)
|
||||
|
||||
services.ResponseStatusOK204NoContent(w)
|
||||
}
|
||||
|
||||
func DeleteParamConfigToNF(w http.ResponseWriter, r *http.Request) {
|
||||
log.Debug("DeleteParamConfigToNF processing... ")
|
||||
|
||||
_, err := services.CheckFrontValidRequest(w, r)
|
||||
if err != nil {
|
||||
log.Error("Request error:", err)
|
||||
return
|
||||
}
|
||||
|
||||
vars := mux.Vars(r)
|
||||
neType := vars["elementTypeValue"]
|
||||
if neType == "" {
|
||||
log.Error("elementTypeValue is empty")
|
||||
services.ResponseNotFound404UriNotExist(w, r)
|
||||
return
|
||||
}
|
||||
neId := services.GetUriParamString(r, "ne_id", ",", false, false)
|
||||
|
||||
// no, _ := strconv.ParseInt(neId, 10, 64)
|
||||
neInfo, err := dborm.XormGetNeInfo(neType, neId)
|
||||
if err != nil {
|
||||
log.Error("dborm.XormGetNeInfo is failed:", err)
|
||||
services.ResponseInternalServerError500DatabaseOperationFailed(w)
|
||||
return
|
||||
}
|
||||
|
||||
requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI)
|
||||
log.Debug("requestURI2NF: DELETE ", requestURI2NF)
|
||||
|
||||
client := resty.New()
|
||||
response, err := client.R().
|
||||
EnableTrace().
|
||||
SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}).
|
||||
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
||||
Delete(requestURI2NF)
|
||||
if err != nil {
|
||||
log.Error("Failed to delete parameter:", err)
|
||||
services.ResponseInternalServerError500NFConnectRefused(w)
|
||||
return
|
||||
}
|
||||
|
||||
services.ResponseWithJson(w, http.StatusNoContent, response)
|
||||
}
|
||||
1025
features/cm/software.go
Normal file
1025
features/cm/software.go
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user