1
0
Files
omc_api/features/mml/mml.go
2023-12-29 20:22:43 +08:00

549 lines
18 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package mml
import (
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"regexp"
"strings"
"time"
"ems.agt/lib/dborm"
"ems.agt/lib/global"
"ems.agt/lib/log"
"ems.agt/lib/mmlp"
"ems.agt/lib/services"
"ems.agt/restagent/config"
tokenConst "ems.agt/src/framework/constants/token"
"github.com/gorilla/mux"
)
const (
//经过测试linux下延时需要大于100ms
TIME_DELAY_AFTER_WRITE = 200
)
type Response struct {
Data []string `json:"data"`
}
type MMLRequest struct {
MML []string `json:"mml"`
}
var (
// MML interface
UriMML = config.DefaultUriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml"
UriMMLDiscard = config.DefaultUriPrefix + "/opeartionManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml"
UriNeOmMml = config.DefaultUriPrefix + "/omManagement/{apiVersion}/mml/{netype}/{neid}"
UriOmMmlExt = config.DefaultUriPrefix + "/{managedType}/{apiVersion}/elementType/OMC/objectType/mml"
UriOmMmlInt = config.DefaultUriPrefix + "/omManagement/{apiVersion}/mml/{neType}/{neId}"
CustomUriMML = config.UriPrefix + "/operationManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/mml"
CustomUriNeOmMml = config.UriPrefix + "/omManagement/{apiVersion}/mml/{netype}/{neid}"
CustomUriOmMmlExt = config.UriPrefix + "/opeartionManagement/{apiVersion}/elementType/OMC/objectType/mml"
CustomUriOmMmlInt = config.UriPrefix + "/omManagement/{apiVersion}/mml/{neType}/{neId}"
)
func PostMMLToNF(w http.ResponseWriter, r *http.Request) {
log.Debug("PostMMLToNF processing... ")
token, err := services.CheckExtValidRequest(w, r)
if err != nil {
log.Error("Request error:", err)
return
}
pack := "mml"
vars := mux.Vars(r)
module := vars["managedType"]
neType := vars["elementTypeValue"]
params := r.URL.Query()
neId := params["ne_id"]
if len(neId) == 0 {
log.Error("NOT FOUND ne_id")
services.ResponseBadRequest400WrongParamValue(w)
return
}
log.Debug("neType:", neType, "neId", neId)
log.Debugf("token:%s, method:%s, managementType:%s dbname:%s, tbname:%s pack:%s",
token, r.Method, module, neType, neId[0], pack)
var buf [8192]byte
var n int
var mmlResult []string
// exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, neType, neId[0], pack)
// if err != nil {
// log.Error("Failed to get permission:", err)
// errMsg := fmt.Sprintf("RetCode = -1 operation failed: do not have the operation permissions")
// log.Error(errMsg)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// //services.ResponseForbidden403NotPermission(w)
// return
// }
// if !exist {
// log.Error("Not permission!")
// errMsg := fmt.Sprintf("RetCode = -1 operation failed: do not have the operation permissions")
// log.Error(errMsg)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// //services.ResponseForbidden403NotPermission(w)
// return
// }
if strings.ToLower(neType) == "omc" {
PostMMLToOMC(w, r)
return
}
neInfo := new(dborm.NeInfo)
neInfo, err = dborm.XormGetNeInfo(neType, neId[0])
if err != nil {
log.Error("dborm.XormGetNeInfo is failed:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
return
}
if neInfo != nil {
switch strings.ToLower(neType) {
case "xxx":
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.Trace("Body:", string(body))
mmlRequest := new(MMLRequest)
_ = json.Unmarshal(body, mmlRequest)
// n, err = conn.Read(buf[0:])
// if err != nil {
// log.Error("Failed to read:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// log.Debug(string(buf[0:n]))
// 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)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// defer conn.Close()
// conn.SetDeadline(time.Now().Add(10 * 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)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
// n, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\n"))
// if err != nil {
// log.Error("Failed to write:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// log.Debug(string(buf[0:n]))
// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
// n, err = conn.Read(buf[0:])
// if err != nil {
// log.Error("Failed to read:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// log.Debug(string(buf[0:n]))
// n, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\n"))
// if err != nil {
// log.Error("Failed to write:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// log.Debug(string(buf[0:n]))
// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
// n, err = conn.Read(buf[0:])
// if err != nil {
// log.Error("Failed to read:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// log.Debug(string(buf[0:n]))
for _, mml := range mmlRequest.MML {
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)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
conn.SetDeadline(time.Now().Add(10 * 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)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
mmlCommand := fmt.Sprintf("%s\n", mml)
log.Debug("mml command:", mmlCommand)
_, err = conn.Write([]byte(mmlCommand))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
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[config.GetYamlConfig().MML.UpfHeaderLength:n-len(neType)-2]), "")
result = re2.ReplaceAllString(result, "")
mmlResult = append(mmlResult, result)
conn.Close()
//mmlResult = append(mmlResult, string(buf[0:n-len(neType)-2]))
// can't read buffer from upf telnet server, so return ok always
// mmlResult = append(mmlResult, "COMMAND OK\n")
}
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)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
// localAddr := conn.LocalAddr()
// remoteAddr := conn.RemoteAddr()
// if localAddr == nil || remoteAddr == nil {
// errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
// log.Error(errMsg)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
conn.SetDeadline(time.Now().Add(10 * time.Second))
_, err = conn.Write([]byte(config.GetYamlConfig().MML.User + "\r\n"))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Debug(string(buf[0:n]))
_, err = conn.Write([]byte(config.GetYamlConfig().MML.Password + "\r\n"))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
// loginStr := fmt.Sprintf("%s\r\n%s\r\n", config.GetYamlConfig().MML.User, config.GetYamlConfig().MML.Password)
// _, err = conn.Write([]byte(loginStr))
// if err != nil {
// log.Error("Failed to write:", err)
// mmlResult = append(mmlResult, err.Error())
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
// time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Trace(string(buf[0 : n-len(neType)-2]))
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.Trace("Body:", string(body))
mmlRequest := new(MMLRequest)
_ = json.Unmarshal(body, mmlRequest)
for _, mml := range mmlRequest.MML {
mmlCommand := fmt.Sprintf("%s\r\n", mml)
log.Debug("mml command:", mmlCommand)
_, err = conn.Write([]byte(mmlCommand))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
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, "")
mmlResult = append(mmlResult, result)
}
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)
mmlResult = append(mmlResult, errMsg)
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
defer conn.Close()
// localAddr := conn.LocalAddr()
// remoteAddr := conn.RemoteAddr()
// if localAddr == nil || remoteAddr == nil {
// errMsg := fmt.Sprintf("connect invalid: localAddr=%v, remoteAddr=%v", localAddr, remoteAddr)
// log.Error(errMsg)
// mmlResult = append(mmlResult, errMsg)
// response := Response{mmlResult}
// services.ResponseWithJson(w, http.StatusOK, response)
// return
// }
conn.SetDeadline(time.Now().Add(10 * 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)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
log.Trace(string(buf[0:n]))
body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen))
if err != nil {
log.Error("Failed to ReadAll:", err)
services.ResponseNotFound404UriNotExist(w, r)
return
}
log.Trace("Body:", string(body))
mmlRequest := new(MMLRequest)
_ = json.Unmarshal(body, mmlRequest)
for _, mml := range mmlRequest.MML {
mmlCommand := fmt.Sprintf("%s\n", mml)
_, err = conn.Write([]byte(mmlCommand))
if err != nil {
log.Error("Failed to write:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
return
}
time.Sleep(time.Millisecond * TIME_DELAY_AFTER_WRITE)
n, err = conn.Read(buf[0:])
if err != nil {
log.Error("Failed to read:", err)
mmlResult = append(mmlResult, err.Error())
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
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, "")
mmlResult = append(mmlResult, result)
}
}
}
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
}
func PostMMLToOMC(w http.ResponseWriter, r *http.Request) {
log.Debug("PostMMLToOMC processing... ")
token, err := services.CheckExtValidRequest(w, r)
if err != nil {
log.Error("Failed to CheckMmlValidRequest:", err)
return
}
params := r.URL.Query()
neId := params["ne_id"]
if len(neId) == 0 {
log.Error("NOT FOUND ne_id ")
services.ResponseBadRequest400WrongParamValue(w)
return
}
neInfo := new(dborm.NeInfo)
neInfo, err = dborm.XormGetNeInfo("OMC", neId[0])
if err != nil {
log.Error("dborm.XormGetNeInfo is failed:", err)
services.ResponseInternalServerError500DatabaseOperationFailed(w)
return
}
log.Trace("neInfo:", neInfo)
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))
hostUri := fmt.Sprintf("http://%s:%s", neInfo.Ip, neInfo.Port)
omcMmlVar := &mmlp.MmlVar{
Version: "16.1.1",
Output: mmlp.DefaultFormatType,
MmlHome: config.GetYamlConfig().MML.MmlHome,
Limit: 50,
User: "",
SessionToken: token, // 旧token
Authorization: r.Header.Get(tokenConst.HEADER_KEY), // 请求Token
HttpUri: hostUri,
UserAgent: config.GetDefaultUserAgent(),
}
mmlRequest := new(MMLRequest)
_ = json.Unmarshal(body, mmlRequest)
var mmlResult []string
mmlLine := strings.Join(mmlRequest.MML, ";")
var mmlCmds []mmlp.MmlCommand
if err = mmlp.ParseMMLCommand(mmlLine, &mmlCmds); err != nil {
response := fmt.Sprintf("parse command error: %v\n", err)
mmlResult = append(mmlResult, response)
}
for _, mmlCmd := range mmlCmds {
output, err := mmlp.TransMml2HttpReq(omcMmlVar, &mmlCmd)
if err != nil {
response := fmt.Sprintf("translate MML command error: %v]\n", err)
mmlResult = append(mmlResult, response)
}
mmlResult = append(mmlResult, string(*output))
}
response := Response{mmlResult}
services.ResponseWithJson(w, http.StatusOK, response)
}