1044 lines
30 KiB
Go
1044 lines
30 KiB
Go
package mmlp
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"math"
|
|
"net/http"
|
|
"regexp"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"ems.agt/lib/dborm"
|
|
"ems.agt/lib/global"
|
|
"ems.agt/lib/log"
|
|
"ems.agt/lib/run"
|
|
"github.com/go-resty/resty/v2"
|
|
)
|
|
|
|
type Param struct {
|
|
Name string `json:"name"`
|
|
Value string `json:"value"`
|
|
}
|
|
|
|
type MmlCommand struct {
|
|
Operation string `json:"operation"`
|
|
Object string `json:"object"`
|
|
Params []Param `json:"params"`
|
|
PaList []string `json:"paList"`
|
|
AaList []string `json:"aaList"`
|
|
AaMap map[string]interface{} `json:"aaMap"`
|
|
NaMap map[string]interface{} `json:"naMap"`
|
|
AaUri []string `json:"aaUri"`
|
|
AaLoc []string `json:"aaLoc"` // for loc parameter
|
|
}
|
|
|
|
type MmlVar struct {
|
|
Version string `json:"version"`
|
|
Output string `json:"output"`
|
|
MmlHome string `json:"mmlHome"`
|
|
Limit int `json:"limit"`
|
|
User string `json:"user"`
|
|
SessionToken string `josn:"sessionToken"`
|
|
HttpUri string `json:"httpUri"`
|
|
UserAgent string `json:"userAgent"`
|
|
}
|
|
|
|
// func init() {
|
|
// OmcMmlVar = &MmlVar{
|
|
// Version: "16.1.1",
|
|
// Output: DefaultFormatType,
|
|
// Limit: 50,
|
|
// }
|
|
// }
|
|
|
|
// func SetOmcMmlVarOutput(output string) {
|
|
// OmcMmlVar.Output = output
|
|
// }
|
|
|
|
// func SetOmcMmlVarLimit(limit int) {
|
|
// OmcMmlVar.Limit = limit
|
|
// }
|
|
|
|
func splitByColon(str string) []string {
|
|
return splitBy(str, ':')
|
|
}
|
|
|
|
func splitByComma(str string) []string {
|
|
return splitBy(str, ',')
|
|
}
|
|
|
|
func splitBy(str string, sep rune) []string {
|
|
var result []string
|
|
var stack []string
|
|
var current []rune
|
|
var quotes, apoFlag bool = false, false
|
|
|
|
for _, c := range str {
|
|
if c == '{' || c == '[' || (c == '\'' && apoFlag == false) || (c == '"' && quotes == false) { // "'"
|
|
apoFlag = true
|
|
quotes = true
|
|
stack = append(stack, string(c))
|
|
} else if c == '}' || c == ']' || (c == '\'' && apoFlag == true) || (c == '"' && quotes == true) {
|
|
apoFlag = false
|
|
quotes = false
|
|
if len(stack) > 0 {
|
|
stack = stack[:len(stack)-1]
|
|
}
|
|
}
|
|
|
|
if c == sep && len(stack) == 0 {
|
|
result = append(result, string(current))
|
|
current = []rune{}
|
|
} else {
|
|
current = append(current, c)
|
|
}
|
|
}
|
|
|
|
result = append(result, string(current))
|
|
return result
|
|
}
|
|
|
|
func ParseMMLCommand(mmlStr string, mmlComms *[]MmlCommand) error {
|
|
log.Info("ParseMMLCommand processing ...")
|
|
log.Debug("mmlStr: ", mmlStr)
|
|
|
|
mc := new(MmlCommand)
|
|
reg := regexp.MustCompile(`\s*;\s*`)
|
|
mmls := reg.Split(mmlStr, -1)
|
|
for _, mml := range mmls {
|
|
log.Trace("mml:", mml)
|
|
if len(mml) == 0 {
|
|
continue
|
|
}
|
|
//reg := regexp.MustCompile(`\s*:\s*`)
|
|
//ms := reg.Split(mml, -1)
|
|
ms := splitByColon(mml)
|
|
if len(ms) < 1 || len(ms) > 2 {
|
|
err := global.ErrMmlInvalidCommandFormat
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
if len(ms) == 2 {
|
|
cmd := strings.Trim(ms[0], " ")
|
|
reg = regexp.MustCompile(`\s+`)
|
|
cs := reg.Split(cmd, -1)
|
|
//cs := strings.Split(cmd, " ")
|
|
if len(cs) == 2 {
|
|
mc.Operation = cs[0]
|
|
mc.Object = cs[1]
|
|
} else {
|
|
err := global.ErrMmlInvalidCommandFormat
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
//reg = regexp.MustCompile(`\s*,\s*`)
|
|
//reg = regexp.MustCompile(`(?U)(?<!\{[^{}]*),(?![^{}]*\})|(?<!\"[^\"]*),(?![^\"]*\")|(?<!\[[^\[\]]*),(?![^\[\]]*\])`)
|
|
//reg = regexp.MustCompile(`,[^'"\(\)]+`)
|
|
//params := reg.Split(ms[1], -1)
|
|
params := splitByComma(strings.Trim(ms[1], " "))
|
|
//params := strings.Split(ms[1], ",")
|
|
for _, p := range params {
|
|
log.Trace("p:", p)
|
|
if p == "" {
|
|
continue
|
|
}
|
|
mc.PaList = append(mc.PaList, p)
|
|
reg = regexp.MustCompile(`\s*=\s*`)
|
|
pvs := reg.Split(p, -1)
|
|
log.Trace("pvs:", pvs)
|
|
if len(pvs) == 2 {
|
|
mc.Params = append(mc.Params, Param{Name: pvs[0], Value: pvs[1]})
|
|
} else {
|
|
err := global.ErrMmlInvalidCommandFormat
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
}
|
|
} else if len(ms) == 1 {
|
|
cmd := ms[0]
|
|
reg = regexp.MustCompile(`\s+`)
|
|
cs := reg.Split(cmd, -1)
|
|
//cs := strings.Split(cmd, " ")
|
|
if len(cs) == 2 {
|
|
mc.Operation = cs[0]
|
|
mc.Object = cs[1]
|
|
} else {
|
|
err := global.ErrMmlInvalidCommandFormat
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
} else {
|
|
err := global.ErrMmlInvalidCommandFormat
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
err := ParseMMLAlias(mc)
|
|
if err != nil {
|
|
err := global.ErrMmlInvalidCommandFormat
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
*mmlComms = append(*mmlComms, *mc)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func ParseMMLAlias(mml *MmlCommand) error {
|
|
where := fmt.Sprintf("operation='%s' AND object='%s'", mml.Operation, mml.Object)
|
|
mc, err := dborm.XormGetMmlCommand("mml_command", where)
|
|
if err != nil {
|
|
log.Error("Failed to XormGetMmlCommand: ", err)
|
|
return err
|
|
}
|
|
if mc == nil {
|
|
err := errors.New("Not found mml map")
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
log.Debug("mml command: ", mc)
|
|
aaMap := make(map[string]interface{})
|
|
naMap := make(map[string]interface{})
|
|
for _, pn := range mml.Params {
|
|
log.Trace("pn: ", pn)
|
|
for _, param := range mc.ParamJson {
|
|
log.Trace("param: ", param)
|
|
var pv string
|
|
if pn.Name == param.Name {
|
|
if param.Apostr == "true" {
|
|
pv = fmt.Sprintf("'%v'", pn.Value)
|
|
} else {
|
|
pv = fmt.Sprintf("%v", pn.Value)
|
|
}
|
|
var aa, av string
|
|
|
|
if param.Alias != "" {
|
|
aa = fmt.Sprintf("%s=%v", param.Alias, pv)
|
|
av = fmt.Sprintf("%v", pv)
|
|
switch param.Type {
|
|
case "int":
|
|
aaMap[param.Alias] = pn.Value
|
|
naMap[param.Alias] = pn.Value
|
|
default:
|
|
aaMap[param.Alias] = pv
|
|
naMap[param.Alias] = fmt.Sprintf("%v", pn.Value)
|
|
}
|
|
} else {
|
|
aa = fmt.Sprintf("%s=%v", param.Name, pv)
|
|
av = fmt.Sprintf("%v", pv)
|
|
switch param.Type {
|
|
case "int":
|
|
aaMap[param.Name] = pn.Value
|
|
naMap[param.Name] = pn.Value
|
|
default:
|
|
aaMap[param.Name] = pv
|
|
naMap[param.Name] = fmt.Sprintf("%v", pn.Value)
|
|
}
|
|
}
|
|
if param.Loc == "" || param.Loc == "true" {
|
|
mml.AaLoc = append(mml.AaLoc, aa)
|
|
mml.AaUri = append(mml.AaUri, av)
|
|
}
|
|
//mml.AaMap = append(mml.AaMap, aaMap)
|
|
mml.AaList = append(mml.AaList, aa)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
mml.AaMap = aaMap
|
|
mml.NaMap = naMap
|
|
log.Trace("mml.AaMap: ", mml.AaMap)
|
|
log.Trace("mml.NaMap: ", mml.NaMap)
|
|
log.Trace("mml.AaList: ", mml.AaList)
|
|
|
|
return nil
|
|
}
|
|
|
|
func ParseMMLParams(mmlComms *[]MmlCommand) error {
|
|
for _, mml := range *mmlComms {
|
|
where := fmt.Sprintf("operation='%s' AND object='%s'", mml.Operation, mml.Object)
|
|
mc, err := dborm.XormGetMmlCommand("mml_command", where)
|
|
if err != nil {
|
|
log.Error("Failed to XormGetMmlCommand: ", err)
|
|
return err
|
|
}
|
|
if mc == nil {
|
|
err := errors.New("Not found mml map")
|
|
log.Error(err)
|
|
return err
|
|
}
|
|
log.Debug("mml command: ", mc)
|
|
for _, pn := range mml.Params {
|
|
log.Trace("pn: ", pn)
|
|
for _, param := range mc.ParamJson {
|
|
log.Trace("param: ", param)
|
|
var pv string
|
|
if pn.Name == param.Name {
|
|
if param.Apostr == "true" {
|
|
pv = fmt.Sprintf("'%v'", pn.Value)
|
|
} else {
|
|
pv = fmt.Sprintf("%v", pn.Value)
|
|
}
|
|
var aa string
|
|
aaMap := make(map[string]interface{})
|
|
if param.Alias != "" {
|
|
aa = fmt.Sprintf("%s=%v", param.Alias, pv)
|
|
switch param.Type {
|
|
case "int":
|
|
aaMap[param.Alias] = pn.Value
|
|
case "string":
|
|
aaMap[param.Alias] = pv
|
|
}
|
|
} else {
|
|
aa = fmt.Sprintf("%s=%v", param.Name, pv)
|
|
switch param.Type {
|
|
case "int":
|
|
aaMap[param.Name] = pn.Value
|
|
case "string":
|
|
aaMap[param.Name] = pv
|
|
}
|
|
}
|
|
//mml.AaMap = append(mml.AaMap, aaMap)
|
|
mml.AaList = append(mml.AaList, aa)
|
|
break
|
|
}
|
|
}
|
|
}
|
|
log.Trace("mml.AaMap: ", mml.AaMap)
|
|
log.Trace("mml.AaList: ", mml.AaList)
|
|
*mmlComms = append(*mmlComms, mml)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func parseRequestUri(httpUri string, mmlMap *dborm.MmlHttpMap, mml *MmlCommand) string {
|
|
requestURI := fmt.Sprintf("%s%s", httpUri, mmlMap.URI)
|
|
if mmlMap.ExtUri != "" && len(mml.AaUri) > 0 {
|
|
extUri := strings.Join(mml.AaUri, "/")
|
|
requestURI = requestURI + fmt.Sprintf(mmlMap.ExtUri, extUri)
|
|
}
|
|
if mmlMap.Params != "" {
|
|
params := strings.Join(mml.AaLoc, "+and+")
|
|
params = strings.ReplaceAll(params, " ", "+") // replace " " to "+"
|
|
log.Trace("params:", params)
|
|
if mmlMap.ParamTag == "SQL" && strings.TrimSpace(params) != "" {
|
|
params = "+where+" + params
|
|
}
|
|
requestURI = fmt.Sprintf("%s%s%s", requestURI, mmlMap.Params, params)
|
|
}
|
|
return requestURI
|
|
}
|
|
|
|
func DeploymentLicense(mml *MmlCommand, omcMmlVar *MmlVar, outputJson *dborm.MmlOutput) *[]byte {
|
|
var output []byte
|
|
log.Debug("mml:", mml)
|
|
var srcNeType, srcNeid, dstNeType, dstNeId, value string
|
|
for _, Param := range mml.Params {
|
|
switch Param.Name {
|
|
case "srcnetype":
|
|
srcNeType = Param.Value
|
|
case "srcneid":
|
|
srcNeid = Param.Value
|
|
case "dstnetype":
|
|
dstNeType = Param.Value
|
|
case "dstneid":
|
|
dstNeId = Param.Value
|
|
case "number":
|
|
value = Param.Value
|
|
}
|
|
}
|
|
intValue, _ := strconv.Atoi(value)
|
|
log.Debugf("srcNeType:%s, srcNeid:%s dstNeType:%s dstNeId:%s intValue:%d", srcNeType, srcNeid, dstNeType, dstNeId, intValue)
|
|
a1, err := dborm.XormAdjustmentNeLicense(srcNeType, srcNeid, intValue)
|
|
if err != nil {
|
|
log.Error("Failed to Put:", err)
|
|
}
|
|
|
|
a2, err := dborm.XormAdjustmentNeLicense(dstNeType, dstNeId, -intValue)
|
|
if err != nil {
|
|
log.Error("Failed to Put:", err)
|
|
output = *ParseErrorOutput(err)
|
|
} else {
|
|
//response := &resty.Response{StatusCode: http.StatusOK}
|
|
//output = ParseOutputResponse(omcMmlVar, outputJson, response.)
|
|
str := fmt.Sprintf("RetCode = 0 operation succeeded\n\nAffected rows = %d \n\n", a1+a2)
|
|
output = []byte(str)
|
|
}
|
|
|
|
return &output
|
|
}
|
|
|
|
func AdjustmentLicense(mml *MmlCommand, omcMmlVar *MmlVar, outputJson *dborm.MmlOutput) *[]byte {
|
|
var output []byte
|
|
log.Debug("mml:", mml)
|
|
var neType, neid, number string
|
|
for _, Param := range mml.Params {
|
|
switch Param.Name {
|
|
case "netype":
|
|
neType = Param.Value
|
|
case "neid":
|
|
neid = Param.Value
|
|
case "number":
|
|
number = Param.Value
|
|
}
|
|
}
|
|
intValue, _ := strconv.Atoi(number)
|
|
log.Debugf("neType:%s, neid:%s intValue:%d", neType, neid, intValue)
|
|
affected, err := dborm.XormAdjustmentNeLicense(neType, neid, intValue)
|
|
if err != nil {
|
|
log.Error("Failed to XormAdjustmentNeLicense:", err)
|
|
output = *ParseErrorOutput(err)
|
|
} else {
|
|
str := fmt.Sprintf("RetCode = 0 operation succeeded\n\nAffected rows = %d \n\n", affected)
|
|
output = []byte(str)
|
|
}
|
|
|
|
return &output
|
|
}
|
|
|
|
func InstallLicense(mml *MmlCommand, omcMmlVar *MmlVar, outputJson *dborm.MmlOutput) *[]byte {
|
|
var output []byte
|
|
log.Debug("mml:", mml)
|
|
var neType, neid, number string
|
|
for _, Param := range mml.Params {
|
|
switch Param.Name {
|
|
case "netype":
|
|
neType = Param.Value
|
|
case "neid":
|
|
neid = Param.Value
|
|
case "number":
|
|
number = Param.Value
|
|
}
|
|
}
|
|
intValue, _ := strconv.Atoi(number)
|
|
log.Debugf("neType:%s, neid:%s intValue:%d", neType, neid, intValue)
|
|
affected, err := dborm.XormUpdateNeLicense(neType, neid, intValue)
|
|
if err != nil {
|
|
log.Error("Failed to XormUpdateNeLicense:", err)
|
|
output = *ParseErrorOutput(err)
|
|
} else {
|
|
str := fmt.Sprintf("RetCode = 0 operation succeeded\n\nAffected rows = %d \n\n", affected)
|
|
output = []byte(str)
|
|
}
|
|
|
|
return &output
|
|
}
|
|
|
|
func RunShellCommand(mml *MmlCommand, omcMmlVar *MmlVar, outputJson *dborm.MmlOutput) *[]byte {
|
|
var output []byte
|
|
log.Debug("mml:", mml)
|
|
var command string
|
|
for _, Param := range mml.Params {
|
|
switch Param.Name {
|
|
case "cmd":
|
|
command = Param.Value
|
|
default:
|
|
}
|
|
}
|
|
out, err := run.ExecCmd(command, omcMmlVar.MmlHome)
|
|
//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)
|
|
str := fmt.Sprintf("Command: %s output:\n\n%v\n", command, string(out))
|
|
//output = *ParseErrorOutput(err)
|
|
output = []byte(str)
|
|
//return &output
|
|
} else {
|
|
str := fmt.Sprintf("Command: %s output:\n\n%v\n", command, string(out))
|
|
output = []byte(str)
|
|
}
|
|
|
|
return &output
|
|
}
|
|
|
|
func TransMml2HttpReq(omcMmlVar *MmlVar, mml *MmlCommand) (*[]byte, error) {
|
|
log.Info("TransMml2HttpReq processing ...")
|
|
log.Debug("mml: ", mml)
|
|
|
|
where := fmt.Sprintf("operation='%s' AND object='%s'", mml.Operation, mml.Object)
|
|
mmlMap, err := dborm.XormGetMmlHttpMap("mml_http_map", where)
|
|
if err != nil {
|
|
log.Error("Failed to XormGetMmlHttpMap: ", err)
|
|
return ParseErrorOutput(err), err
|
|
}
|
|
if mmlMap == nil {
|
|
err := errors.New("Not found mml map")
|
|
log.Error(err)
|
|
return ParseErrorOutput(err), err
|
|
}
|
|
log.Trace("mmlMap: ", mmlMap)
|
|
if mmlMap.Output == "" {
|
|
mmlMap.Output = "{}"
|
|
}
|
|
outputJson := new(dborm.MmlOutput)
|
|
err = json.Unmarshal([]byte(mmlMap.Output), outputJson)
|
|
if err != nil {
|
|
log.Error("Failed to Unmarshal:", err)
|
|
return ParseErrorOutput(err), err
|
|
}
|
|
log.Trace("outputJson: ", outputJson)
|
|
inputJson := new(dborm.MmlInput)
|
|
log.Trace("mmlMap.Input: ", mmlMap.Input)
|
|
if mmlMap.Input == "" {
|
|
mmlMap.Input = "{}"
|
|
}
|
|
err = json.Unmarshal([]byte(mmlMap.Input), inputJson)
|
|
if err != nil {
|
|
log.Error("Failed to Unmarshal:", err)
|
|
return ParseErrorOutput(err), err
|
|
}
|
|
log.Trace("inputJson: ", inputJson)
|
|
|
|
var requestURI string
|
|
var output *[]byte
|
|
client := resty.New()
|
|
switch strings.ToLower(mmlMap.Method) {
|
|
case "get":
|
|
requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
|
|
log.Debugf("method: Get requestURI: %s", requestURI)
|
|
response, err := client.R().
|
|
EnableTrace().
|
|
SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
|
|
SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
|
|
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
|
Get(requestURI)
|
|
if err != nil {
|
|
log.Error("Failed to Get:", err)
|
|
output = ParseErrorOutput(err)
|
|
} else {
|
|
output = ParseOutputResponse(omcMmlVar, outputJson, response)
|
|
}
|
|
case "post":
|
|
requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
|
|
body := ParseInputBody(inputJson, mml)
|
|
log.Debugf("method: Post requestURI: %s", requestURI)
|
|
response, err := client.R().
|
|
EnableTrace().
|
|
SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
|
|
SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
|
|
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
|
SetBody(*body).
|
|
Post(requestURI)
|
|
if err != nil {
|
|
log.Error("Failed to Post:", err)
|
|
output = ParseErrorOutput(err)
|
|
} else {
|
|
output = ParseOutputResponse(omcMmlVar, outputJson, response)
|
|
}
|
|
case "put":
|
|
switch inputJson.CallFunc {
|
|
case "DeploymentLicense":
|
|
output = DeploymentLicense(mml, omcMmlVar, outputJson)
|
|
return output, nil
|
|
case "AdjustmentLicense":
|
|
output = AdjustmentLicense(mml, omcMmlVar, outputJson)
|
|
return output, nil
|
|
case "InstallLicense":
|
|
output = InstallLicense(mml, omcMmlVar, outputJson)
|
|
return output, nil
|
|
case "RunShellCommand":
|
|
output = RunShellCommand(mml, omcMmlVar, outputJson)
|
|
return output, nil
|
|
default:
|
|
}
|
|
|
|
requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
|
|
log.Debugf("method: Put requestURI: %s", requestURI)
|
|
body := ParseInputBody(inputJson, mml)
|
|
response, err := client.R().
|
|
EnableTrace().
|
|
SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
|
|
SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
|
|
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
|
SetBody(*body).
|
|
Put(requestURI)
|
|
if err != nil {
|
|
log.Error("Failed to Put:", err)
|
|
output = ParseErrorOutput(err)
|
|
} else {
|
|
output = ParseOutputResponse(omcMmlVar, outputJson, response)
|
|
}
|
|
case "delete":
|
|
requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
|
|
log.Debugf("method: Delete requestURI: %s", requestURI)
|
|
response, err := client.R().
|
|
EnableTrace().
|
|
SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
|
|
SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
|
|
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
|
Delete(requestURI)
|
|
if err != nil {
|
|
log.Error("Failed to Delete:", err)
|
|
output = ParseErrorOutput(err)
|
|
} else {
|
|
output = ParseOutputResponse(omcMmlVar, outputJson, response)
|
|
}
|
|
case "patch":
|
|
requestURI = parseRequestUri(omcMmlVar.HttpUri, mmlMap, mml)
|
|
log.Debugf("method: patch requestURI: %s", requestURI)
|
|
response, err := client.R().
|
|
EnableTrace().
|
|
SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}).
|
|
SetHeaders(map[string]string{"User-Agent": omcMmlVar.UserAgent}).
|
|
SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}).
|
|
Patch(requestURI)
|
|
if err != nil {
|
|
log.Error("Failed to Patch:", err)
|
|
output = ParseErrorOutput(err)
|
|
} else {
|
|
output = ParseOutputResponse(omcMmlVar, outputJson, response)
|
|
}
|
|
default:
|
|
err := errors.New("not found mml command")
|
|
log.Error(err)
|
|
output = ParseErrorOutput(err)
|
|
}
|
|
return output, nil
|
|
}
|
|
|
|
const (
|
|
MaxMmlOutputBufferSize = 1000000
|
|
FormatTypeJson = "json"
|
|
FormatTypeTable = "table"
|
|
DefaultFormatType = FormatTypeTable
|
|
)
|
|
|
|
const (
|
|
RetCodeSucceeded = 0
|
|
RetCodeFailed = 0
|
|
)
|
|
|
|
func ParseInputBody(inputJson *dborm.MmlInput, mml *MmlCommand) *[]byte {
|
|
inputBody := make(map[string]interface{})
|
|
log.Trace("mml.NaMap:", mml.NaMap)
|
|
log.Trace("mml.AaMap:", mml.AaMap)
|
|
if strings.ToLower(inputJson.BodyFmt) == "putdb" {
|
|
for _, icol := range inputJson.Cols {
|
|
log.Trace("icol:", icol)
|
|
mml.NaMap[icol.Name] = icol.Value
|
|
}
|
|
inputBody[inputJson.BodyKey] = mml.NaMap
|
|
} else {
|
|
inputParams := make([]map[string]interface{}, 0)
|
|
inputParams = append(inputParams, mml.NaMap)
|
|
inputBody[inputJson.BodyKey] = inputParams
|
|
}
|
|
|
|
body, err := json.Marshal(inputBody)
|
|
if err != nil {
|
|
log.Error("Failed to marshal:", err)
|
|
}
|
|
|
|
log.Trace("inputBody:", inputBody)
|
|
log.Trace("body:", string(body))
|
|
return &body
|
|
}
|
|
|
|
func ParseOutputResponse(omcMmlVar *MmlVar, outputJson *dborm.MmlOutput, response *resty.Response) *[]byte {
|
|
var output []byte
|
|
var str bytes.Buffer
|
|
|
|
switch response.StatusCode() {
|
|
case http.StatusOK, http.StatusCreated, http.StatusNoContent, http.StatusAccepted:
|
|
if omcMmlVar.Output == FormatTypeJson {
|
|
code := fmt.Sprintf("StatusCode = %d status %s\n\n", response.StatusCode(), response.Status())
|
|
title := formatTitle(outputJson.Title)
|
|
|
|
json.Indent(&str, response.Body(), "", " ")
|
|
log.Trace(str.String())
|
|
|
|
output = global.BytesCombine1([]byte(code), []byte(title), str.Bytes(), []byte("\n"))
|
|
} else {
|
|
log.Trace("Body:", string(response.Body()))
|
|
mapDatas := make(map[string]interface{}, 0)
|
|
|
|
err := json.Unmarshal(response.Body(), &mapDatas)
|
|
if err != nil {
|
|
log.Error("Failed to json.Unmarshal:", err)
|
|
//output = *ParseErrorOutput(err)
|
|
output = *ParseErrorOutput(string(response.Body()))
|
|
return &output
|
|
}
|
|
log.Trace("mapDatas:", mapDatas)
|
|
switch strings.ToLower(outputJson.RetFmt) {
|
|
case "getdb":
|
|
if len(mapDatas) > 0 {
|
|
var data interface{}
|
|
for _, data = range mapDatas {
|
|
log.Trace("data:", data)
|
|
break
|
|
}
|
|
if len(data.([]interface{})) > 0 {
|
|
table := (data.([]interface{}))[0]
|
|
log.Trace("table:", table)
|
|
|
|
code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
|
|
title := formatTitle(outputJson.Title)
|
|
fmtResults := ParseTableOutput(outputJson, table)
|
|
output = global.BytesCombine1([]byte(code), []byte(title), []byte(fmtResults))
|
|
}
|
|
}
|
|
case "deletedb":
|
|
var data interface{}
|
|
for _, data = range mapDatas {
|
|
log.Trace("data:", data)
|
|
break
|
|
}
|
|
|
|
if len(data.(map[string]interface{})) > 0 {
|
|
table := data.(map[string]interface{})
|
|
code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
|
|
fmtResults := ParseDBOperOutput(outputJson, table)
|
|
output = global.BytesCombine1([]byte(code), []byte(fmtResults))
|
|
}
|
|
case "postdb":
|
|
var data interface{}
|
|
for _, data = range mapDatas {
|
|
log.Trace("data:", data)
|
|
break
|
|
}
|
|
|
|
if len(data.(map[string]interface{})) > 0 {
|
|
table := data.(map[string]interface{})
|
|
code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
|
|
fmtResults := ParseDBOperOutput(outputJson, table)
|
|
output = global.BytesCombine1([]byte(code), []byte(fmtResults))
|
|
}
|
|
case "putdb":
|
|
var data interface{}
|
|
for _, data = range mapDatas {
|
|
log.Trace("data:", data)
|
|
break
|
|
}
|
|
if len(data.(map[string]interface{})) > 0 {
|
|
table := data.(map[string]interface{})
|
|
code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
|
|
fmtResults := ParseDBOperOutput(outputJson, table)
|
|
output = global.BytesCombine1([]byte(code), []byte(fmtResults))
|
|
}
|
|
case "getnf":
|
|
if len(mapDatas) > 0 {
|
|
var data interface{}
|
|
for _, data = range mapDatas {
|
|
log.Trace("data:", data)
|
|
break
|
|
}
|
|
if len(data.([]interface{})) > 0 {
|
|
//table := (data.([]interface{}))[0]
|
|
//log.Trace("table:", table)
|
|
|
|
code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
|
|
title := formatTitle(outputJson.Title)
|
|
fmtResults := ParseNFTableOutput(outputJson, data)
|
|
output = global.BytesCombine1([]byte(code), []byte(title), []byte(fmtResults))
|
|
}
|
|
}
|
|
default:
|
|
code := fmt.Sprintf(outputJson.RetMsg, RetCodeSucceeded)
|
|
output = global.BytesCombine1([]byte(code))
|
|
}
|
|
|
|
}
|
|
default:
|
|
if omcMmlVar.Output == FormatTypeJson {
|
|
code := fmt.Sprintf("StatusCode = %d status %s\n\n", response.StatusCode(), response.Status())
|
|
//title := formatTitle("Network Element Information")
|
|
|
|
json.Indent(&str, response.Body(), "", " ")
|
|
log.Trace(str.String())
|
|
|
|
output = global.BytesCombine1([]byte(code), str.Bytes(), []byte("\n"))
|
|
} else {
|
|
log.Trace("Body:", string(response.Body()))
|
|
mapResults := make(map[string]interface{}, 0)
|
|
|
|
err := json.Unmarshal(response.Body(), &mapResults)
|
|
if err != nil {
|
|
log.Error("Failed to json.Unmarshal:", err)
|
|
output = *ParseErrorOutput(string(response.Body()))
|
|
} else {
|
|
log.Trace("mapResults:", mapResults)
|
|
errResult := mapResults["error"]
|
|
log.Trace("errResult:", errResult)
|
|
if len(errResult.(map[string]interface{})) > 0 {
|
|
errCode, _ := strconv.Atoi(fmt.Sprintf("%v", errResult.(map[string]interface{})["errorCode"]))
|
|
errorInfo := errResult.(map[string]interface{})["errorInfo"]
|
|
output = []byte(fmt.Sprintf(outputJson.ErrMsg, errCode, errorInfo))
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return &output
|
|
}
|
|
|
|
func ParseDBOperOutput(outputJson *dborm.MmlOutput, cols any) string {
|
|
var colOutput []dborm.ColOutput = outputJson.Cols
|
|
var value, retFmtCols string
|
|
if len(cols.(map[string]interface{})) > 0 {
|
|
if len(colOutput) > 0 {
|
|
coln := colOutput[0].Name
|
|
value = fmt.Sprintf("%v", cols.(map[string]interface{})[coln])
|
|
log.Tracef("coln:%s value:%s", coln, value)
|
|
retFmtCols = colOutput[0].Display + " = " + value + "\n\n"
|
|
}
|
|
}
|
|
|
|
return retFmtCols
|
|
}
|
|
|
|
func ParseNFTableOutput(outputJson *dborm.MmlOutput, cols any) string {
|
|
var colOutput []dborm.ColOutput
|
|
var fmtColName string
|
|
var colName []string
|
|
var spaceNum int = 1
|
|
var alignmentM, alignmentSN, alignmentSV string = "Left", "Right", "Left"
|
|
|
|
if outputJson.SepSpaceNum != 0 {
|
|
spaceNum = outputJson.SepSpaceNum
|
|
}
|
|
if outputJson.AlignmentM != "" {
|
|
alignmentM = outputJson.AlignmentM
|
|
}
|
|
if outputJson.AlignmentSN != "" {
|
|
alignmentSN = outputJson.AlignmentSN
|
|
}
|
|
if outputJson.AlignmentSV != "" {
|
|
alignmentSV = outputJson.AlignmentSV
|
|
}
|
|
|
|
maxLength := math.MinInt64
|
|
for _, coln := range outputJson.Cols {
|
|
log.Trace("coln:", coln)
|
|
|
|
if len(coln.Display) > maxLength {
|
|
maxLength = len(coln.Display)
|
|
}
|
|
if coln.Length < len(coln.Display) {
|
|
coln.Length = len(coln.Display)
|
|
}
|
|
|
|
colName = append(colName, ParseAlignmentOutput(coln.Length, alignmentM, coln.Display))
|
|
colOutput = append(colOutput, coln)
|
|
}
|
|
fmtColName = formatLineBySpace(&colName, spaceNum)
|
|
log.Trace("fmtColName:", fmtColName)
|
|
|
|
var retFmtCols string
|
|
var fmtColValues []string
|
|
var numberResult int
|
|
// for _, colnvs := range cols.([]interface{}) {
|
|
// log.Trace("colnvs:", colnvs)
|
|
// if colnvs == nil {
|
|
// break
|
|
// }
|
|
numberResult = len(cols.([]interface{}))
|
|
|
|
if numberResult == 1 && outputJson.SingleList == true {
|
|
colnv := cols.([]interface{})[0]
|
|
log.Trace("colnv:", colnv)
|
|
|
|
var fmtNV []string
|
|
for _, coln := range colOutput {
|
|
fmtName := ParseAlignmentOutput(maxLength, alignmentSN, coln.Display)
|
|
log.Tracef("alignmentSN:%s fmtName:%s", alignmentSN, fmtName)
|
|
value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
|
|
fmtValue := ParseAlignmentOutput(coln.Length, alignmentSV, value)
|
|
fmtNV = append(fmtNV, fmtName+": "+fmtValue)
|
|
}
|
|
|
|
fmtResults := strings.Join(fmtNV, "\n")
|
|
log.Tracef("fmtResults:\n%s", fmtResults)
|
|
fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
|
|
retFmtCols = fmtResults + "\n\n" + fmtEnd
|
|
log.Tracef("retFmtCols:\n%s", retFmtCols)
|
|
return retFmtCols
|
|
} else {
|
|
for i := 0; i < numberResult; i++ {
|
|
colnv := cols.([]interface{})[i]
|
|
log.Trace("colnv:", colnv)
|
|
var colValues []string
|
|
var newVal []string
|
|
for _, coln := range colOutput {
|
|
value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
|
|
if len(coln.Alias) != 0 {
|
|
enumVal, _ := strconv.Atoi(value)
|
|
value = parseEnumAlias(&(coln.Alias), enumVal)
|
|
}
|
|
newVal = append(newVal, ParseAlignmentOutput(coln.Length, alignmentM, value))
|
|
}
|
|
colValues = append(colValues, formatLineBySpace(&newVal, spaceNum))
|
|
log.Trace("colValues:", colValues)
|
|
fmtColValues = append(fmtColValues, strings.Join(colValues, "\n"))
|
|
log.Trace("fmtColValues:", fmtColValues)
|
|
}
|
|
fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
|
|
retFmtCols = fmtColName + "\n\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
|
|
log.Tracef("retFmtCols:\n%s", retFmtCols)
|
|
return retFmtCols
|
|
}
|
|
}
|
|
|
|
func ParseTableOutput(outputJson *dborm.MmlOutput, cols any) string {
|
|
var colOutput []dborm.ColOutput
|
|
var fmtColName string
|
|
var colName []string
|
|
var spaceNum int = 1
|
|
var alignmentM, alignmentSN, alignmentSV string = "Left", "Right", "Left"
|
|
|
|
if outputJson.SepSpaceNum != 0 {
|
|
spaceNum = outputJson.SepSpaceNum
|
|
}
|
|
if outputJson.AlignmentM != "" {
|
|
alignmentM = outputJson.AlignmentM
|
|
}
|
|
if outputJson.AlignmentSN != "" {
|
|
alignmentSN = outputJson.AlignmentSN
|
|
}
|
|
if outputJson.AlignmentSV != "" {
|
|
alignmentSV = outputJson.AlignmentSV
|
|
}
|
|
|
|
maxLength := math.MinInt64
|
|
for _, coln := range outputJson.Cols {
|
|
log.Trace("coln:", coln)
|
|
|
|
if len(coln.Display) > maxLength {
|
|
maxLength = len(coln.Display)
|
|
}
|
|
if coln.Length < len(coln.Display) {
|
|
coln.Length = len(coln.Display)
|
|
}
|
|
|
|
colName = append(colName, ParseAlignmentOutput(coln.Length, alignmentM, coln.Display))
|
|
colOutput = append(colOutput, coln)
|
|
}
|
|
fmtColName = formatLineBySpace(&colName, spaceNum)
|
|
log.Trace("fmtColName:", fmtColName)
|
|
|
|
var retFmtCols string
|
|
var fmtColValues []string
|
|
var numberResult int
|
|
for _, colnvs := range cols.(map[string]interface{}) {
|
|
log.Trace("colnvs:", colnvs)
|
|
if colnvs == nil {
|
|
break
|
|
}
|
|
numberResult = len(colnvs.([]interface{}))
|
|
|
|
if numberResult == 1 && outputJson.SingleList == true {
|
|
colnv := colnvs.([]interface{})[0]
|
|
log.Trace("colnv:", colnv)
|
|
|
|
var fmtNV []string
|
|
for _, coln := range colOutput {
|
|
fmtName := ParseAlignmentOutput(maxLength, alignmentSN, coln.Display)
|
|
log.Tracef("alignmentSN:%s fmtName:%s", alignmentSN, fmtName)
|
|
value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
|
|
fmtValue := ParseAlignmentOutput(coln.Length, alignmentSV, value)
|
|
fmtNV = append(fmtNV, fmtName+": "+fmtValue)
|
|
}
|
|
|
|
fmtResults := strings.Join(fmtNV, "\n")
|
|
log.Tracef("fmtResults:\n%s", fmtResults)
|
|
fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
|
|
retFmtCols = fmtResults + "\n\n" + fmtEnd
|
|
log.Tracef("retFmtCols:\n%s", retFmtCols)
|
|
return retFmtCols
|
|
} else {
|
|
for i := 0; i < numberResult; i++ {
|
|
colnv := colnvs.([]interface{})[i]
|
|
log.Trace("colnv:", colnv)
|
|
var colValues []string
|
|
var newVal []string
|
|
for _, coln := range colOutput {
|
|
value := fmt.Sprintf("%v", colnv.(map[string]interface{})[coln.Name])
|
|
if len(coln.Alias) != 0 {
|
|
enumVal, _ := strconv.Atoi(value)
|
|
value = parseEnumAlias(&(coln.Alias), enumVal)
|
|
}
|
|
newVal = append(newVal, ParseAlignmentOutput(coln.Length, alignmentM, value))
|
|
}
|
|
colValues = append(colValues, formatLineBySpace(&newVal, spaceNum))
|
|
log.Trace("colValues:", colValues)
|
|
fmtColValues = append(fmtColValues, strings.Join(colValues, "\n"))
|
|
log.Trace("fmtColValues:", fmtColValues)
|
|
}
|
|
fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
|
|
retFmtCols = fmtColName + "\n\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
|
|
log.Tracef("retFmtCols:\n%s", retFmtCols)
|
|
return retFmtCols
|
|
}
|
|
}
|
|
fmtEnd := fmt.Sprintf(outputJson.End, numberResult)
|
|
retFmtCols = fmtColName + "\n" + strings.Join(fmtColValues, "\n") + "\n\n" + fmtEnd
|
|
log.Tracef("retFmtCols:\n%s", retFmtCols)
|
|
return retFmtCols
|
|
}
|
|
|
|
func parseEnumAlias(alias *[]string, enumVal int) string {
|
|
return (*alias)[enumVal]
|
|
}
|
|
|
|
func formatLineBySpace(strArray *[]string, spaceNum int) string {
|
|
space := strings.Repeat(" ", spaceNum)
|
|
return strings.Join(*strArray, space)
|
|
}
|
|
|
|
func ParseAlignmentOutput(length int, alignment string, str string) string {
|
|
spaceLen := length - len(str)
|
|
if spaceLen < 0 {
|
|
log.Warnf("len(str=%s)=%d more length=%d", str, len(str), length)
|
|
spaceLen = 0
|
|
}
|
|
var retStr string
|
|
switch alignment {
|
|
case "Left":
|
|
suffix := strings.Repeat(" ", spaceLen)
|
|
retStr = str + suffix
|
|
case "Right":
|
|
prefix := strings.Repeat(" ", spaceLen)
|
|
retStr = prefix + str
|
|
log.Tracef("retStr:%s", retStr)
|
|
case "Middle":
|
|
prefix := strings.Repeat(" ", int(math.Ceil(float64(spaceLen)/2)))
|
|
suffix := strings.Repeat(" ", int(math.Floor(float64(spaceLen)/2)))
|
|
retStr = prefix + str + suffix
|
|
}
|
|
log.Tracef("length=%d, spaceLne=%d, alignment=%s, str=%s, retStr=%s", length, spaceLen, alignment, str, retStr)
|
|
return retStr
|
|
}
|
|
|
|
func ParseErrorOutput(err any) *[]byte {
|
|
var output []byte
|
|
|
|
var formatType string = DefaultFormatType
|
|
if formatType == FormatTypeJson {
|
|
output = []byte(fmt.Sprintf("ErrorCode = 1 Error message: %v\n\n", err))
|
|
} else {
|
|
output = []byte(fmt.Sprintf("RetCode = -1 operation failed: %v\n\n", err))
|
|
}
|
|
|
|
return &output
|
|
}
|
|
|
|
func formatTitle(title string) string {
|
|
var builder strings.Builder
|
|
builder.WriteString(title)
|
|
builder.WriteString("\n")
|
|
for i := 0; i < len(title); i++ {
|
|
builder.WriteString("-")
|
|
}
|
|
builder.WriteString("\n")
|
|
return builder.String()
|
|
}
|
|
|
|
func formatTableOutput() {
|
|
|
|
}
|