feat: omc原始代码

This commit is contained in:
TsMask
2024-03-12 10:58:33 +08:00
parent 5133c93971
commit 2d01bb86d1
432 changed files with 66597 additions and 1 deletions

95
features/cm/exec_linux.go Normal file
View 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
}

View 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
View 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
View 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
View 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

File diff suppressed because it is too large Load Diff