From 3cc193f57dce8aca620a79ea13615b4c43d725b5 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Tue, 30 Apr 2024 20:37:27 +0800 Subject: [PATCH] =?UTF-8?q?merge:=20=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- features/cm/license.go | 72 ++-- features/cm/ne.go | 135 +++---- features/cm/param.go | 125 ++----- features/cm/software.go | 85 +++-- features/dbrest/dbrest.go | 95 ++--- features/file/file.go | 36 +- features/fm/alarm.go | 31 +- features/fm/smsforward.go | 216 ++++++------ features/fm/ucpcli.go | 4 +- features/lm/logbak.go | 23 +- features/maintenance/maintenance.go | 2 +- features/mml/mml.go | 52 +-- features/pm/performance.go | 127 +++++-- features/security/account.go | 24 +- features/sm/backup.go | 10 +- features/state/getstate.go | 83 ++--- features/trace/trace.go | 40 +-- features/ue/ue.go | 71 ++-- go.mod | 43 ++- go.sum | 117 ++++++ lib/core/utils/ctx/ctx.go | 48 ++- lib/dborm/dborm.go | 56 +-- lib/midware/mml_log.go | 12 +- lib/mmlp/parse.go | 10 +- lib/routes/routes.go | 12 +- lib/services/services.go | 108 +++--- restagent/config/config.go | 123 +++++-- restagent/dev.yaml | 181 ---------- restagent/etc/restconf.yaml | 45 +-- restagent/makefile | 2 +- restagent/restagent.go | 20 +- restagent/run.sh | 17 - .../config/config/config.default.yaml | 4 +- .../constants/uploadsubpath/uploadsubpath.go | 4 + src/framework/i18n/i18n.go | 21 ++ src/framework/utils/date/date.go | 2 + src/framework/utils/file/file.go | 7 +- src/framework/utils/regular/regular.go | 2 +- src/framework/utils/ssh/scp.go | 19 +- src/framework/utils/ssh/ssh.go | 64 +++- src/lib_features/account/account.go | 39 -- src/lib_features/readme.md | 3 +- src/lib_features/session/session.go | 28 -- src/modules/common/controller/account.go | 4 - .../deleteExpiredRecord.go | 22 +- .../genNeStateAlarm/genNeStateAlarm.go | 14 +- .../getStateFromNE/getStateFromNE.go | 13 +- src/modules/monitor/controller/sys_job.go | 46 ++- src/modules/monitor/controller/sys_job_log.go | 46 ++- .../monitor/repository/sys_job_log.impl.go | 7 +- .../network_element/controller/ne_host.go | 50 +++ .../network_element/controller/ne_info.go | 134 +++++-- .../network_element/controller/ne_license.go | 301 ++++++++++++++++ .../network_element/controller/ne_software.go | 56 +-- .../network_element/controller/ne_version.go | 2 + .../network_element/model/ne_license.go | 28 ++ .../network_element/model/ne_software.go | 25 +- .../network_element/model/ne_version.go | 27 +- src/modules/network_element/model/udm_auth.go | 16 +- src/modules/network_element/model/udm_sub.go | 2 + .../network_element/network_element.go | 76 +++- .../repository/ne_info.impl.go | 1 + .../network_element/repository/ne_license.go | 27 ++ .../repository/ne_license.impl.go | 333 ++++++++++++++++++ .../network_element/repository/ne_software.go | 4 +- .../repository/ne_software.impl.go | 71 ++-- .../repository/ne_version.impl.go | 53 +-- .../network_element/service/ne_direct_link.go | 5 + .../network_element/service/ne_info.go | 9 + .../network_element/service/ne_info.impl.go | 154 +++++++- .../network_element/service/ne_license.go | 37 ++ .../service/ne_license.impl.go | 183 ++++++++++ .../network_element/service/ne_software.go | 12 +- .../service/ne_software.impl.go | 80 +++-- src/modules/system/controller/sys_config.go | 19 +- src/modules/system/controller/sys_dept.go | 13 +- .../system/controller/sys_dict_data.go | 48 ++- .../system/controller/sys_dict_type.go | 30 +- .../system/controller/sys_log_login.go | 47 +-- .../system/controller/sys_log_operate.go | 98 ++++-- src/modules/system/controller/sys_menu.go | 4 +- src/modules/system/controller/sys_post.go | 32 +- src/modules/system/controller/sys_role.go | 42 ++- src/modules/system/controller/sys_user.go | 66 ++-- .../system/repository/sys_config.impl.go | 7 +- .../system/repository/sys_dict_data.impl.go | 2 +- .../system/repository/sys_dict_type.impl.go | 11 +- .../system/repository/sys_log_login.impl.go | 7 +- .../system/repository/sys_log_operate.impl.go | 11 +- .../system/repository/sys_role.impl.go | 9 +- .../system/repository/sys_user.impl.go | 12 +- src/modules/system/service/sys_user.impl.go | 2 +- src/modules/trace/service/tcpdump.impl.go | 3 +- src/modules/ws/controller/ws.go | 20 +- src/modules/ws/service/ws_receive.impl.go | 6 + 95 files changed, 3027 insertions(+), 1518 deletions(-) delete mode 100644 restagent/dev.yaml delete mode 100644 restagent/run.sh delete mode 100644 src/lib_features/account/account.go delete mode 100644 src/lib_features/session/session.go create mode 100644 src/modules/network_element/controller/ne_license.go create mode 100644 src/modules/network_element/model/ne_license.go create mode 100644 src/modules/network_element/repository/ne_license.go create mode 100644 src/modules/network_element/repository/ne_license.impl.go create mode 100644 src/modules/network_element/service/ne_license.go create mode 100644 src/modules/network_element/service/ne_license.impl.go diff --git a/features/cm/license.go b/features/cm/license.go index 1c045dd..30b2e1f 100644 --- a/features/cm/license.go +++ b/features/cm/license.go @@ -7,7 +7,6 @@ import ( "os" "os/exec" "strings" - "time" "be.ems/lib/dborm" "be.ems/lib/log" @@ -29,11 +28,11 @@ var ( 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -51,11 +50,11 @@ func UploadLicenseFile(w http.ResponseWriter, r *http.Request) { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -97,11 +96,11 @@ func DownloadLicenseFile(w http.ResponseWriter, r *http.Request) { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -154,30 +153,30 @@ func DeleteLcenseFile(w http.ResponseWriter, r *http.Request) { services.ResponseStatusOK204NoContent(w) } -type MMLRequest struct { - MML []string `json:"mml"` -} +// type MMLRequest struct { +// MML []string `json:"mml"` +// } -var TIME_DELAY_AFTER_WRITE time.Duration = 200 -var TIME_DEAD_LINE time.Duration = 10 +// 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 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -274,12 +273,13 @@ func UploadLicenseFileData(w http.ResponseWriter, r *http.Request) { } // 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) + cpCmd := fmt.Sprintf("sudo test -f %s/system.ini && cp -f %s/system.ini %s/system.ini.bak||echo 0", + neLicensePath, 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) + log.Errorf("Faile to execute cp command:%v, cmd:%s", err, cpCmd) services.ResponseInternalServerError500ProcessError(w, err) return } diff --git a/features/cm/ne.go b/features/cm/ne.go index 708749f..665c3f8 100644 --- a/features/cm/ne.go +++ b/features/cm/ne.go @@ -70,11 +70,11 @@ func init() { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -112,11 +112,11 @@ type OmcNeConfig struct { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -142,7 +142,8 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) { services.ResponseInternalServerError500ProcessError(w, err) return } - neInfo.UpdateTime = time.Now().Format(time.DateTime) + //neInfo.UpdateTime = time.Now().Format(time.DateTime) + neInfo.UpdateTime = time.Now() log.Debug("NE info:", neInfo) //if !config.GetYamlConfig().OMC.Chk2Ne { @@ -166,7 +167,7 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) { } 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)) + apiUri := fmt.Sprintf("%s/systemManagement/v1/elementType/%s/objectType/config/omcNeConfig?ne_id=%s", config.DefaultUriPrefix, strings.ToLower(neInfo.NeType), neInfo.NeId) requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri) log.Debug("requestURI2NF:", requestURI2NF) @@ -226,11 +227,11 @@ func PostNeInfo(w http.ResponseWriter, r *http.Request) { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -252,7 +253,7 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) { neInfo := new(dborm.NeInfo) _ = json.Unmarshal(body, neInfo) neInfo.NeType = strings.ToUpper(neType) - neInfo.UpdateTime = time.Now().Format(time.DateTime) + neInfo.UpdateTime = time.Now() log.Debug("NE info:", neInfo) //if !config.GetYamlConfig().OMC.Chk2Ne { @@ -276,7 +277,7 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) { } 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) + apiUri := fmt.Sprintf("%s/systemManagement/v1/elementType/%s/objectType/config/omcNeConfig?ne_id=%s", config.DefaultUriPrefix, neTypeLower, neInfo.NeId) requestURI2NF := fmt.Sprintf("%s%s", hostUri, apiUri) log.Debug("requestURI2NF:", requestURI2NF) @@ -337,11 +338,11 @@ func PutNeInfo(w http.ResponseWriter, r *http.Request) { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -420,11 +421,11 @@ func IsActiveNF(neInfo *dborm.NeInfo) bool { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -561,11 +562,11 @@ type ImportCMJson struct { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -595,12 +596,13 @@ func ImportCmToNF(w http.ResponseWriter, r *http.Request) { path = config.GetYamlConfig().OMC.Backup } else { path = config.GetYamlConfig().OMC.Upload - fileName, err = services.HandleUploadFile(r, path, "") + fileNamePath, err := services.HandleUploadFile(r, path, "") if err != nil { log.Error("Faile to HandleUploadFile:", err) services.ResponseInternalServerError500ProcessError(w, err) return } + fileName = fileNamePath } filePath := fmt.Sprintf("%s/%s", path, fileName) @@ -722,11 +724,11 @@ func ImportCmToNF(w http.ResponseWriter, r *http.Request) { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -767,11 +769,11 @@ func DownloadNeBackupFile(w http.ResponseWriter, r *http.Request) { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -826,11 +828,11 @@ func DeleteNeBackupFile(w http.ResponseWriter, r *http.Request) { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -857,15 +859,20 @@ func PostNeServiceAction(w http.ResponseWriter, r *http.Request) { 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 - } + // send 204 to fe firstly + services.ResponseStatusOK204NoContent(w) + //actionCmd := fmt.Sprintf("sudo %s/bin/omcsvc.sh %s", config.GetYamlConfig().NE.OmcDir, action) + actionCmd := fmt.Sprintf("sudo systemctl %s restagent", action) + go RunSSHCmd(sshHost, actionCmd) + return + // 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": @@ -912,11 +919,11 @@ func PostNeServiceAction(w http.ResponseWriter, r *http.Request) { 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 - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] diff --git a/features/cm/param.go b/features/cm/param.go index 679bd25..6ba6ccd 100644 --- a/features/cm/param.go +++ b/features/cm/param.go @@ -3,7 +3,7 @@ package cm import ( "strings" - "be.ems/lib/dborm" + "be.ems/lib/core/utils/ctx" "be.ems/lib/global" "be.ems/lib/log" "be.ems/lib/services" @@ -14,7 +14,8 @@ import ( "io" "net/http" - tokenConst "be.ems/src/framework/constants/token" + neService "be.ems/src/modules/network_element/service" + "github.com/go-resty/resty/v2" "github.com/gorilla/mux" ) @@ -29,54 +30,20 @@ var ( func GetParamConfigFromNF(w http.ResponseWriter, r *http.Request) { log.Debug("GetParamConfigFromNF processing... ") - // data := make([]map[string]interface{}, 1) - var response services.DataResponse + neId := ctx.GetQuery(r, "ne_id") vars := mux.Vars(r) neType := vars["elementTypeValue"] - if neType == "" { + if neType == "" || neId == "" { 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 - } + neInfo := neService.NewNeInfoImpl.SelectNeInfoByNeTypeAndNeID(neType, neId) - 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) + var response services.DataResponse + if neInfo.NeId == neId && neInfo.NeId != "" { + requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.IP, neInfo.Port, r.RequestURI) log.Debug("requestURI2NF:", requestURI2NF) resp, err := client.R(). @@ -100,30 +67,24 @@ func GetParamConfigFromNF(w http.ResponseWriter, r *http.Request) { 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 - } - + neId := ctx.GetQuery(r, "ne_id") vars := mux.Vars(r) neType := vars["elementTypeValue"] - if neType == "" { + if neType == "" || neId == "" { 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) + neInfo := neService.NewNeInfoImpl.SelectNeInfoByNeTypeAndNeID(neType, neId) + + if neInfo.NeId != neId || neInfo.NeId == "" { + log.Error("neId is empty") services.ResponseInternalServerError500DatabaseOperationFailed(w) return } - requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI) + 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限制大小 @@ -152,12 +113,6 @@ func PostParamConfigToNF(w http.ResponseWriter, r *http.Request) { 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 == "" { @@ -172,16 +127,16 @@ func PutParamConfigToNF(w http.ResponseWriter, r *http.Request) { 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) + neId := ctx.GetQuery(r, "ne_id") + neInfo := neService.NewNeInfoImpl.SelectNeInfoByNeTypeAndNeID(neType, neId) + + if neInfo.NeId != neId || neInfo.NeId == "" { + log.Error("neId is empty") services.ResponseInternalServerError500DatabaseOperationFailed(w) return } - requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI) + 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限制大小 @@ -211,36 +166,12 @@ func PutParamConfigToNF(w http.ResponseWriter, r *http.Request) { // // 目前没配置,返回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 == "" { @@ -248,17 +179,17 @@ func DeleteParamConfigToNF(w http.ResponseWriter, r *http.Request) { 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) + neId := ctx.GetQuery(r, "ne_id") + neInfo := neService.NewNeInfoImpl.SelectNeInfoByNeTypeAndNeID(neType, neId) + + if neInfo.NeId != neId || neInfo.NeId == "" { + log.Error("neId is empty") services.ResponseInternalServerError500DatabaseOperationFailed(w) return } - requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.Ip, neInfo.Port, r.RequestURI) + requestURI2NF := fmt.Sprintf("http://%s:%v%s", neInfo.IP, neInfo.Port, r.RequestURI) log.Debug("requestURI2NF: DELETE ", requestURI2NF) client := resty.New() diff --git a/features/cm/software.go b/features/cm/software.go index d4ec7ed..2ab11dc 100644 --- a/features/cm/software.go +++ b/features/cm/software.go @@ -55,11 +55,11 @@ func verify_signature(public_key_name string, source_cms_file string, source_fil func UploadSoftwareFile(w http.ResponseWriter, r *http.Request) { log.Debug("UploadSoftwareFile processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Http request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -191,11 +191,11 @@ func UploadSoftwareFile(w http.ResponseWriter, r *http.Request) { func UploadSoftwareMultiFile(w http.ResponseWriter, r *http.Request) { log.Info("UploadSoftwareMultiFile processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Http request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -213,10 +213,21 @@ func UploadSoftwareMultiFile(w http.ResponseWriter, r *http.Request) { services.ResponseNotFound404UriNotExist(w, r) return } + + sql := fmt.Sprintf("select * from ne_software where ne_type='%s' and version='%s'", neTypeUpper, version) + neSoftwareInfo, _ := dborm.XormGetDataBySQL(sql) + if len(*neSoftwareInfo) >= 1 { + services.ResponseWithJson(w, 200, map[string]any{ + "code": 0, + "msg": "Software version already exists", + }) + return + } + md5Param := services.GetUriParamString(r, "md5Sum", ",", false, false) softwarePath := fmt.Sprintf("%s/%s", config.GetYamlConfig().OMC.Software, neTypeLower) - err = os.MkdirAll(softwarePath, os.ModePerm) + err := os.MkdirAll(softwarePath, os.ModePerm) if err != nil { log.Error("Failed to Mkdir:", err) services.ResponseInternalServerError500ProcessError(w, err) @@ -372,11 +383,11 @@ func UploadSoftwareMultiFile(w http.ResponseWriter, r *http.Request) { func DownloadSoftwareFile(w http.ResponseWriter, r *http.Request) { log.Debug("DownloadSoftwareFile processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -418,11 +429,11 @@ func DownloadSoftwareFile(w http.ResponseWriter, r *http.Request) { func DeleteSoftwareFile(w http.ResponseWriter, r *http.Request) { log.Debug("DeleteSoftwareFile processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -478,11 +489,11 @@ func DeleteSoftwareFile(w http.ResponseWriter, r *http.Request) { func DistributeSoftwareToNF(w http.ResponseWriter, r *http.Request) { log.Debug("DistributeSoftwareFile processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Http request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -618,11 +629,11 @@ func DistributeSoftwareToNF(w http.ResponseWriter, r *http.Request) { func ActiveSoftwareToNF(w http.ResponseWriter, r *http.Request) { log.Debug("ActiveSoftwareToNF processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Http request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -825,11 +836,11 @@ func ActiveSoftwareToNF(w http.ResponseWriter, r *http.Request) { func RollBackSoftwareToNF(w http.ResponseWriter, r *http.Request) { log.Debug("ActiveSoftwareToNF processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Http request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] @@ -919,7 +930,7 @@ func RollBackSoftwareToNF(w http.ResponseWriter, r *http.Request) { return } services.ResponseStatusOK204NoContent(w) - RunSSHCmd(sshHost, runCmd) + go RunSSHCmd(sshHost, runCmd) return } err = RunSSHCmd(sshHost, runCmd) diff --git a/features/dbrest/dbrest.go b/features/dbrest/dbrest.go index 91f5177..1a03083 100644 --- a/features/dbrest/dbrest.go +++ b/features/dbrest/dbrest.go @@ -77,18 +77,20 @@ type DatabaseClient struct { var DbClient DatabaseClient -func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error { - DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbUser, dbPassword, dbHost, dbPort, dbName) +func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName, dbParam string) error { + // DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", + // dbUser, dbPassword, dbHost, dbPort, dbName) + DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s", + dbUser, dbPassword, dbHost, dbPort, dbName, dbParam) DbClient.dbType = dbType DbClient.dbConnMaxLifetime = 0 DbClient.dbMaxIdleConns = 0 DbClient.dbMaxOpenConns = 0 + if log.GetLevel() == log.LOG_TRACE { DbClient.IsShowSQL = true } - log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbType, dbUser, dbHost, dbPort, dbName) + log.Debugf("dbType:%s dbUrl:%s:", dbType, DbClient.dbUrl) var err error DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl) @@ -99,6 +101,8 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime) DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns) DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns) + DbClient.XEngine.DatabaseTZ = time.Local // 必须 + DbClient.XEngine.TZLocation = time.Local // 必须 if DbClient.IsShowSQL { //DbClient.XEngine.SetLogger(&log.Elogger) DbClient.XEngine.ShowSQL(true) @@ -188,13 +192,13 @@ func ExtDatabaseExecSQL(w http.ResponseWriter, r *http.Request) { log.Debug("ExtDatabaseExecSQL processing... ") var sql []string - var err error + // var err error - _, err = services.CheckExtValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err = services.CheckExtValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } //vars := mux.Vars(r) //tblName := vars["objectTypeValue"] @@ -249,11 +253,11 @@ func ExtDatabaseGetData(w http.ResponseWriter, r *http.Request) { log.Debug("ExtDatabaseGetData processing... ") var sql []string - token, err := services.CheckExtValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // token, err := services.CheckExtValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } pack := "dbrest" vars := mux.Vars(r) @@ -261,7 +265,7 @@ func ExtDatabaseGetData(w http.ResponseWriter, r *http.Request) { dbname := vars["elementTypeValue"] tbname := vars["objectTypeValue"] - log.Debugf("token:%s, method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", token, r.Method, module, dbname, tbname, pack) + log.Debugf("method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", r.Method, module, dbname, tbname, pack) // exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack) // if err != nil { @@ -295,12 +299,11 @@ func ExtDatabaseGetData(w http.ResponseWriter, r *http.Request) { for i, s := range sql { log.Tracef("SQL[%d]: %s", i, sql[i]) - rows := make([]map[string]interface{}, 0) mapRows := make(map[string]interface{}) if s != "" { // err = XEngine.SQL(s).Find(&rows) - if IsQuerySQL(s) == false { + if !IsQuerySQL(s) { services.ResponseNotAcceptable406QuerySQLError(w) return } @@ -310,7 +313,7 @@ func ExtDatabaseGetData(w http.ResponseWriter, r *http.Request) { querySQL = querySQL + " " + ls } log.Debug("querySQL:", querySQL) - rows, err = DbClient.XEngine.QueryInterface(querySQL) + rows, err := DbClient.XEngine.QueryInterface(querySQL) if err != nil { log.Error("SQL failed:", err) services.ResponseInternalServerError500DatabaseOperationFailed(w) @@ -332,11 +335,11 @@ func ExtDatabaseGetData(w http.ResponseWriter, r *http.Request) { func ExtDatabaseInsertData(w http.ResponseWriter, r *http.Request) { log.Debug("ExtDatabaseInsertData processing... ") - token, err := services.CheckExtValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // token, err := services.CheckExtValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } body, err := io.ReadAll(io.LimitReader(r.Body, global.RequestBodyMaxLen)) //io.LimitReader限制大小 if err != nil { @@ -351,7 +354,7 @@ func ExtDatabaseInsertData(w http.ResponseWriter, r *http.Request) { tbname := vars["objectTypeValue"] pack := "dbrest" - log.Debugf("token:%s, method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", token, r.Method, module, dbname, tbname, pack) + log.Debugf("method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", r.Method, module, dbname, tbname, pack) // exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack) // if err != nil { @@ -396,11 +399,11 @@ func ExtDatabaseInsertData(w http.ResponseWriter, r *http.Request) { func ExtDatabaseUpdateData(w http.ResponseWriter, r *http.Request) { log.Debug("ExtDatabaseUpdateData processing... ") - token, err := services.CheckExtValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // token, err := services.CheckExtValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) module := "" @@ -408,7 +411,7 @@ func ExtDatabaseUpdateData(w http.ResponseWriter, r *http.Request) { tbname := vars["objectTypeValue"] pack := "dbrest" - log.Debugf("token:%s, method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", token, r.Method, module, dbname, tbname, pack) + log.Debugf("method:%s, module:%s, dbname:%s, tbname:%s, pack:%s", r.Method, module, dbname, tbname, pack) // exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack) // if err != nil { @@ -460,11 +463,11 @@ func ExtDatabaseUpdateData(w http.ResponseWriter, r *http.Request) { func ExtDatabaseDeleteData(w http.ResponseWriter, r *http.Request) { log.Debug("ExtDatabaseDeleteData processing... ") - token, err := services.CheckExtValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // token, err := services.CheckExtValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) module := "" @@ -472,7 +475,7 @@ func ExtDatabaseDeleteData(w http.ResponseWriter, r *http.Request) { tbname := vars["objectTypeValue"] pack := "dbreset" - log.Debugf("token:%s, method:%s, module:%, dbname:%s, tbname:%s pack:%s", token, r.Method, module, dbname, tbname, pack) + log.Debugf("method:%s, module:%, dbname:%s, tbname:%s pack:%s", r.Method, module, dbname, tbname, pack) // exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack) // if err != nil { @@ -514,11 +517,11 @@ func DatabaseGetData(w http.ResponseWriter, r *http.Request) { var sql []string var err error - _, err = services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err = services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) tblName := vars["objectTypeValue"] @@ -548,7 +551,7 @@ func DatabaseGetData(w http.ResponseWriter, r *http.Request) { if s != "" { // err = XEngine.SQL(s).Find(&rows) - if IsQuerySQL(s) == false { + if !IsQuerySQL(s) { services.ResponseNotAcceptable406QuerySQLError(w) return } @@ -560,8 +563,8 @@ func DatabaseGetData(w http.ResponseWriter, r *http.Request) { log.Debug("querySQL:", querySQL) rows, err = DbClient.XEngine.QueryInterface(querySQL) if err != nil { - log.Error("SQL failed:", err) - services.ResponseInternalServerError500DatabaseOperationFailed(w) + log.Error("QueryInterface failed:", err) + services.ResponseInternalServerError500ProcessError(w, err) return } tableName := GetTableName(s) diff --git a/features/file/file.go b/features/file/file.go index 4374d4c..7abfe87 100644 --- a/features/file/file.go +++ b/features/file/file.go @@ -37,11 +37,11 @@ var ( func UploadFile(w http.ResponseWriter, r *http.Request) { log.Debug("UploadFile processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Http request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } vars := mux.Vars(r) location := vars["location"] @@ -63,20 +63,22 @@ func UploadFile(w http.ResponseWriter, r *http.Request) { } if location == "upload" { path = config.GetYamlConfig().OMC.Upload - fileName, err = services.HandleUploadFile(r, path, fileName) + fileNamePath, err := services.HandleUploadFile(r, path, fileName) if err != nil { log.Error("Faile to HandleUploadFile:", err) services.ResponseInternalServerError500ProcessError(w, err) return } + fileName = fileNamePath } else { path = config.GetYamlConfig().OMC.FrontUpload - fileName, err = services.HandleUploadFile(r, path, fileName) + fileName, err := services.HandleUploadFile(r, path, fileName) if err != nil { log.Error("Faile to HandleUploadFile:", err) services.ResponseInternalServerError500ProcessError(w, err) return } + fileName = fileName } log.Debugf("upload file=%s to path=%s", fileName, path) @@ -87,11 +89,11 @@ func UploadFile(w http.ResponseWriter, r *http.Request) { func DownloadFile(w http.ResponseWriter, r *http.Request) { log.Debug("DownloadFile processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) location := vars["location"] @@ -132,11 +134,11 @@ func DownloadFile(w http.ResponseWriter, r *http.Request) { func DeleteFile(w http.ResponseWriter, r *http.Request) { log.Debug("DeleteFile processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["neType"] diff --git a/features/fm/alarm.go b/features/fm/alarm.go index 6a61081..716721b 100644 --- a/features/fm/alarm.go +++ b/features/fm/alarm.go @@ -151,9 +151,9 @@ type DatabaseClient struct { var DbClient DatabaseClient -func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error { - DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbUser, dbPassword, dbHost, dbPort, dbName) +func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName, dbParam string) error { + DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s", + dbUser, dbPassword, dbHost, dbPort, dbName, dbParam) DbClient.dbType = dbType DbClient.dbConnMaxLifetime = 0 DbClient.dbMaxIdleConns = 0 @@ -161,8 +161,7 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err if log.GetLevel() == log.LOG_TRACE { DbClient.IsShowSQL = true } - log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbType, dbUser, dbHost, dbPort, dbName) + log.Debugf("dbType:%s dbUrl:%s:", dbType, DbClient.dbUrl) var err error DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl) @@ -173,6 +172,8 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime) DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns) DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns) + DbClient.XEngine.DatabaseTZ = time.Local // 必须 + DbClient.XEngine.TZLocation = time.Local // 必须 if DbClient.IsShowSQL { DbClient.XEngine.ShowSQL(true) } @@ -460,8 +461,8 @@ func PostAlarmFromNF(w http.ResponseWriter, r *http.Request) { if err = AlarmEmailForward(&alarmData); err != nil { log.Error("Failed to AlarmEmailForward:", err) } - if err = AlarmForwardBySMSC(&alarmData); err != nil { - log.Error("Failed to AlarmForwardBySMSC:", err) + if err = AlarmSMSForward(&alarmData); err != nil { + log.Error("Failed to AlarmSMSForward:", err) } } } @@ -473,11 +474,11 @@ func PostAlarmFromNF(w http.ResponseWriter, r *http.Request) { func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) { log.Debug("GetAlarmFromNF processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] neTypeLower := strings.ToLower(neType) @@ -491,7 +492,7 @@ func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) { //var neInfo *dborm.NeInfo var nes []dborm.NeInfo - _, err = dborm.XormGetAllNeInfo(&nes) + _, err := dborm.XormGetAllNeInfo(&nes) if err != nil { log.Error("Failed to get all ne info:", err) services.ResponseInternalServerError500ProcessError(w, err) @@ -734,8 +735,8 @@ func GetAlarmFromNF(w http.ResponseWriter, r *http.Request) { if err = AlarmEmailForward(&alarmData); err != nil { log.Error("Failed to AlarmEmailForward:", err) } - if err = AlarmForwardBySMSC(&alarmData); err != nil { - log.Error("Failed to AlarmForwardBySMSC:", err) + if err = AlarmSMSForward(&alarmData); err != nil { + log.Error("Failed to AlarmSMSForward:", err) } } } diff --git a/features/fm/smsforward.go b/features/fm/smsforward.go index 635a05c..06e1134 100644 --- a/features/fm/smsforward.go +++ b/features/fm/smsforward.go @@ -5,6 +5,7 @@ import ( "fmt" "net/http" "net/url" + "strings" "time" "be.ems/lib/dborm" @@ -15,7 +16,24 @@ import ( "github.com/linxGnu/gosmpp/pdu" ) -func AlarmForwardBySMS(alarmData *Alarm) error { +func AlarmSMSForward(alarmData *Alarm) error { + switch config.GetYamlConfig().Alarm.SMProxy { + case "sms": + users, err := AlarmForwardBySMS(alarmData) + writeLog(alarmData, users, "SMS", err) + return err + case "smsc": + users, err := AlarmForwardBySMPP(alarmData) + writeLog(alarmData, users, "SMS", err) + return err + default: + users, err := AlarmForwardBySMPP(alarmData) + writeLog(alarmData, users, "SMS", err) + return err + } +} + +func AlarmForwardBySMS(alarmData *Alarm) (string, error) { log.Info("AlarmForwardBySMS processing... ") SMSFforwardconfig := config.GetYamlConfig().Alarm.SMS @@ -29,91 +47,74 @@ func AlarmForwardBySMS(alarmData *Alarm) error { toUsers, err := dborm.XormGetAlarmForward("SMS") if err != nil { log.Error("Failed to XormGetAlarmForward:", err) - return err + return "", err } else if toUsers == nil { err := errors.New("not found forward phone number") log.Error(err) - return err + return "", err + } + userList := strings.Join(*toUsers, ",") + + // 短信相关参数 + params := url.Values{} + params.Set("PhoneNumbers", userList) + params.Set("SignName", SMSFforwardconfig.SignName) + params.Set("TemplateCode", SMSFforwardconfig.TemplateCode) + params.Set("TemplateParam", `{"message":"alarm"}`) + + // 构建请求URL + reqURL := apiURL + "?Action=SendSms&" + params.Encode() + + // 创建HTTP请求 + req, err := http.NewRequest("GET", reqURL, nil) + if err != nil { + log.Error("Failed to create request:", err) + return userList, err } - for _, toUser := range *toUsers { - // 短信相关参数 - params := url.Values{} - params.Set("PhoneNumbers", toUser) - params.Set("SignName", SMSFforwardconfig.SignName) - params.Set("TemplateCode", SMSFforwardconfig.TemplateCode) - params.Set("TemplateParam", `{"message":"alarm"}`) + // 添加请求头部 + req.Header.Set("Content-Type", "application/x-www-form-urlencoded") + req.Header.Set("Authorization", "APPCODE "+accessKeySecret) - // 构建请求URL - reqURL := apiURL + "?Action=SendSms&" + params.Encode() + // 发送请求 + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Error("Failed to send request:%v", err) + return userList, err + } + defer resp.Body.Close() - // 创建HTTP请求 - req, err := http.NewRequest("GET", reqURL, nil) - if err != nil { - log.Error("Failed to create request:", err) - return err - } - - // 添加请求头部 - req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - req.Header.Set("Authorization", "APPCODE "+accessKeySecret) - - forwardLog := &dborm.AlarmForwardLog{ - NeType: alarmData.NeType, - NeID: alarmData.NeId, - AlarmID: alarmData.AlarmId, - AlarmTitle: alarmData.AlarmTitle, - AlarmSeq: alarmData.AlarmSeq, - EventTime: alarmData.EventTime, - ToUser: toUser, - } - // 发送请求 - client := &http.Client{} - resp, err := client.Do(req) - if err != nil { - operResult := fmt.Sprintf("Failed to send request:%v", err) - log.Error(operResult) - forwardLog.OperResult = operResult - affected, err := dborm.XormInsertAlarmForwardLog(forwardLog) - if err != nil && affected <= 0 { - log.Error("Failed to insert data:", err) - } - continue - } - defer resp.Body.Close() - - // 解析响应 - if resp.StatusCode == http.StatusOK { - operResult := "SMS sent successfully!" - log.Info(operResult) - forwardLog.OperResult = operResult - affected, err := dborm.XormInsertAlarmForwardLog(forwardLog) - if err != nil && affected <= 0 { - log.Error("Failed to insert data:", err) - continue - } - } else { - operResult := fmt.Sprintf("Failed to send SMS, StatusCode=%d", resp.StatusCode) - log.Error(operResult) - forwardLog.OperResult = operResult - affected, err := dborm.XormInsertAlarmForwardLog(forwardLog) - if err != nil && affected <= 0 { - log.Error("Failed to insert data:", err) - continue - } - } + // 解析响应 + switch resp.StatusCode { + case http.StatusOK, http.StatusAccepted, http.StatusNoContent, http.StatusCreated: + return userList, nil + default: + err := fmt.Errorf("Failed to send SMS: %s(Code=%d)", resp.Status, resp.StatusCode) + log.Error(err) + return userList, err } - return nil } -func AlarmForwardBySMPP(alarmData *Alarm) error { +func AlarmForwardBySMPP(alarmData *Alarm) (string, error) { log.Info("AlarmForwardBySMPP processing... ") + toUsers, err := dborm.XormGetAlarmForward("SMS") + if err != nil { + log.Error("Failed to XormGetAlarmForward:", err) + return "", err + } else if toUsers == nil { + err := errors.New("not found forward phone number") + log.Error(err) + return "", err + } + userList := strings.Join(*toUsers, ",") + auth := gosmpp.Auth{ SMSC: config.GetYamlConfig().Alarm.SMSC.Addr, - SystemID: config.GetYamlConfig().Alarm.SMSC.UserName, + SystemID: config.GetYamlConfig().Alarm.SMSC.SystemID, Password: config.GetYamlConfig().Alarm.SMSC.Password, - SystemType: "", + SystemType: config.GetYamlConfig().Alarm.SMSC.SystemType, } // conn, err := gosmpp.NonTLSDialer(auth.SMSC) @@ -141,49 +142,50 @@ func AlarmForwardBySMPP(alarmData *Alarm) error { }, }, -1) if err != nil { - log.Error(err) - return err + log.Error("Failed to create SMPP new session:", err) + return userList, err } defer func() { _ = trans.Close() }() - toUsers, err := dborm.XormGetAlarmForward("SMS") - if err != nil { - log.Error("Failed to XormGetAlarmForward:", err) - return err - } else if toUsers == nil { - err := errors.New("not found forward phone number") - log.Error(err) - return err - } // sending SMS(s) - for _, toUser := range *toUsers { - forwardLog := &dborm.AlarmForwardLog{ - NeType: alarmData.NeType, - NeID: alarmData.NeId, - AlarmID: alarmData.AlarmId, - AlarmTitle: alarmData.AlarmTitle, - AlarmSeq: alarmData.AlarmSeq, - EventTime: alarmData.EventTime, - ToUser: toUser, - } - message := alarmData.AlarmTitle + "from" + alarmData.NeType + alarmData.NeId + "at" + alarmData.EventTime - if err = trans.Transceiver().Submit(newSubmitSM(toUser, message)); err != nil { - operResult := fmt.Sprintf("Failed to submit short message:%v", err) - log.Error(operResult) - forwardLog.OperResult = operResult - } else { - operResult := "SMS sent successfully!" - log.Trace(operResult) - forwardLog.OperResult = operResult - } + // var results []string + // for _, toUser := range *toUsers { + message := "Alarm Notification: " + alarmData.AlarmTitle + " from " + alarmData.NeType + " " + alarmData.NeId + " at " + alarmData.EventTime + if err = trans.Transceiver().Submit(newSubmitSM(userList, message)); err != nil { + // result := fmt.Sprintf("Failed to submit %s hort message:%s", toUser, err.Error()) + // results = append(results, result) + log.Error("Failed to submit hort message:", err) + return userList, err + } + // } + return userList, nil +} - affected, err := dborm.XormInsertAlarmForwardLog(forwardLog) - if err != nil && affected <= 0 { - log.Error("Failed to insert data:", err) - continue - } +func writeLog(alarmData *Alarm, toUser, forwardBy string, err error) error { + var result string + if err == nil { + result = "SMS sent successfully" + } else { + result = err.Error() + } + forwardLog := &dborm.AlarmForwardLog{ + NeType: alarmData.NeType, + NeID: alarmData.NeId, + AlarmID: alarmData.AlarmId, + AlarmTitle: alarmData.AlarmTitle, + AlarmSeq: alarmData.AlarmSeq, + EventTime: alarmData.EventTime, + Interface: forwardBy, + ToUser: toUser, + OperResult: result, + } + + affected, err := dborm.XormInsertAlarmForwardLog(forwardLog) + if err != nil && affected <= 0 { + log.Error("Failed to insert data:", err) + return err } return nil } diff --git a/features/fm/ucpcli.go b/features/fm/ucpcli.go index 94581d5..4c7b0e0 100644 --- a/features/fm/ucpcli.go +++ b/features/fm/ucpcli.go @@ -13,9 +13,9 @@ import ( func AlarmForwardBySMSC(alarmData *Alarm) error { opt := &ucp.Options{ Addr: config.GetYamlConfig().Alarm.SMSC.Addr, - User: config.GetYamlConfig().Alarm.SMSC.UserName, + User: config.GetYamlConfig().Alarm.SMSC.SystemID, Password: config.GetYamlConfig().Alarm.SMSC.Password, - AccessCode: "", + AccessCode: config.GetYamlConfig().Alarm.SMSC.SystemType, } client := ucp.New(opt) diff --git a/features/lm/logbak.go b/features/lm/logbak.go index aa65696..b744e82 100644 --- a/features/lm/logbak.go +++ b/features/lm/logbak.go @@ -50,9 +50,9 @@ var DbClient DatabaseClient // conf.Database.Host, conf.Database.Port, conf.Database.Name) // } -func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error { - DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbUser, dbPassword, dbHost, dbPort, dbName) +func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName, dbParam string) error { + DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s", + dbUser, dbPassword, dbHost, dbPort, dbName, dbParam) DbClient.dbType = dbType DbClient.dbConnMaxLifetime = 0 DbClient.dbMaxIdleConns = 0 @@ -60,8 +60,7 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err if log.GetLevel() == log.LOG_TRACE { DbClient.IsShowSQL = true } - log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbType, dbUser, dbHost, dbPort, dbName) + log.Debugf("dbType:%s dbUrl:%s:", dbType, DbClient.dbUrl) var err error DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl) @@ -72,6 +71,8 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime) DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns) DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns) + DbClient.XEngine.DatabaseTZ = time.Local // 必须 + DbClient.XEngine.TZLocation = time.Local // 必须 if DbClient.IsShowSQL { DbClient.XEngine.ShowSQL(true) } @@ -83,18 +84,18 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err func ExtDatabaseBackupData(w http.ResponseWriter, r *http.Request) { log.Debug("ExtDatabaseBackupData processing... ") - token, err := services.CheckExtValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // token, err := services.CheckExtValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) module := vars["managementModule"] dbname := vars["dataStorage"] tbname := vars["dataObject"] pack := "lm" - log.Debugf("token:%s, method:%s, module:%s dbname:%s, tbname:%s pack:%s", token, r.Method, module, dbname, tbname, pack) + log.Debugf("method:%s, module:%s dbname:%s, tbname:%s pack:%s", r.Method, module, dbname, tbname, pack) // exist, err := services.CheckUserPermission(token, strings.ToLower(r.Method), module, dbname, tbname, pack) // if err != nil { // log.Error("Failed to get permission:", err) diff --git a/features/maintenance/maintenance.go b/features/maintenance/maintenance.go index 49dcd06..2ee014a 100644 --- a/features/maintenance/maintenance.go +++ b/features/maintenance/maintenance.go @@ -216,7 +216,7 @@ func SqlClient(w http.ResponseWriter, r *http.Request) { if isConnet == "connet" && dborm.DbClient.XEngine == nil { conf := config.GetYamlConfig() err := dborm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password, - conf.Database.Host, conf.Database.Port, conf.Database.Name) + conf.Database.Host, conf.Database.Port, conf.Database.Name, conf.Database.ConnParam) if err != nil { fmt.Println("dborm.initDbClient err:", err) services.ResponseInternalServerError500DatabaseOperationFailed(w) diff --git a/features/mml/mml.go b/features/mml/mml.go index ad025b1..1df4fca 100644 --- a/features/mml/mml.go +++ b/features/mml/mml.go @@ -51,16 +51,24 @@ var ( CustomUriOmMmlInt = config.UriPrefix + "/omManagement/{apiVersion}/mml/{neType}/{neId}" ) -var TIME_DELAY_AFTER_WRITE time.Duration = 200 -var TIME_DEAD_LINE time.Duration = 10 +var ( + TIME_DELAY_AFTER_WRITE time.Duration = 200 + TIME_DEAD_LINE time.Duration = 10 + WIN_ROW_SIZE byte = 100 + WIN_COL_SIZE byte = 100 + BUFFER_SIZE int = 65535 +) -func init() { +func InitMML() { 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) } + WIN_ROW_SIZE = config.GetYamlConfig().MML.SizeRow + WIN_COL_SIZE = config.GetYamlConfig().MML.SizeCol + BUFFER_SIZE = config.GetYamlConfig().MML.BufferSize } func PostMML2ToNF(w http.ResponseWriter, r *http.Request) { @@ -78,8 +86,7 @@ func PostMML2ToNF(w http.ResponseWriter, r *http.Request) { return } - var buf [20 * 1024]byte - //buf := make([]byte, 0) + buf := make([]byte, BUFFER_SIZE) var n int var mmlResult []string port2 := 5002 @@ -90,6 +97,7 @@ func PostMML2ToNF(w http.ResponseWriter, r *http.Request) { if neInfo != nil { hostMML := fmt.Sprintf("%s:%d", neInfo.Ip, port2) conn, err := net.Dial("tcp", hostMML) + //conn, err := net.Dial("tcp", hostMML) if err != nil { errMsg := fmt.Sprintf("Failed to dial %s: %v", hostMML, err) log.Error(errMsg) @@ -110,6 +118,9 @@ func PostMML2ToNF(w http.ResponseWriter, r *http.Request) { // services.ResponseWithJson(w, http.StatusOK, response) // return // } + // 发送窗口大小设置命令 + conn.Write([]byte{255, 251, 31}) // 发送WILL WINDOW SIZE + conn.Write([]byte{255, 250, 31, 0, WIN_ROW_SIZE, 0, WIN_COL_SIZE, 255, 240}) // 发送设置 WINDOW SIZE 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) @@ -172,7 +183,7 @@ func PostMML2ToNF(w http.ResponseWriter, r *http.Request) { //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 := re1.ReplaceAllString(string(buf[0:n]), "") result = re2.ReplaceAllString(result, "") mmlResult = append(mmlResult, result) } @@ -186,11 +197,11 @@ func PostMML2ToNF(w http.ResponseWriter, r *http.Request) { 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 - } + // token, err := services.CheckExtValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } // 经过测试,linux下,延时需要大于100ms // var TIME_DELAY_AFTER_WRITE time.Duration = 200 // var TIME_DEAD_LINE time.Duration = 10 @@ -214,8 +225,7 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) { } 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) + log.Debugf("method:%s, managementType:%s dbname:%s, tbname:%s pack:%s", r.Method, module, neType, neId[0], pack) var buf [20 * 1024]byte //buf := make([]byte, 0) @@ -250,7 +260,7 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) { } neInfo := new(dborm.NeInfo) - neInfo, err = dborm.XormGetNeInfo(neType, neId[0]) + neInfo, err := dborm.XormGetNeInfo(neType, neId[0]) if err != nil { log.Error("dborm.XormGetNeInfo is failed:", err) services.ResponseInternalServerError500DatabaseOperationFailed(w) @@ -631,11 +641,11 @@ func PostMMLToNF(w http.ResponseWriter, r *http.Request) { 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 - } + // token, err := services.CheckExtValidRequest(w, r) + // if err != nil { + // log.Error("Failed to CheckMmlValidRequest:", err) + // return + // } params := r.URL.Query() neId := params["ne_id"] @@ -646,7 +656,7 @@ func PostMMLToOMC(w http.ResponseWriter, r *http.Request) { } neInfo := new(dborm.NeInfo) - neInfo, err = dborm.XormGetNeInfo("OMC", neId[0]) + neInfo, err := dborm.XormGetNeInfo("OMC", neId[0]) if err != nil { log.Error("dborm.XormGetNeInfo is failed:", err) services.ResponseInternalServerError500DatabaseOperationFailed(w) @@ -670,7 +680,7 @@ func PostMMLToOMC(w http.ResponseWriter, r *http.Request) { MmlHome: config.GetYamlConfig().MML.MmlHome, Limit: 50, User: "", - SessionToken: token, // 旧token + SessionToken: "", // 旧token Authorization: r.Header.Get(tokenConst.HEADER_KEY), // 请求Token HttpUri: hostUri, UserAgent: config.GetDefaultUserAgent(), diff --git a/features/pm/performance.go b/features/pm/performance.go index 096e021..6f17fcd 100644 --- a/features/pm/performance.go +++ b/features/pm/performance.go @@ -8,6 +8,7 @@ import ( "math" "net/http" "strconv" + "strings" "time" "be.ems/lib/dborm" @@ -63,6 +64,26 @@ type GoldKpi struct { Timestamp string `json:"timestamp"` } +type KpiData struct { + ID int `json:"id" xorm:"pk 'id' '<-' autoincr"` + NEType string `json:"neType" xorm:"ne_type"` + NEName string `json:"neName" xorm:"ne_name"` + RmUid string `json:"rmUid" xorm:"rm_uid"` + Date string `json:"date" xorm:"date"` + StartTime time.Time `json:"startTime" xorm:"start_time"` + EndTime time.Time `json:"endTime" xorm:"end_time"` + Index int `json:"index" xorm:"index"` + Granularity int8 `json:"granularity" xorm:"granularity"` + KPIValues []KPIVal `json:"kpiValues" xorm:"json 'kpi_values'"` + //CreatedAt int64 `json:"createdAt" xorm:"created 'created_at'"` + CreatedAt int64 `json:"createdAt" xorm:"'created_at'"` +} +type KPIVal struct { + KPIID string `json:"kpi_id" xorm:"kpi_id"` + Value int64 `json:"value" xorm:"value"` + Err string `json:"err" xorm:"err"` +} + var ( // performance management PerformanceUri = config.DefaultUriPrefix + "/performanceManagement/{apiVersion}/elementType/{elementTypeValue}/objectType/kpiReport/{index}" @@ -96,9 +117,9 @@ type DatabaseClient struct { var DbClient DatabaseClient -func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error { - DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbUser, dbPassword, dbHost, dbPort, dbName) +func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName, dbParam string) error { + DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s", + dbUser, dbPassword, dbHost, dbPort, dbName, dbParam) DbClient.dbType = dbType DbClient.dbConnMaxLifetime = 0 DbClient.dbMaxIdleConns = 0 @@ -106,8 +127,7 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err if log.GetLevel() == log.LOG_TRACE { DbClient.IsShowSQL = true } - log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbType, dbUser, dbHost, dbPort, dbName) + log.Debugf("dbType:%s dbUrl:%s:", dbType, DbClient.dbUrl) var err error DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl) @@ -118,11 +138,28 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime) DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns) DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns) + DbClient.XEngine.DatabaseTZ = time.Local // 必须 + DbClient.XEngine.TZLocation = time.Local // 必须 if DbClient.IsShowSQL { DbClient.XEngine.ShowSQL(true) } xEngine = DbClient.XEngine + // exist, err := xEngine.IsTableExist("kpi_report") + // if err != nil { + // log.Error("Failed to IsTableExist:", err) + // return err + // } + // if exist { + // // 复制表结构到新表 + // sql := fmt.Sprintf("CREATE TABLE IF NOT EXISTS `%s` AS SELECT * FROM kpi_report WHERE 1=0", "kpi_report_amf") + // _, err := xEngine.Exec(sql) + // if err != nil { + // log.Error("Failed to Exec:", err) + // return err + // } + // } + return nil } @@ -203,12 +240,34 @@ func PostKPIReportFromNF(w http.ResponseWriter, r *http.Request) { "startIndex": goldKpi.Index, "timeGroup": goldKpi.StartTime, } + // insert into new kpi_report_xxx table + kpiData := new(KpiData) + kpiData.Date = goldKpi.Date + kpiData.Index = goldKpi.Index + st, _ := time.ParseInLocation(time.RFC3339Nano, kpiReport.Task.Period.StartTime, time.Local) + et, _ := time.ParseInLocation(time.RFC3339Nano, kpiReport.Task.Period.EndTime, time.Local) + // kpiData.StartTime = goldKpi.StartTime + // kpiData.EndTime = goldKpi.EndTime + kpiData.StartTime = st + kpiData.EndTime = et + kpiData.Granularity = goldKpi.Granularity + kpiData.NEName = goldKpi.NEName + kpiData.NEType = goldKpi.NEType + kpiData.RmUid = goldKpi.RmUid + kpiVal := new(KPIVal) + kpiData.CreatedAt = time.Now().UnixMilli() for _, k := range kpiReport.Task.NE.KPIs { kpiEvent[k.KPIID] = k.Value // kip_id goldKpi.KpiId = k.KPIID goldKpi.Value = k.Value goldKpi.Error = k.Err - log.Trace("goldKpi:", goldKpi) + + kpiVal.KPIID = k.KPIID + kpiVal.Value = int64(k.Value) + kpiVal.Err = k.Err + kpiData.KPIValues = append(kpiData.KPIValues, *kpiVal) + + //log.Trace("goldKpi:", goldKpi) // 启动事务 err := session.Begin() @@ -242,10 +301,22 @@ func PostKPIReportFromNF(w http.ResponseWriter, r *http.Request) { } } + // insert kpi_report table, no session + tableName := "kpi_report_" + strings.ToLower(kpiReport.Task.NE.NeType) + affected, err := xEngine.Table(tableName).Insert(kpiData) + if err != nil && affected <= 0 { + log.Errorf("Failed to insert %s:%v", tableName, err) + services.ResponseInternalServerError500ProcessError(w, err) + return + } + // 推送到ws订阅组 wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_KPI, kpiEvent) + if goldKpi.NEType == "UPF" { + wsService.NewWSSendImpl.ByGroupID(wsService.GROUP_KPI_UPF, kpiEvent) + } - services.ResponseStatusOK200Null(w) + services.ResponseStatusOK204NoContent(w) } type MeasureTask struct { @@ -409,11 +480,11 @@ func PostMeasureReportFromNF(w http.ResponseWriter, r *http.Request) { func PostMeasureTaskToNF(w http.ResponseWriter, r *http.Request) { log.Debug("PostMeasureTaskToNF processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -585,11 +656,11 @@ func PutMeasureTaskToNF(w http.ResponseWriter, r *http.Request) { func DeleteMeasureTaskToNF(w http.ResponseWriter, r *http.Request) { log.Debug("DeleteMeasureTaskToNF processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -716,11 +787,11 @@ func DeleteMeasureTaskToNF(w http.ResponseWriter, r *http.Request) { func PatchMeasureTaskToNF(w http.ResponseWriter, r *http.Request) { log.Debug("PatchMeasureTaskToNF processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) neType := vars["elementTypeValue"] @@ -912,11 +983,11 @@ func PostMeasurementFromNF(w http.ResponseWriter, r *http.Request) { func GetMeasurementFromNF(w http.ResponseWriter, r *http.Request) { log.Debug("GetMeasurementFromNF processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } vars := mux.Vars(r) apiVer := vars["apiVersion"] @@ -944,7 +1015,7 @@ func GetMeasurementFromNF(w http.ResponseWriter, r *http.Request) { //var neInfo *dborm.NeInfo neInfo := new(dborm.NeInfo) - neInfo, err = dborm.XormGetNeInfo(neType, neIds[0]) + neInfo, err := dborm.XormGetNeInfo(neType, neIds[0]) if err != nil { log.Error("dborm.XormGetNeInfo is failed:", err) services.ResponseInternalServerError500DatabaseOperationFailed(w) diff --git a/features/security/account.go b/features/security/account.go index 0681bc8..c1190fc 100644 --- a/features/security/account.go +++ b/features/security/account.go @@ -150,11 +150,11 @@ func LoginFromOMC(w http.ResponseWriter, r *http.Request) { func LogoutFromOMC(w http.ResponseWriter, r *http.Request) { log.Info("LogoutFromOMC processing... ") - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } // // check media type(content type) only support "application/json" // if services.IsVallidContentType(r, config.GetYamlConfig().OMC.CheckContentType) == false { // log.Error("Invalid Content-Type") @@ -178,14 +178,14 @@ func LogoutFromOMC(w http.ResponseWriter, r *http.Request) { // return // } - se, err := dborm.XormLogoutUpdateSession(token) - if err != nil { - log.Error("Uri is invalid") - services.ResponseNotFound404UriNotExist(w, r) - return - } + // se, err := dborm.XormLogoutUpdateSession(token) + // if err != nil { + // log.Error("Uri is invalid") + // services.ResponseNotFound404UriNotExist(w, r) + // return + // } // 清除缓存用户信息 - account.ClearLoginUser(se.AccountId) + // account.ClearLoginUser(se.AccountId) services.ResponseStatusOK200Null(w) } diff --git a/features/sm/backup.go b/features/sm/backup.go index 2216a85..a946de8 100644 --- a/features/sm/backup.go +++ b/features/sm/backup.go @@ -29,11 +29,11 @@ type OMCLocalTime struct { func GetOMCLocalTime(w http.ResponseWriter, r *http.Request) { log.Debug("GetOMCLocalTime processing... ") - _, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Http request error:", err) - return - } + // _, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Http request error:", err) + // return + // } t := time.Now() _, offset := t.Zone() diff --git a/features/state/getstate.go b/features/state/getstate.go index 3092542..f41627f 100644 --- a/features/state/getstate.go +++ b/features/state/getstate.go @@ -192,12 +192,12 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) { services.ResponseNotFound404UriNotExist(w, r) return } - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("AccessToken:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("AccessToken:", token) neInfo, err := dborm.XormGetNeInfo(neType, neId) if err != nil { @@ -247,7 +247,7 @@ func GetOneLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) @@ -310,15 +310,15 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) { data := make([]map[string]interface{}, 0) - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("AccessToken:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("AccessToken:", token) var neList []dborm.NeInfo - _, err = dborm.XormGetAllNeInfo(&neList) + _, err := dborm.XormGetAllNeInfo(&neList) if err != nil { log.Error("Failed to XormGetAllNeInfo:", err) services.ResponseInternalServerError500ProcessError(w, err) @@ -363,7 +363,7 @@ func GetAllLicenseInfoFromNF(w http.ResponseWriter, r *http.Request) { resp, err := client.SetTimeout(time.Duration(1 * time.Second)).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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) @@ -434,12 +434,12 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) { services.ResponseNotFound404UriNotExist(w, r) return } - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("AccessToken:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("AccessToken:", token) neInfo, err := dborm.XormGetNeInfo(neType, neId) if err != nil { @@ -489,7 +489,7 @@ func GetOneSysinfoFromNF(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) @@ -581,15 +581,15 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) { data := make([]map[string]interface{}, 0) - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("AccessToken:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("AccessToken:", token) var neList []dborm.NeInfo - _, err = dborm.XormGetAllNeInfo(&neList) + _, err := dborm.XormGetAllNeInfo(&neList) if err != nil { log.Error("Failed to XormGetAllNeInfo:", err) services.ResponseInternalServerError500ProcessError(w, err) @@ -634,7 +634,7 @@ func GetAllSysinfoFromNF(w http.ResponseWriter, r *http.Request) { resp, err := client.SetTimeout(time.Duration(1 * time.Second)).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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) @@ -846,18 +846,19 @@ func GetStateFromNFOld(w http.ResponseWriter, r *http.Request) { services.ResponseNotFound404UriNotExist(w, r) return } - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("AccessToken:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("AccessToken:", token) switch strings.ToLower(neType) { case "all": // query all NFs // create rest client - restHostPort := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port) + + restHostPort := config.GetOMCHostUrl() getNeInfoPattern := fmt.Sprintf(config.DefaultUriPrefix+"/databaseManagement/v1/elementType/%s/objectType/ne_info", config.GetYamlConfig().Database.Name) getNeInfoURI := restHostPort + getNeInfoPattern + "?WHERE=status+in+('0','3')" @@ -866,7 +867,7 @@ func GetStateFromNFOld(w http.ResponseWriter, r *http.Request) { 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{"AccessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(getNeInfoURI) @@ -878,7 +879,7 @@ func GetStateFromNFOld(w http.ResponseWriter, r *http.Request) { neList, _ = dborm.XormParseResult(resp.Body()) default: - restHostPort := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port) + restHostPort := config.GetOMCHostUrl() getNeInfoPattern := fmt.Sprintf(config.DefaultUriPrefix+"/databaseManagement/v1/elementType/%s/objectType/ne_info", config.GetYamlConfig().Database.Name) getNeInfoURI := restHostPort + getNeInfoPattern @@ -893,7 +894,7 @@ func GetStateFromNFOld(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(getNeInfoURI) @@ -924,7 +925,7 @@ func GetStateFromNFOld(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) diff --git a/features/trace/trace.go b/features/trace/trace.go index eec2472..73a8c82 100644 --- a/features/trace/trace.go +++ b/features/trace/trace.go @@ -67,12 +67,12 @@ func PostTraceTaskToNF(w http.ResponseWriter, r *http.Request) { //vars := mux.Vars(r) - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("AccessToken:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("AccessToken:", token) body, err := io.ReadAll(io.LimitReader(r.Body, int64(config.GetYamlConfig().Params.UriMaxLen))) if err != nil { @@ -194,12 +194,12 @@ func PutTraceTaskToNF(w http.ResponseWriter, r *http.Request) { //vars := mux.Vars(r) - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("AccessToken:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("AccessToken:", token) body, err := io.ReadAll(io.LimitReader(r.Body, int64(config.GetYamlConfig().Params.UriMaxLen))) if err != nil { @@ -311,17 +311,17 @@ func PutTraceTaskToNF(w http.ResponseWriter, r *http.Request) { func DeleteTraceTaskToNF(w http.ResponseWriter, r *http.Request) { log.Debug("DeleteTraceTaskToNF processing... ") - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("AccessToken:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("AccessToken:", token) vars := r.URL.Query() ids, ok := vars["id"] if !ok || len(ids) == 0 { - err = global.ErrTraceNotCarriedTaskID + err := global.ErrTraceNotCarriedTaskID log.Error(err) services.ResponseInternalServerError500ProcessError(w, err) return @@ -332,7 +332,7 @@ func DeleteTraceTaskToNF(w http.ResponseWriter, r *http.Request) { log.Debug("id:", id) var succNes []string - err = dborm.XormGetColStringArrayByWhere("trace_task", "succ_nes", fmt.Sprintf("id=%s", id), &succNes) + err := dborm.XormGetColStringArrayByWhere("trace_task", "succ_nes", fmt.Sprintf("id=%s", id), &succNes) if err != nil { log.Error("Failed to dborm.XormGetSingleColStringArrayByWhere:", err) services.ResponseInternalServerError500ProcessError(w, err) diff --git a/features/ue/ue.go b/features/ue/ue.go index e8e93d7..279e24b 100644 --- a/features/ue/ue.go +++ b/features/ue/ue.go @@ -46,6 +46,7 @@ type SmfUEInfo struct { UpfN3IP string `json:"upfN3IP"` RanN3IP string `json:"ranN3IP"` Activetime string `json:"activeTime"` + UpState string `json:"upState"` } `json:"pduSessionInfo"` } @@ -130,12 +131,12 @@ func GetAvailableAMFsFromNSSF(w http.ResponseWriter, r *http.Request) { return } - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("token:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("token:", token) neInfo, err := dborm.XormGetNeInfo(neType, neId) if err != nil { @@ -158,7 +159,7 @@ func GetAvailableAMFsFromNSSF(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) @@ -194,12 +195,12 @@ func GetSubscriptionsFromNSSF(w http.ResponseWriter, r *http.Request) { return } - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("token:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("token:", token) neInfo, err := dborm.XormGetNeInfo(neType, neId) if err != nil { @@ -222,7 +223,7 @@ func GetSubscriptionsFromNSSF(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) @@ -258,12 +259,12 @@ func GetUEInfoFromNF(w http.ResponseWriter, r *http.Request) { return } - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("token:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("token:", token) neInfo, err := dborm.XormGetNeInfo(neType, neId) if err != nil { @@ -286,7 +287,7 @@ func GetUEInfoFromNF(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) @@ -535,12 +536,12 @@ func GetUENumFromNF(w http.ResponseWriter, r *http.Request) { return } - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("token:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("token:", token) neInfo, err := dborm.XormGetNeInfo(neType, neId) if err != nil { @@ -563,7 +564,7 @@ func GetUENumFromNF(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) @@ -599,12 +600,12 @@ func GetNBInfoFromNF(w http.ResponseWriter, r *http.Request) { return } - token, err := services.CheckFrontValidRequest(w, r) - if err != nil { - log.Error("Request error:", err) - return - } - log.Debug("token:", token) + // token, err := services.CheckFrontValidRequest(w, r) + // if err != nil { + // log.Error("Request error:", err) + // return + // } + // log.Debug("token:", token) neInfo, err := dborm.XormGetNeInfo(neType, neId) if err != nil { @@ -627,7 +628,7 @@ func GetNBInfoFromNF(w http.ResponseWriter, r *http.Request) { 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{"accessToken": token}). SetHeaders(map[string]string{"User-Agent": config.GetDefaultUserAgent()}). SetHeaders(map[string]string{"Content-Type": "application/json;charset=UTF-8"}). Get(requestURI2NF) diff --git a/go.mod b/go.mod index 59f2b71..0dc59fa 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/dlclark/regexp2 v1.10.0 github.com/gin-gonic/gin v1.9.1 + github.com/go-admin-team/go-admin-core/sdk v1.5.1 github.com/go-gsm/ucp v0.0.1 github.com/go-resty/resty/v2 v2.7.0 github.com/go-sql-driver/mysql v1.7.1 @@ -16,21 +17,27 @@ require ( github.com/gorilla/mux v1.8.0 github.com/gorilla/websocket v1.5.0 github.com/gosnmp/gosnmp v1.35.0 + github.com/jasonlvhit/gocron v0.0.1 github.com/lestrrat/go-file-rotatelogs v0.0.0-20180223000712-d3151e2a480f github.com/linxGnu/gosmpp v0.2.0 github.com/matoous/go-nanoid/v2 v2.0.0 + github.com/metaleap/go-xsd v0.0.0-20180330193350-61f7638f502f github.com/mojocn/base64Captcha v1.3.5 github.com/mssola/user_agent v0.6.0 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/prometheus-community/pro-bing v0.4.0 github.com/redis/go-redis/v9 v9.1.0 + github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e github.com/robfig/cron/v3 v3.0.1 github.com/shirou/gopsutil v3.21.11+incompatible github.com/shirou/gopsutil/v3 v3.23.7 github.com/spf13/afero v1.9.5 github.com/spf13/viper v1.16.0 github.com/xuri/excelize/v2 v2.7.1 + github.com/xuri/xgen v0.0.0-20230702070049-db840e1a4605 + github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b golang.org/x/crypto v0.19.0 + golang.org/x/term v0.17.0 gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df gopkg.in/yaml.v3 v3.0.1 gorm.io/driver/mysql v1.5.1 @@ -39,52 +46,77 @@ require ( ) require ( + github.com/creack/pty v1.1.9 // indirect + github.com/go-admin-team/go-admin-core v1.3.12-0.20221121065133-27b7dbe27a8f // indirect github.com/go-gsm/charset v1.0.0 // indirect - github.com/mattn/go-sqlite3 v1.14.15 // indirect - github.com/onsi/ginkgo v1.16.5 // indirect - github.com/onsi/gomega v1.21.1 // indirect golang.org/x/sync v0.6.0 // indirect golang.org/x/time v0.1.0 // indirect ) require ( + github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible // indirect + github.com/bsm/redislock v0.8.2 // indirect + github.com/bytedance/go-tagexpr/v2 v2.7.12 // indirect github.com/bytedance/sonic v1.9.1 // indirect + github.com/casbin/casbin/v2 v2.54.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/chanxuehong/rand v0.0.0-20201110082127-2f19a1bdd973 // indirect + github.com/chanxuehong/wechat v0.0.0-20201110083048-0180211b69fd // indirect github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect + github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 // indirect + github.com/fatih/color v1.13.0 // indirect github.com/fsnotify/fsnotify v1.6.0 // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect github.com/gin-contrib/sse v0.1.0 // indirect + github.com/git-chglog/git-chglog v0.0.0-20190611050339-63a4e637021f // indirect + github.com/go-admin-team/redisqueue/v2 v2.0.0-20221119141731-97c556b0d5b7 // indirect + github.com/go-forks/fsnotify v1.4.7 // indirect github.com/go-ole/go-ole v1.2.6 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/go-playground/validator/v10 v10.14.0 // indirect + github.com/go-redis/redis/v8 v8.11.5 // indirect + github.com/go-redis/redis/v9 v9.0.0-rc.1 // indirect github.com/goccy/go-json v0.10.2 github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/golang/snappy v0.0.4 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/henrylee2cn/ameda v1.4.10 // indirect + github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 // indirect + github.com/imdario/mergo v0.3.9 // indirect github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/json-iterator/go v1.1.12 // indirect + github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect github.com/klauspost/cpuid/v2 v2.2.4 // indirect github.com/leodido/go-urn v1.2.4 // indirect github.com/lestrrat/go-envload v0.0.0-20180220120943-6ed08b54a570 // indirect github.com/lestrrat/go-strftime v0.0.0-20180220042222-ba3bf9c1d042 // indirect github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect github.com/magiconair/properties v1.8.7 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/goveralls v0.0.2 // indirect + github.com/metaleap/go-util v0.0.0-20180330192724-a09253046f73 // indirect + github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect + github.com/nsqio/go-nsq v1.0.8 // indirect + github.com/nyaruka/phonenumbers v1.0.55 // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c // indirect + github.com/reiver/go-oi v1.0.0 // indirect github.com/richardlehane/mscfb v1.0.4 // indirect github.com/richardlehane/msoleps v1.0.3 // indirect + github.com/russross/blackfriday/v2 v2.1.0 // indirect github.com/shoenig/go-m1cpu v0.1.6 // indirect github.com/spf13/cast v1.5.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect @@ -94,8 +126,10 @@ require ( github.com/tebeka/strftime v0.1.5 // indirect github.com/tklauser/go-sysconf v0.3.11 // indirect github.com/tklauser/numcpus v0.6.0 // indirect + github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df // indirect github.com/twitchyliquid64/golang-asm v0.15.1 // indirect github.com/ugorji/go/codec v1.2.11 // indirect + github.com/urfave/cli v1.22.1 // indirect github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 // indirect github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect @@ -106,8 +140,11 @@ require ( golang.org/x/text v0.14.0 golang.org/x/tools v0.16.1 // indirect google.golang.org/protobuf v1.30.0 // indirect + gopkg.in/AlecAivazis/survey.v1 v1.8.5 // indirect gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/kyokomi/emoji.v1 v1.5.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect xorm.io/builder v0.3.11-0.20220531020008-1bd24a7dc978 // indirect ) diff --git a/go.sum b/go.sum index 2680b44..4e517ec 100644 --- a/go.sum +++ b/go.sum @@ -41,8 +41,11 @@ gitea.com/xorm/sqlfiddle v0.0.0-20180821085327-62ce714f951a/go.mod h1:EXuID2Zs0p gitee.com/travelliu/dm v1.8.11192/go.mod h1:DHTzyhCrM843x9VdKVbZ+GKXGRbKM2sJ4LxihRxShkE= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible h1:1G1pk05UrOh0NlF1oeaaix1x8XzrfjIDK47TY0Zehcw= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8 h1:xzYJEypr/85nBpB11F9br+3HUrpgb+fcm5iADzXXYEw= +github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61PbNXchhh0oikYAH+4Pcfw5LKv21+Jnpr6r6Pc= github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= @@ -68,15 +71,27 @@ github.com/bsm/ginkgo/v2 v2.9.5 h1:rtVBYPs3+TC5iLUVOis1B9tjLTup7Cj5IfzosKtvTJ0= github.com/bsm/ginkgo/v2 v2.9.5/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= github.com/bsm/gomega v1.26.0 h1:LhQm+AFcgV2M0WyKroMASzAzCAJVpAxQXv4SaI9a69Y= github.com/bsm/gomega v1.26.0/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bsm/redislock v0.8.2 h1:W0aDRjt6FNmAZovbG2fPyjl1YZZdlqMkCKKCffJew1o= +github.com/bsm/redislock v0.8.2/go.mod h1:tC0JZxZCdJN4DCB31cGxgjgf/ye1R4LLNJQd5ecjg08= +github.com/bytedance/go-tagexpr/v2 v2.7.12 h1:qL2f0j11S8DHQsUWUA6aacLNBcbPTbNKuzVjaW4kF/M= +github.com/bytedance/go-tagexpr/v2 v2.7.12/go.mod h1:cKpo/rwg2Y5Njs8SX3FspMWEhAWCaF4xUr5LJYXibSU= github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM= github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s= github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U= github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/casbin/casbin/v2 v2.54.0 h1:NFQ3Xkw6rfbD/rwEHMVRHVP5gUxhNQKdcZCb53pwSrA= +github.com/casbin/casbin/v2 v2.54.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chanxuehong/rand v0.0.0-20201110082127-2f19a1bdd973 h1:Js/7nHtkpvUW62passc9FOflXyLQDjSoYclkFeDdTEM= +github.com/chanxuehong/rand v0.0.0-20201110082127-2f19a1bdd973/go.mod h1:9+sJ9zvvkXC5sPjPEZM3Jpb9n2Q2VtcrGZly0UHYF5I= +github.com/chanxuehong/util v0.0.0-20200304121633-ca8141845b13/go.mod h1:XEYt99iTxMqkv+gW85JX/DdUINHUe43Sbe5AtqSaDAQ= +github.com/chanxuehong/wechat v0.0.0-20201110083048-0180211b69fd h1:TM3wjEWel4U31J72dlhnwCBqPC0+FA0Ejm2NCbn5a5U= +github.com/chanxuehong/wechat v0.0.0-20201110083048-0180211b69fd/go.mod h1:/dvhOIRCjjiZu6NV0QTTiMcc5XwoORbxfDSsRY2IfaM= github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams= github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk= @@ -103,7 +118,11 @@ github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM= +github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -130,6 +149,8 @@ github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7 github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239 h1:Ghm4eQYC0nEPnSJdVkTrXpu9KtoVCSo1hg7mtI7G9KU= github.com/fastly/go-utils v0.0.0-20180712184237-d95a45783239/go.mod h1:Gdwt2ce0yfBxPvZrHkprdPPTTS3N5rwmLE8T22KBXlw= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= @@ -145,6 +166,16 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/git-chglog/git-chglog v0.0.0-20190611050339-63a4e637021f h1:8l4Aw3Jmx0pLKYMkY+1b6yBPgE+rzRtA5T3vqFyI2Z8= +github.com/git-chglog/git-chglog v0.0.0-20190611050339-63a4e637021f/go.mod h1:Dcsy1kii/xFyNad5JqY/d0GO5mu91sungp5xotbm3Yk= +github.com/go-admin-team/go-admin-core v1.3.12-0.20221121065133-27b7dbe27a8f h1:2xHpluWqY/ZlYoUpOU8VwDponYSnukRDhkOr7rk3ffU= +github.com/go-admin-team/go-admin-core v1.3.12-0.20221121065133-27b7dbe27a8f/go.mod h1:a9/XW1rCChPLVJ3bST13hB6R8YfVjYeF0GYjb8If6Yg= +github.com/go-admin-team/go-admin-core/sdk v1.5.1 h1:U1VaXuMrMmeLiQyJipqnTxHE84vspaK++wkTWfYpcOI= +github.com/go-admin-team/go-admin-core/sdk v1.5.1/go.mod h1:yNoHmYZtGc1WFWZwhAop0sSyZhsrsSGqvje2yvClXjE= +github.com/go-admin-team/redisqueue/v2 v2.0.0-20221119141731-97c556b0d5b7 h1:p1cq6CN47zEbDt8EWBX3mOZpIa4zVwHCrXcy0NwD+So= +github.com/go-admin-team/redisqueue/v2 v2.0.0-20221119141731-97c556b0d5b7/go.mod h1:XGwBJD4aMmHSoJFPKs4vcW4Y5s+8MV1gHR+P0Uxe9Eg= +github.com/go-forks/fsnotify v1.4.7 h1:lyiU2Wqd4fNGCQDn9dZ4UxSiSFgeU1rM6yIfahk8haY= +github.com/go-forks/fsnotify v1.4.7/go.mod h1:AU8mot+GznW5+B4jRJHxKg/2EeO+jMORGRkKSxs0biw= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -168,6 +199,11 @@ github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJn github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= github.com/go-playground/validator/v10 v10.14.0 h1:vgvQWe3XCz3gIeFDm/HnTIbj6UGmg/+t63MyGU2n5js= github.com/go-playground/validator/v10 v10.14.0/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU= +github.com/go-redis/redis v6.15.5+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= +github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI= +github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo= +github.com/go-redis/redis/v9 v9.0.0-rc.1 h1:/+bS+yeUnanqAbuD3QwlejzQZ+4eqgfUtFTG4b+QnXs= +github.com/go-redis/redis/v9 v9.0.0-rc.1/go.mod h1:8et+z03j0l8N+DvsVnclzjf3Dl/pFHgRk+2Ct1qw66A= github.com/go-resty/resty/v2 v2.7.0 h1:me+K9p3uhSmXtrBZ4k9jcEAfJmuC8IivWHwaLZwPrFY= github.com/go-resty/resty/v2 v2.7.0/go.mod h1:9PWDzw47qPphMRFfhsyk0NnSgvluHcljSMVIq3w7q0I= github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= @@ -186,6 +222,7 @@ github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFG github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= @@ -203,6 +240,8 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -218,6 +257,9 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= @@ -252,6 +294,7 @@ github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -261,6 +304,7 @@ github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= @@ -297,10 +341,20 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/henrylee2cn/ameda v1.4.8/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= +github.com/henrylee2cn/ameda v1.4.10 h1:JdvI2Ekq7tapdPsuhrc4CaFiqw6QXFvZIULWJgQyCAk= +github.com/henrylee2cn/ameda v1.4.10/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4= +github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8 h1:yE9ULgp02BhYIrO6sdV/FPe0xQM6fNHkVQW2IAymfM0= +github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8/go.mod h1:Nhe/DM3671a5udlv2AdV2ni/MZzgfv2qrPL5nIi3EGQ= +github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174 h1:WlZsjVhE8Af9IcZDGgJGQpNflI3+MJSBhsgT5PCtzBQ= +github.com/hinshun/vt10x v0.0.0-20180616224451-1954e6464174/go.mod h1:DqJ97dSdRW1W22yXSB90986pcOyQ7r45iio1KN2ez1A= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/imdario/mergo v0.3.7/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg= +github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= @@ -350,6 +404,8 @@ github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0f github.com/jackc/puddle v1.1.0/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jasonlvhit/gocron v0.0.1 h1:qTt5qF3b3srDjeOIR4Le1LfeyvoYzJlYpqvG7tJX5YU= +github.com/jasonlvhit/gocron v0.0.1/go.mod h1:k9a3TV8VcU73XZxfVHCHWMWF9SOqgoku0/QlY2yvlA4= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -366,11 +422,13 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= github.com/klauspost/cpuid/v2 v2.2.4 h1:acbojRNwl3o09bUq+yDCtZFc1aiwaAAxtcn8YkZXnvk= @@ -384,6 +442,7 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= @@ -417,6 +476,9 @@ github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaO github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= @@ -424,13 +486,22 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= +github.com/mattn/goveralls v0.0.2 h1:7eJB6EqsPhRVxvwEXGnqdO2sJI0PTsrWoTMXEk9/OQc= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/metaleap/go-util v0.0.0-20180330192724-a09253046f73 h1:4vKVhAdype/dejZjdQZZXVTKLz8mD0oakKz128L+IFQ= +github.com/metaleap/go-util v0.0.0-20180330192724-a09253046f73/go.mod h1:l71/5fppWP5A6nqhcxz6wQAYok6pr/vM2+KHIy50/LY= +github.com/metaleap/go-xsd v0.0.0-20180330193350-61f7638f502f h1:eeJGcYszuvOpmuJxeq57LaOO8mJurfjpOHJJMfQSD0s= +github.com/metaleap/go-xsd v0.0.0-20180330193350-61f7638f502f/go.mod h1:WK3zEKtwVd/v+NM3lh1ZE6MdDfHsdOFFOD5Ezi4Hutg= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= +github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -462,20 +533,30 @@ github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzE github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/nsqio/go-nsq v1.0.8 h1:3L2F8tNLlwXXlp2slDUrUWSBn2O3nMh8R1/KEDFTHPk= +github.com/nsqio/go-nsq v1.0.8/go.mod h1:vKq36oyeVXgsS5Q8YEO7WghqidAVXQlcFxzQbQTuDEY= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/nyaruka/phonenumbers v1.0.55 h1:bj0nTO88Y68KeUQ/n3Lo2KgK7lM1hF7L9NFuwcCl3yg= +github.com/nyaruka/phonenumbers v1.0.55/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= +github.com/onsi/ginkgo/v2 v2.0.0/go.mod h1:vw5CSIxN1JObi/U8gcbwft7ZxR2dgaR70JSE3/PpL4c= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= +github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs= github.com/onsi/gomega v1.21.1 h1:OB/euWYIExnPBohllTicTHmGTrMaqJ67nIu80j0/uEM= github.com/onsi/gomega v1.21.1/go.mod h1:iYAIXgPSaDHak0LCMA+AWBpIKBr8WZicMxnE8luStNc= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= @@ -491,6 +572,7 @@ github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIw github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pborman/uuid v1.2.0 h1:J7Q5mO4ysT1dv8hyrUGHb9+ooztCXu1D8MY8DZYsu3g= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ= github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4= @@ -529,6 +611,10 @@ github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+Gx github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/redis/go-redis/v9 v9.1.0 h1:137FnGdk+EQdCbye1FW+qOEcY5S+SpY9T0NiuqvtfMY= github.com/redis/go-redis/v9 v9.1.0/go.mod h1:urWj3He21Dj5k4TK1y59xH8Uj6ATueP8AH1cY3lZl4c= +github.com/reiver/go-oi v1.0.0 h1:nvECWD7LF+vOs8leNGV/ww+F2iZKf3EYjYZ527turzM= +github.com/reiver/go-oi v1.0.0/go.mod h1:RrDBct90BAhoDTxB1fenZwfykqeGvhI6LsNfStJoEkI= +github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e h1:quuzZLi72kkJjl+f5AQ93FMcadG19WkS7MO6TXFOSas= +github.com/reiver/go-telnet v0.0.0-20180421082511-9ff0b2ab096e/go.mod h1:+5vNVvEWwEIx86DB9Ke/+a5wBI464eDRo3eF0LcfpWg= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 h1:OdAsTTz6OkFY5QxjkYwrChwuRruF69c169dPK26NUlk= github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/richardlehane/mscfb v1.0.4 h1:WULscsljNPConisD5hR0+OyZjwK46Pfyr6mPu5ZawpM= @@ -546,6 +632,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= @@ -565,7 +653,9 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= @@ -589,6 +679,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+ github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.2.1/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= @@ -608,16 +699,22 @@ github.com/syndtr/goleveldb v1.0.0 h1:fBdIW9lB4Iz0n9khmH8w27SJ3QEJ7+IgjPEwGSZiFd github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= github.com/tebeka/strftime v0.1.5 h1:1NQKN1NiQgkqd/2moD6ySP/5CoZQsKa1d3ZhJ44Jpmg= github.com/tebeka/strftime v0.1.5/go.mod h1:29/OidkoWHdEKZqzyDLUyC+LmgDgdHo4WAFCDT7D/Ig= +github.com/tidwall/gjson v1.6.0/go.mod h1:P256ACg0Mn+j1RXIDXoss50DeIABTYK1PULOJHhxOls= +github.com/tidwall/match v1.0.1/go.mod h1:LujAq0jyVjBy028G1WhWfIzbpQfMO8bBZ6Tyb0+pL9E= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tklauser/go-sysconf v0.3.11 h1:89WgdJhk5SNwJfu+GKyYveZ4IaJ7xAkecBo+KdJV0CM= github.com/tklauser/go-sysconf v0.3.11/go.mod h1:GqXfhXY3kiPa0nAXPDIQIWzJbMCB7AmcWpGR8lSZfqI= github.com/tklauser/numcpus v0.6.0 h1:kebhY2Qt+3U6RNK7UqpYNA+tJ23IBEGKkB7JQBfDYms= github.com/tklauser/numcpus v0.6.0/go.mod h1:FEZLMke0lhOUG6w2JadTzp0a+Nl8PF/GFkQ5UVIcaL4= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df h1:Y2l28Jr3vOEeYtxfVbMtVfOdAwuUqWaP9fvNKiBVeXY= +github.com/tsuyoshiwada/go-gitcmd v0.0.0-20180205145712-5f1f5f9475df/go.mod h1:pnyouUty/nBr/zm3GYwTIt+qFTLWbdjeLjZmJdzJOu8= github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU= github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1 h1:+mkCCcOFKPnCmVYVcURKps1Xe+3zP90gSYGNfRkjoIY= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xuri/efp v0.0.0-20220603152613-6918739fd470 h1:6932x8ltq1w4utjmfMPVj09jdMlkY0aiA6+Skbtl3/c= @@ -626,6 +723,8 @@ github.com/xuri/excelize/v2 v2.7.1 h1:gm8q0UCAyaTt3MEF5wWMjVdmthm2EHAWesGSKS9tdV github.com/xuri/excelize/v2 v2.7.1/go.mod h1:qc0+2j4TvAUrBw36ATtcTeC1VCM0fFdAXZOmcF4nTpY= github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22 h1:OAmKAfT06//esDdpi/DZ8Qsdt4+M5+ltca05dA5bG2M= github.com/xuri/nfp v0.0.0-20220409054826-5e722a1d9e22/go.mod h1:WwHg+CVyzlv/TX9xqBFXEZAuxOPxn2k1GNHwG41IIUQ= +github.com/xuri/xgen v0.0.0-20230702070049-db840e1a4605 h1:urU5p/tQOOUd9B0c6O+6aBk7udJI5HcN4VYmX2tMTcI= +github.com/xuri/xgen v0.0.0-20230702070049-db840e1a4605/go.mod h1:tBkmlRf8JH62H5fAW+BPFj0LNZWRmKglWTLFfpXhhbg= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -635,6 +734,8 @@ github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFi github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= +github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b h1:VfPXB/wCGGt590QhD1bOpv2J/AmC/RJNTg/Q59HKSB0= +github.com/ziutek/telnet v0.0.0-20180329124119-c3b780dc415b/go.mod h1:IZpXDfkJ6tWD3PhBK5YzgQT+xJWh7OsdwiG8hA2MkO4= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= @@ -661,6 +762,7 @@ golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k= golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190123085648-057139ce5d2b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= @@ -762,10 +864,12 @@ golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4= golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= @@ -792,6 +896,7 @@ golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20180606202747-9527bec2660b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -849,8 +954,11 @@ golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210902050250-f475640dd07b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -891,6 +999,7 @@ golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -1052,8 +1161,11 @@ google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpAD google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/AlecAivazis/survey.v1 v1.8.5 h1:QoEEmn/d5BbuPIL2qvXwzJdttFFhRQFkaq+tEKb7SMI= +gopkg.in/AlecAivazis/survey.v1 v1.8.5/go.mod h1:iBNOmqKz/NUbZx3bA+4hAGLRC7fSK7tgtVDT4tB22XA= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk= gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk= @@ -1070,6 +1182,8 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkp gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/kyokomi/emoji.v1 v1.5.1 h1:beetH5mWDMzFznJ+Qzd5KVHp79YKhVUMcdO8LpRLeGw= +gopkg.in/kyokomi/emoji.v1 v1.5.1/go.mod h1:N9AZ6hi1jHOPn34PsbpufQZUcKftSD7WgS2pgpmH4Lg= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= @@ -1079,7 +1193,10 @@ gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw= diff --git a/lib/core/utils/ctx/ctx.go b/lib/core/utils/ctx/ctx.go index dfbbe92..fefb6b4 100644 --- a/lib/core/utils/ctx/ctx.go +++ b/lib/core/utils/ctx/ctx.go @@ -10,9 +10,9 @@ import ( "path/filepath" "strings" - "be.ems/lib/core/vo" - commonConstants "be.ems/src/framework/constants/common" - tokenConst "be.ems/src/framework/constants/token" + "be.ems/src/framework/constants/token" + tokenUtils "be.ems/src/framework/utils/token" + "be.ems/src/framework/vo" "github.com/gorilla/mux" "golang.org/x/text/language" ) @@ -122,12 +122,26 @@ func SaveUploadedFile(r *http.Request, dst string) error { // Authorization 解析请求头 func Authorization(r *http.Request) string { - authHeader := r.Header.Get(tokenConst.HEADER_KEY) + // Query请求查询 + if authQuery := r.URL.Query().Get(token.ACCESS_TOKEN); authQuery != "" { + return authQuery + } + // Header请求头 + if authHeader := r.Header.Get(token.ACCESS_TOKEN); authHeader != "" { + return authHeader + } + + // Query请求查询 + if authQuery := r.URL.Query().Get(token.RESPONSE_FIELD); authQuery != "" { + return authQuery + } + // Header请求头 + authHeader := r.Header.Get(token.HEADER_KEY) if authHeader == "" { return "" } // 拆分 Authorization 请求头,提取 JWT 令牌部分 - arr := strings.Split(authHeader, tokenConst.HEADER_PREFIX) + arr := strings.Split(authHeader, token.HEADER_PREFIX) if len(arr) == 2 && arr[1] == "" { return "" } @@ -164,12 +178,24 @@ type ContextKey string // LoginUser 登录用户信息需要Authorize中间件 func LoginUser(r *http.Request) (vo.LoginUser, error) { - // 上下文 - v := r.Context().Value(ContextKey(commonConstants.CTX_LOGIN_USER)) - if v != nil { - return v.(vo.LoginUser), nil + // 获取请求头标识信息 + tokenStr := Authorization(r) + if tokenStr == "" { + return vo.LoginUser{}, fmt.Errorf("not token info") } - return vo.LoginUser{}, fmt.Errorf("No user information") + // 验证令牌 + claims, err := tokenUtils.Verify(tokenStr) + if err != nil { + return vo.LoginUser{}, fmt.Errorf("token verify fail") + } + + // 获取缓存的用户信息 + loginUser := tokenUtils.LoginUser(claims) + if loginUser.UserID == "" { + return vo.LoginUser{}, fmt.Errorf("not user info") + } + + return loginUser, nil } // LoginUserToUserID 登录用户信息-用户ID @@ -187,5 +213,5 @@ func LoginUserToUserName(r *http.Request) string { if err != nil { return "" } - return loginUser.UserName + return loginUser.User.UserName } diff --git a/lib/dborm/dborm.go b/lib/dborm/dborm.go index 102e410..7455aea 100644 --- a/lib/dborm/dborm.go +++ b/lib/dborm/dborm.go @@ -45,9 +45,9 @@ type DatabaseClient struct { var DbClient DatabaseClient -func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) error { - DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbUser, dbPassword, dbHost, dbPort, dbName) +func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName, dbParam string) error { + DbClient.dbUrl = fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?%s", + dbUser, dbPassword, dbHost, dbPort, dbName, dbParam) DbClient.dbType = dbType DbClient.dbConnMaxLifetime = 0 DbClient.dbMaxIdleConns = 0 @@ -55,8 +55,7 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err if log.GetLevel() == log.LOG_TRACE { DbClient.IsShowSQL = true } - log.Debugf("dbType:%s dbUrl:%s:******@tcp(%s:%s)/%s??charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=true&loc=Local", - dbType, dbUser, dbHost, dbPort, dbName) + log.Debugf("dbType:%s dbUrl:%s:", dbType, DbClient.dbUrl) var err error DbClient.XEngine, err = xorm.NewEngine(DbClient.dbType, DbClient.dbUrl) @@ -67,9 +66,12 @@ func InitDbClient(dbType, dbUser, dbPassword, dbHost, dbPort, dbName string) err DbClient.XEngine.SetConnMaxLifetime(DbClient.dbConnMaxLifetime) DbClient.XEngine.SetMaxIdleConns(DbClient.dbMaxIdleConns) DbClient.XEngine.SetMaxOpenConns(DbClient.dbMaxOpenConns) + DbClient.XEngine.DatabaseTZ = time.Local // 必须 + DbClient.XEngine.TZLocation = time.Local // 必须 if DbClient.IsShowSQL { DbClient.XEngine.ShowSQL(true) } + xEngine = DbClient.XEngine return nil @@ -180,20 +182,20 @@ func InsertDataWithJson(insertData interface{}) (int64, error) { } type NeInfo struct { - Id int `json:"id" xorm:"pk 'id' autoincr"` - NeType string `json:"neType" xorm:"ne_type"` - NeId string `json:"neId" xorm:"ne_id"` // neUID/rmUID 网元唯一标识 - RmUID string `json:"rmUid" xorm:"rm_uid"` // neUID/rmUID网元UID - NeName string `json:"neName" xorm:"ne_name"` // NeName/UserLabel 网元名称/网元设备友好名称 - Ip string `json:"ip" xorm:"ip"` - Port string `json:"port" xorm:"port"` - PvFlag string `json:"pvFlag" xorm:"pv_flag"` // 网元虚实性标识 VNF/PNF: 虚拟/物理 - NeAddress string `json:"neAddress" xorm:"ne_address"` // 只对PNF - Province string `json:"province" xorm:"province"` // 网元所在省份 - VendorName string `json:"vendorName" xorm:"vendor_name"` // 厂商名称 - Dn string `json:"dn" xorm:"dn"` // 网络标识 - Status int `json:"status" xorm:"status"` - UpdateTime string `json:"-" xorm:"-"` + Id int `json:"id" xorm:"pk 'id' autoincr"` + NeType string `json:"neType" xorm:"ne_type"` + NeId string `json:"neId" xorm:"ne_id"` // neUID/rmUID 网元唯一标识 + RmUID string `json:"rmUid" xorm:"rm_uid"` // neUID/rmUID网元UID + NeName string `json:"neName" xorm:"ne_name"` // NeName/UserLabel 网元名称/网元设备友好名称 + Ip string `json:"ip" xorm:"ip"` + Port string `json:"port" xorm:"port"` + PvFlag string `json:"pvFlag" xorm:"pv_flag"` // 网元虚实性标识 VNF/PNF: 虚拟/物理 + NeAddress string `json:"neAddress" xorm:"ne_address"` // 只对PNF + Province string `json:"province" xorm:"province"` // 网元所在省份 + VendorName string `json:"vendorName" xorm:"vendor_name"` // 厂商名称 + Dn string `json:"dn" xorm:"dn"` // 网络标识 + Status int `json:"status" xorm:"status"` + UpdateTime time.Time `json:"updateTime" xorm:"<-"` } func XormGetMySQLVersion() (string, error) { @@ -1424,7 +1426,7 @@ type NeVersion struct { } func XormGetDataBySQL(sql string) (*[]map[string]string, error) { - log.Debug("XormGetDataBySQL processing... ") + //log.Debug("XormGetDataBySQL processing... ") rows := make([]map[string]string, 0) rows, err := DbClient.XEngine.QueryString(sql) @@ -1451,6 +1453,15 @@ func XormDeleteDataByWhere(where, table string) (int64, error) { return affected, nil } +func XormDeleteDataByWhereNoSession(where, table string) (int64, error) { + affected, err := DbClient.XEngine.Table(table).Where(where).Delete() + if err != nil { + log.Error("Failed to Delete:", err) + return 0, err + } + return affected, nil +} + func XormDeleteDataById(id int, table string) (int64, error) { log.Debug("XormDeleteDataByWhere processing... ") @@ -1632,9 +1643,10 @@ type AlarmForwardLog struct { AlarmTitle string `json:"alarmTitle" xorm:"alarm_title"` AlarmSeq int `json:"alarmSeq" xorm:"alarm_seq"` EventTime string `json:"eventTime" xorm:"event_time"` + Interface string `json:"interface" xorm:"interface"` ToUser string `json:"toUser" xorm:"to_user"` OperResult string `json:"operResult" xorm:"oper_result"` - LogTime string `json:"-" xorm:"-"` + LogTime string `json:"logTime" xorm:"<-"` } func XormInsertAlarmForwardLog(logData *AlarmForwardLog) (int64, error) { @@ -1669,7 +1681,7 @@ func XormInsertSystemLog(logData *SystemLog) (int64, error) { return affected, err } -type permission struct { +type Permission struct { ID int `json:"-" xorm:"pk 'id' autoincr"` PermissionName string `json:"permissionName"` Method string `json:"method"` diff --git a/lib/midware/mml_log.go b/lib/midware/mml_log.go index a28be1b..9171147 100644 --- a/lib/midware/mml_log.go +++ b/lib/midware/mml_log.go @@ -12,7 +12,6 @@ import ( "be.ems/lib/core/datasource" "be.ems/lib/core/utils/ctx" "be.ems/lib/core/utils/date" - "be.ems/lib/dborm" "be.ems/lib/log" ) @@ -50,19 +49,12 @@ func LogMML(next http.Handler) http.Handler { resultStr := fmt.Sprintf(`{"status":"%s","size":"%s","content-type":"%s"}`, status, size, contentType) // 用户名 - username := "-" - accessToken := r.Header.Get("AccessToken") - if accessToken != "" { - // 验证令牌 == 这里直接查数据库session - se, _ := dborm.XormUpdateSessionShakeTime(accessToken) - username = se.AccountId - } - + username := ctx.LoginUserToUserName(r) // 执行插入 sql := "insert into mml_log (user,ip,ne_type,ne_id,mml,result,log_time)values(?,?,?,?,?,?,?)" _, sqlerr := datasource.ExecDB("", sql, []any{username, ipAddr, neType, neId, mmlCmd, resultStr, timeStr}) if sqlerr != nil { - log.Errorf("insert row : %v", err.Error()) + log.Errorf("insert row : %v", sqlerr.Error()) } }) } diff --git a/lib/mmlp/parse.go b/lib/mmlp/parse.go index ded9c02..94a5692 100644 --- a/lib/mmlp/parse.go +++ b/lib/mmlp/parse.go @@ -507,7 +507,7 @@ func TransMml2HttpReq(omcMmlVar *MmlVar, mml *MmlCommand) (*[]byte, error) { response, err := client.R(). EnableTrace(). SetHeaders(map[string]string{tokenConst.HEADER_KEY: omcMmlVar.Authorization}). - SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}). + // 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) @@ -524,7 +524,7 @@ func TransMml2HttpReq(omcMmlVar *MmlVar, mml *MmlCommand) (*[]byte, error) { response, err := client.R(). EnableTrace(). SetHeaders(map[string]string{tokenConst.HEADER_KEY: omcMmlVar.Authorization}). - SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}). + // 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). @@ -558,7 +558,7 @@ func TransMml2HttpReq(omcMmlVar *MmlVar, mml *MmlCommand) (*[]byte, error) { response, err := client.R(). EnableTrace(). SetHeaders(map[string]string{tokenConst.HEADER_KEY: omcMmlVar.Authorization}). - SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}). + // 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). @@ -575,7 +575,7 @@ func TransMml2HttpReq(omcMmlVar *MmlVar, mml *MmlCommand) (*[]byte, error) { response, err := client.R(). EnableTrace(). SetHeaders(map[string]string{tokenConst.HEADER_KEY: omcMmlVar.Authorization}). - SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}). + // 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) @@ -591,7 +591,7 @@ func TransMml2HttpReq(omcMmlVar *MmlVar, mml *MmlCommand) (*[]byte, error) { response, err := client.R(). EnableTrace(). SetHeaders(map[string]string{tokenConst.HEADER_KEY: omcMmlVar.Authorization}). - SetHeaders(map[string]string{"accessToken": omcMmlVar.SessionToken}). + // 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) diff --git a/lib/routes/routes.go b/lib/routes/routes.go index 2023bda..bf95fe7 100644 --- a/lib/routes/routes.go +++ b/lib/routes/routes.go @@ -145,9 +145,9 @@ func init() { // parameter config management Register("GET", cm.ParamConfigUri, cm.GetParamConfigFromNF, nil) - Register("POST", cm.ParamConfigUri, cm.PostParamConfigToNF, midware.LogOperate(collectlogs.OptionNew("Parameter Config", collectlogs.BUSINESS_TYPE_INSERT))) - Register("PUT", cm.ParamConfigUri, cm.PutParamConfigToNF, midware.LogOperate(collectlogs.OptionNew("Parameter Config", collectlogs.BUSINESS_TYPE_UPDATE))) - Register("DELETE", cm.ParamConfigUri, cm.DeleteParamConfigToNF, midware.LogOperate(collectlogs.OptionNew("Parameter Config", collectlogs.BUSINESS_TYPE_INSERT))) + Register("POST", cm.ParamConfigUri, cm.PostParamConfigToNF, midware.LogOperate(collectlogs.OptionNew("log.operate.title.neConfig", collectlogs.BUSINESS_TYPE_INSERT))) + Register("PUT", cm.ParamConfigUri, cm.PutParamConfigToNF, midware.LogOperate(collectlogs.OptionNew("log.operate.title.neConfig", collectlogs.BUSINESS_TYPE_UPDATE))) + Register("DELETE", cm.ParamConfigUri, cm.DeleteParamConfigToNF, midware.LogOperate(collectlogs.OptionNew("log.operate.title.neConfig", collectlogs.BUSINESS_TYPE_INSERT))) Register("GET", cm.CustomParamConfigUri, cm.GetParamConfigFromNF, nil) Register("POST", cm.CustomParamConfigUri, cm.PostParamConfigToNF, nil) @@ -174,11 +174,11 @@ func init() { Register("POST", mml.UriMML, mml.PostMMLToNF, midware.LogMML) Register("POST", mml.UriMMLDiscard, mml.PostMMLToNF, nil) Register("POST", mml.UriOmMmlExt, mml.PostMMLToOMC, midware.LogMML) - Register("POST", mml.CustomUriMML, mml.PostMMLToNF, midware.LogMML) - Register("POST", mml.CustomUriOmMmlExt, mml.PostMMLToOMC, midware.LogMML) + Register("POST", mml.CustomUriMML, mml.PostMMLToNF, nil) + Register("POST", mml.CustomUriOmMmlExt, mml.PostMMLToOMC, nil) // post mml2 (standard upf port=5002) Register("POST", mml.UriMML2, mml.PostMML2ToNF, midware.LogMML) - Register("POST", mml.CustomUriMML2, mml.PostMML2ToNF, midware.LogMML) + Register("POST", mml.CustomUriMML2, mml.PostMML2ToNF, nil) // Northbound Get NRM Register("GET", nbi.GetNRMUri, nbi.NBIGetNRMFromNF, nil) diff --git a/lib/services/services.go b/lib/services/services.go index 149e3f5..8b55bf4 100644 --- a/lib/services/services.go +++ b/lib/services/services.go @@ -449,66 +449,66 @@ func CheckFrontValidRequest(w http.ResponseWriter, r *http.Request) (string, err log.Debug("CheckFrontValidRequest processing... ") var token string = "" - var err error - var ret bool - // response 414-4 uri too long ? (optional) - // todo ... ? - if bytes.Count([]byte(r.RequestURI), nil) > config.GetUriMaxLenFromConfig() { - err = errors.New("request Uri too long") - log.Errorf("Request Uri too long: bytes=%d, MaxLen=%d", bytes.Count([]byte(r.RequestURI), nil), config.GetUriMaxLenFromConfig()) - ResponseRequestURITooLong414UriTooLong(w) - return token, err - } + // var err error + // var ret bool + // // response 414-4 uri too long ? (optional) + // // todo ... ? + // if bytes.Count([]byte(r.RequestURI), nil) > config.GetUriMaxLenFromConfig() { + // err = errors.New("request Uri too long") + // log.Errorf("Request Uri too long: bytes=%d, MaxLen=%d", bytes.Count([]byte(r.RequestURI), nil), config.GetUriMaxLenFromConfig()) + // ResponseRequestURITooLong414UriTooLong(w) + // return token, err + // } - /* - // check media type(content type) only support "application/json" - // response 415-1 - if !IsVallidContentType(r) { - err := errors.New("Invalid Content-Type") - log.Error(err) - ResponseUnsupportedMediaType415(w) - return err - } - */ + // /* + // // check media type(content type) only support "application/json" + // // response 415-1 + // if !IsVallidContentType(r) { + // err := errors.New("Invalid Content-Type") + // log.Error(err) + // ResponseUnsupportedMediaType415(w) + // return err + // } + // */ - // error processing ... - // 401-1 response - if config.GetYamlConfig().Auth.Token && !IsLocalhost(r.RemoteAddr) { - token, ret = oauth.IsCarriedToken(r) - if !ret { - err = errors.New("accessToken is not carried") - log.Error(err) - ResponseUnauthorized401AccessTokenNotCarried(w) - return token, err - } + // // error processing ... + // // 401-1 response + // if config.GetYamlConfig().Auth.Token && !IsLocalhost(r.RemoteAddr) { + // token, ret = oauth.IsCarriedToken(r) + // if !ret { + // err = errors.New("accessToken is not carried") + // log.Error(err) + // ResponseUnauthorized401AccessTokenNotCarried(w) + // return token, err + // } - // 401-2 response - if !dborm.XormExistValidToken(token, config.GetExpiresFromConfig()) { - err = errors.New("accessToken fails or does not exist") - log.Error(err) - ResponseUnauthorized401AccessTokenNotExist(w) - return token, err - } + // // 401-2 response + // if !dborm.XormExistValidToken(token, config.GetExpiresFromConfig()) { + // err = errors.New("accessToken fails or does not exist") + // log.Error(err) + // ResponseUnauthorized401AccessTokenNotExist(w) + // return token, err + // } - if operType := GetOperationTypeFromHttpRequest(r); operType != "auto" { - _, err = dborm.XormUpdateSessionShakeTime(token) - if err != nil { - log.Error("Failed to update session table:", err) - ResponseUnauthorized401AccessTokenNotExist(w) - return token, err - } - } + // if operType := GetOperationTypeFromHttpRequest(r); operType != "auto" { + // _, err = dborm.XormUpdateSessionShakeTime(token) + // if err != nil { + // log.Error("Failed to update session table:", err) + // ResponseUnauthorized401AccessTokenNotExist(w) + // return token, err + // } + // } - } + // } - vars := mux.Vars(r) - apiVer := vars["apiVersion"] - if apiVer != global.ApiVersionV1 { - err = errors.New("uri is invalid") - log.Error(err) - ResponseNotFound404UriNotExist(w, r) - return token, err - } + // vars := mux.Vars(r) + // apiVer := vars["apiVersion"] + // if apiVer != global.ApiVersionV1 { + // err = errors.New("uri is invalid") + // log.Error(err) + // ResponseNotFound404UriNotExist(w, r) + // return token, err + // } return token, nil } diff --git a/restagent/config/config.go b/restagent/config/config.go index 39cb6ee..1dd3ce9 100644 --- a/restagent/config/config.go +++ b/restagent/config/config.go @@ -11,16 +11,6 @@ import ( "gopkg.in/yaml.v3" ) -type DbConfig struct { - Type string `yaml:"type"` - User string `yaml:"user"` - Password string `yaml:"password"` - Host string `yaml:"host"` - Port string `yaml:"port"` - Name string `yaml:"name"` - Backup string `yaml:"backup"` -} - // Yaml struct of config type YamlConfig struct { Logger struct { @@ -30,16 +20,18 @@ type YamlConfig struct { Count int `yaml:"count"` } `yaml:"logger"` - Rest []struct { - IPv4 string `yaml:"ipv4"` - IPv6 string `yaml:"ipv6"` - Port uint16 `yaml:"port"` - Scheme string `yaml:"scheme"` - ClientAuthType int `yaml:"clientAuthType"` - CaFile string `yaml:"caFile"` - CertFile string `yaml:"certFile"` - KeyFile string `yaml:"keyFile"` - } `yaml:"rest"` + // Rest []struct { + // IPv4 string `yaml:"ipv4"` + // IPv6 string `yaml:"ipv6"` + // Port uint16 `yaml:"port"` + // Scheme string `yaml:"scheme"` + // ClientAuthType int `yaml:"clientAuthType"` + // CaFile string `yaml:"caFile"` + // CertFile string `yaml:"certFile"` + // KeyFile string `yaml:"keyFile"` + // } `yaml:"rest"` + + Rest []RestParam WebServer struct { Enabled bool `yaml:"enabled"` @@ -85,7 +77,8 @@ type YamlConfig struct { } `yaml:"omc"` Alarm struct { - ForwardAlarm bool `yaml:"forwardAlarm"` + ForwardAlarm bool `yaml:"forwardAlarm"` + SMProxy string `yaml:"smProxy"` Email struct { Smtp string `yaml:"smtp"` Port uint16 `yaml:"port"` @@ -101,22 +94,14 @@ type YamlConfig struct { TemplateCode string `yaml:"templateCode"` } `yaml:"sms"` SMSC struct { - Addr string `yaml:"addr"` - UserName string `yaml:"userName"` - Password string `yaml:"password"` + Addr string `yaml:"addr"` + SystemID string `yaml:"systemID"` + Password string `yaml:"password"` + SystemType string `yaml:"systemType"` } `yaml:"smsc"` } `yaml:"alarm"` - MML struct { - Port int `yaml:"port"` - Port2 int `yaml:"port2"` - Sleep int64 `yaml:"sleep"` - DeadLine int64 `yaml:"deadLine"` - User string `yaml:"user"` - Password string `ymal:"password"` - MmlHome string `yaml:"mmlHome"` - Upload string `yaml:"upload"` - } `yaml:"mml"` + MML MMLParam `yaml:"mml"` NE struct { Addr string `yaml:"addr"` @@ -157,6 +142,42 @@ type YamlConfig struct { } `yaml:"testConfig"` } +type RestParam struct { + IPv4 string `yaml:"ipv4"` + IPv6 string `yaml:"ipv6"` + Port uint16 `yaml:"port"` + Scheme string `yaml:"scheme,omitempty" default:"http"` + ClientAuthType int `yaml:"clientAuthType"` + CaFile string `yaml:"caFile"` + CertFile string `yaml:"certFile"` + KeyFile string `yaml:"keyFile"` +} + +type DbConfig struct { + Type string `yaml:"type"` + User string `yaml:"user"` + Password string `yaml:"password"` + Host string `yaml:"host"` + Port string `yaml:"port"` + Name string `yaml:"name"` + ConnParam string `yaml:"connParam,omitempty"` + Backup string `yaml:"backup"` +} + +type MMLParam struct { + Port int `yaml:"port"` + Port2 int `yaml:"port2"` + Sleep int64 `yaml:"sleep"` + DeadLine int64 `yaml:"deadLine"` + SizeRow byte `yaml:"sizeRow"` + SizeCol byte `yaml:"sizeCol"` + BufferSize int `yaml:"bufferSize"` + User string `yaml:"user"` + Password string `ymal:"password"` + MmlHome string `yaml:"mmlHome"` + Upload string `yaml:"upload"` +} + type TestDatas struct { UDM struct { CapUsed uint32 `yaml:"capUsed"` @@ -188,7 +209,22 @@ type TestDataMap struct { NeTestDatas []map[string]NeTestData } -var yamlConfig YamlConfig +var yamlConfig YamlConfig = NewYamlConfig() + +// set default value for yaml config +func NewYamlConfig() YamlConfig { + return YamlConfig{ + Database: DbConfig{ + Type: "mysql", + ConnParam: "charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&interpolateParams=True", + }, + MML: MMLParam{ + SizeRow: 100, + SizeCol: 128, + BufferSize: 65535, + }, + } +} func ReadConfig(configFile string) { yamlFile, err := os.ReadFile(configFile) @@ -327,6 +363,23 @@ func GetDefaultUserAgent() string { return "OMC-restagent/" + global.Version } +func GetOMCHostUrl() string { + var omcip string = "127.0.0.1" + var rest RestParam = yamlConfig.Rest[0] + var port uint16 = rest.Port + if rest.IPv4 != "0.0.0.0" && rest.IPv4 != "" { + omcip = rest.IPv4 + } else if rest.IPv6 != "::" && rest.IPv6 != "" { + omcip = "[" + rest.IPv6 + "]" + } + var scheme string = "http" + if rest.Scheme != "" { + scheme = rest.Scheme + } + + return fmt.Sprintf("%s://%s:%d", scheme, omcip, port) +} + // const defaultConfigFile = "./etc/restconf.yaml" // func init() { diff --git a/restagent/dev.yaml b/restagent/dev.yaml deleted file mode 100644 index c7924e1..0000000 --- a/restagent/dev.yaml +++ /dev/null @@ -1,181 +0,0 @@ -# file: log file name -# level: /trace/debug/info/warn/error/fatal, default: debug -# duration: rotation time with xx hours, example: 1/12/24 hours -# count: rotation count of log, default is 30 rotation -logger: - file: "../temp/log/restagent.log" - level: "trace" - duration: 24 - count: 2 - -# rest agent listen ipv4/v6 and port, support multiple routines -# ip: 0.0.0.0 or ::0, support IPv4/v6 -# clientAuthType: 0:NoClientCert (default), 1:RequestClientCert, 2:RequireAnyClientCert, -# 3:VerifyClientCertIfGiven, 4:RequireAndVerifyClientCerts -rest: - - ipv4: 0.0.0.0 - ipv6: - port: 33040 - - ipv4: 0.0.0.0 - ipv6: - port: 33443 - scheme: https - clientAuthType: 0 - caFile: ./etc/certs/omc-ca.crt - certFile: ./etc/certs/omc-server.crt - keyFile: ./etc/certs/omc-server.key - -webServer: - enabled: false - rootDir: d:/local.git/fe.ems.vue3/dist - listen: - - addr: :80 - schema: http - - addr: :443 - scheme: https - clientAuthType: 0 - caFile: ./etc/certs/omc-ca.crt - certFile: ./etc/certs/omc-server.crt - keyFile: ./etc/certs/omc-server.key - -database: - type: mysql - user: root - # password: 1000omc@kp! - # host: "192.168.8.103" - # port: 33066 - name: omc_db - backup: d:/local.git/be.ems/restagent/database - password: "root@1234" - host: "192.168.5.59" - port: 3306 - -# Redis 缓存数据,数据源声明全小写 -redis: - dataSource: - # OMC系统使用库 - default: - port: 6379 # Redis port - host: "192.168.5.59" # Redis host - password: "redis@1234" - db: 10 # Redis db_num - # UDM网元用户库 - udmuser: - port: 6379 # Redis port - host: "192.168.13.140" - password: "" - db: 0 # Redis db_num - # 多个数据源时可以用这个指定默认的数据源 - defaultDataSourceName: "default" - -# sleep: time delay for after write buffer (millisecond) -# deadLine: timeout for io read and write (second) -mml: - port: 4100 - port2: 5002 - sleep: 200 - deadLine: 10 - user: admin - password: admin - mmlHome: ./mmlhome - upload: /home/agtuser - -# NE config -ne: - user: agtuser - etcdir: /usr/local/etc - bindir: /usr/local/bin - omcdir: /usr/local/omc - scpdir: /tmp - licensedir: /usr/local/etc/{neType}/license - # backup etc list of IMS,no space - etcListIMS: "{*.yaml,mmtel,vars.cfg}" - etcListDefault: "{*.yaml,*.conf,*.cfg}" - # true/false to overwrite config file when dpkg ne software - dpkgOverwrite: false - # dpkg timeout (second) - dpkgTimeout: 180 - -# chk2ne: true/false, if put OmcNeConfig parameters to NE -omc: - uriPrefix: "/omc/rest" - neType: OMC - neId: 001 - rmUID: 4400HX101 - neName: OMC - province: GD - vendor: "" - dn: 4600 - chk2ne: false - sn: "-" - checksign: false - rootDir: ./ - binDir: ./bin - backup: ./backup - upload: ./upload - frontUpload: d:/local.git/fe.ems/upload - frontTraceDir: d:/local.git/fe.ems/trace - software: ./software - license: ./license - gtpUri: gtp:192.168.2.219:2152 - checkContentType: false - testMode: false - rbacMode: true - runDir: - cmdTimeout: 120 - -# Alarm module setting -# Forward interface: -# email/sms -alarm: - forwardAlarm: true - email: - smtp: mail.agrandtech.com - port: 25 - user: smtpext@agrandtech.com - password: "1000smtp@omc!" - # TLS skip verify: true/false - tlsSkipVerify: true - sms: - apiURL: http://smsc.xxx.com.cn/ - accessKeyID: xxxx - accessKeySecret: xxxx - signName: xxx SMSC - templateCode: 1000 - smsc: - addr: "192.168.14.211:2775" - userName: OMC - password: "123456" - -#User authorized information -# crypt: mysql/md5/bcrypt -# token: true/false to check accessToken -# expires for session, unit: second -# Support single/multiple session of user -# -auth: - crypt: bcrypt - token: true - expires: 1800 - session: multiple - publicKey: ./etc/certs/omc_pub.key - privateKey: ./etc/certs/omc_pri.key - -# Parameter for limit number -# rmuid_maxnum: the max number of rmUID, default: 50 -# alarmid_maxnum: the max number of AlarmID, default: 50 -# pmid_maxnum: the max number of pmID, default: 50 -# subid_maxnum: the max number of subscription ID, default: 20 -# uri_maxlen: the max length of uri, default: 8192 -# rmuid_regexp: regexp pattern of rmUID -params: - rmuidmaxnum: 50 - alarmidmaxnum: 50 - pmidmaxnum: 50 - subidmaxnum: 20 - urimaxlen: 2100000 - rmuidregexp: "[0-9]{4}[A-Z]{2}[A-Z]{2}[0-9A-Z]{1}[0-9A-Z]{3}[0-9A-Z]{1,16}" - -testConfig: - enabled: true - file: ./etc/testconfig.yaml diff --git a/restagent/etc/restconf.yaml b/restagent/etc/restconf.yaml index a19d796..f2fa6a2 100644 --- a/restagent/etc/restconf.yaml +++ b/restagent/etc/restconf.yaml @@ -16,14 +16,6 @@ rest: - ipv4: 0.0.0.0 ipv6: port: 33040 - - ipv4: 0.0.0.0 - ipv6: - port: 33443 - scheme: https - clientAuthType: 0 - caFile: ./etc/certs/omc-ca.crt - certFile: ./etc/certs/omc-server.crt - keyFile: ./etc/certs/omc-server.key webServer: enabled: false @@ -41,14 +33,12 @@ webServer: database: type: mysql user: root - # password: 1000omc@kp! - # host: "192.168.8.103" - # port: 33066 - name: omc_db - backup: d:/local.git/be.ems/restagent/database password: "root@1234" host: "192.168.5.59" port: 3306 + name: "omc_db" + connParam: charset=utf8mb4&collation=utf8mb4_general_ci&parseTime=True&interpolateParams=True + backup: d:/local.git/be.ems/restagent/database # Redis 缓存数据,数据源声明全小写 redis: @@ -62,8 +52,8 @@ redis: # UDM网元用户库 udmuser: port: 6379 # Redis port - host: "192.168.13.140" - password: "" + host: "172.60.5.140" + password: "helloearth" db: 0 # Redis db_num # 多个数据源时可以用这个指定默认的数据源 defaultDataSourceName: "default" @@ -75,6 +65,9 @@ mml: port2: 5002 sleep: 200 deadLine: 10 + sizeRow: 100 + sizeCol: 128 + bufferSize: 65535 user: admin password: admin mmlHome: ./mmlhome @@ -128,7 +121,7 @@ omc: # Forward interface: # email/sms alarm: - forwardAlarm: true + forwardAlarm: false email: smtp: mail.agrandtech.com port: 25 @@ -143,9 +136,10 @@ alarm: signName: xxx SMSC templateCode: 1000 smsc: - addr: "192.168.14.211:2775" - userName: OMC - password: "123456" + addr: "192.168.13.114:2775" + systemID: "omc" + password: "omc123" + systemType: "UTRAN" #User authorized information # crypt: mysql/md5/bcrypt @@ -178,4 +172,15 @@ params: testConfig: enabled: true - file: ./etc/testconfig.yaml \ No newline at end of file + file: ./etc/testconfig.yaml + +# 静态文件配置, 相对项目根路径或填绝对路径 +# staticFile: +# # 默认资源,dir目录需要预先创建 +# default: +# prefix: "/static" +# dir: "./static" +# # 文件上传资源目录映射,与项目目录同级 +# upload: +# prefix: "/upload" +# dir: "./upload" diff --git a/restagent/makefile b/restagent/makefile index c9fcc72..8fec79f 100644 --- a/restagent/makefile +++ b/restagent/makefile @@ -1,7 +1,7 @@ # Makefile for rest agent project PROJECT = OMC -VERSION = 2.2403.1 +VERSION = 2.2404.6 PLATFORM = amd64 ARMPLATFORM = aarch64 BUILDDIR = ../../build diff --git a/restagent/restagent.go b/restagent/restagent.go index f8b49a9..04aac95 100644 --- a/restagent/restagent.go +++ b/restagent/restagent.go @@ -13,6 +13,7 @@ import ( "be.ems/features/event" "be.ems/features/fm" "be.ems/features/lm" + "be.ems/features/mml" "be.ems/features/pm" "be.ems/lib/dborm" "be.ems/lib/global" @@ -21,7 +22,6 @@ import ( "be.ems/restagent/config" "be.ems/src" "be.ems/src/framework/middleware" - libSession "be.ems/src/lib_features/session" "github.com/gin-gonic/gin" "golang.org/x/net/http2" "golang.org/x/net/http2/h2c" @@ -197,46 +197,46 @@ func main() { log.Infof("OMC restagent version: %s %s %s", global.Version, global.BuildTime, global.GoVer) err := dborm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password, - conf.Database.Host, conf.Database.Port, conf.Database.Name) + conf.Database.Host, conf.Database.Port, conf.Database.Name, conf.Database.ConnParam) if err != nil { fmt.Println("dborm.initDbClient err:", err) os.Exit(4) } err = fm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password, - conf.Database.Host, conf.Database.Port, conf.Database.Name) + conf.Database.Host, conf.Database.Port, conf.Database.Name, conf.Database.ConnParam) if err != nil { fmt.Println("dborm.initDbClient err:", err) os.Exit(4) } err = pm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password, - conf.Database.Host, conf.Database.Port, conf.Database.Name) + conf.Database.Host, conf.Database.Port, conf.Database.Name, conf.Database.ConnParam) if err != nil { fmt.Println("dborm.initDbClient err:", err) os.Exit(4) } err = dbrest.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password, - conf.Database.Host, conf.Database.Port, conf.Database.Name) + conf.Database.Host, conf.Database.Port, conf.Database.Name, conf.Database.ConnParam) if err != nil { fmt.Println("dbrest.initDbClient err:", err) os.Exit(4) } err = lm.InitDbClient(conf.Database.Type, conf.Database.User, conf.Database.Password, - conf.Database.Host, conf.Database.Port, conf.Database.Name) + conf.Database.Host, conf.Database.Port, conf.Database.Name, conf.Database.ConnParam) if err != nil { fmt.Println("lm.initDbClient err:", err) os.Exit(4) } + mml.InitMML() + // 将 mux.Router 注册到 gin.Engine // 默认路由组 defaultUriGroup := app.Group(config.DefaultUriPrefix) defaultUriGroup.Use(middleware.PreAuthorize(nil)) - defaultUriGroup.Use(libSession.SessionHeader()) defaultUriGroup.Any("/*any", gin.WrapH(routes.NewRouter())) // 可配置前缀路由组 uriGroup := app.Group(config.UriPrefix) - uriGroup.Use(libSession.SessionHeader()) uriGroup.Any("/*any", gin.WrapH(routes.NewRouter())) // AMF上报的UE事件, 无前缀,暂时特殊处理 app.POST(event.UriUEEvent, event.PostUEEventFromAMF) @@ -244,6 +244,7 @@ func main() { // 开启监控采集 // monitor.StartMonitor(false, "") + var listenLocalhost bool = false for _, rest := range conf.Rest { // ipv4 goroutines if rest.IPv4 != "" { @@ -254,7 +255,8 @@ func main() { go HttpListen(listen, app) } } - if rest.IPv4 != "0.0.0.0" { + if rest.IPv4 != "0.0.0.0" && !listenLocalhost { + listenLocalhost = true // 默认启动localhost侦听 listenLocal := "127.0.0.1" + ":" + strconv.Itoa(int(rest.Port)) if strings.ToLower(rest.Scheme) == "https" { diff --git a/restagent/run.sh b/restagent/run.sh deleted file mode 100644 index a366846..0000000 --- a/restagent/run.sh +++ /dev/null @@ -1,17 +0,0 @@ -#! /usr/bin/bash - -ps aux | grep "omcDevApp" - -process_id=$(ps aux | grep "omcDevApp" | grep -v grep | awk '{print $2}') -if [ -n "$process_id" ]; then - kill -9 "$process_id" -else - echo "未找到匹配的进程" -fi - -go version -go build -ldflags="-s -w" -o omcDevApp - -BUILD_ID=dontKillMe -nohup ./omcDevApp -c ./dev.yaml > ./dev.log 2>&1 & -echo ok \ No newline at end of file diff --git a/src/framework/config/config/config.default.yaml b/src/framework/config/config/config.default.yaml index 443c891..ce4c945 100644 --- a/src/framework/config/config/config.default.yaml +++ b/src/framework/config/config/config.default.yaml @@ -1,7 +1,7 @@ # 项目信息 framework: name: "CN EMS" - version: "2.2403.1" + version: "2.2404.6" # 应用服务配置 server: @@ -68,6 +68,8 @@ upload: # 软件包 - ".deb" - ".rpm" + # 验证文件 + - ".ini" # cors 跨域 cors: diff --git a/src/framework/constants/uploadsubpath/uploadsubpath.go b/src/framework/constants/uploadsubpath/uploadsubpath.go index c58e87f..b4c181f 100644 --- a/src/framework/constants/uploadsubpath/uploadsubpath.go +++ b/src/framework/constants/uploadsubpath/uploadsubpath.go @@ -26,6 +26,9 @@ const ( // 软件包 SOFTWARE = "software" + + // 授权文件 + LICENSE = "license" ) // 子路径类型映射 @@ -38,4 +41,5 @@ var UploadSubpath = map[string]string{ DOWNLOAD: "下载", CHUNK: "切片", SOFTWARE: "软件包", + LICENSE: "授权文件", } diff --git a/src/framework/i18n/i18n.go b/src/framework/i18n/i18n.go index f35e602..7e5c2de 100644 --- a/src/framework/i18n/i18n.go +++ b/src/framework/i18n/i18n.go @@ -3,6 +3,7 @@ package i18n import ( "fmt" "regexp" + "strings" systemService "be.ems/src/modules/system/service" ) @@ -70,6 +71,26 @@ func UpdateKeyValue(language, key, value string) bool { return false } +// TFindKeyPrefix 翻译值查找键 值前缀匹配 +func TFindKeyPrefix(language, keyPrefix, value string) string { + key := value + if value == "" { + return key + } + arr, ok := localeMap[language] + if !ok || len(arr) == 0 { + arr = LoadLocaleData(language) + } + + for _, v := range arr { + if strings.HasPrefix(v.Key, keyPrefix) && strings.HasPrefix(v.Value, value) { + key = v.Key + break + } + } + return key +} + // TKey 翻译键 func TKey(language, key string) string { value := key diff --git a/src/framework/utils/date/date.go b/src/framework/utils/date/date.go index 533bf09..84ae33d 100644 --- a/src/framework/utils/date/date.go +++ b/src/framework/utils/date/date.go @@ -17,6 +17,8 @@ const ( YYYYMMDDHHMMSS = "20060102150405" // 年-月-日 时:分:秒 列如:2022-12-30 01:01:59 YYYY_MM_DD_HH_MM_SS = "2006-01-02 15:04:05" + // 年-月-日T时:分:秒Z时区 列如:2022-12-30T01:01:59+08:00 + YYYY_MM_DDTHH_MM_SSZ = time.RFC3339 ) // 格式时间字符串 diff --git a/src/framework/utils/file/file.go b/src/framework/utils/file/file.go index 4077816..d0a602a 100644 --- a/src/framework/utils/file/file.go +++ b/src/framework/utils/file/file.go @@ -60,9 +60,12 @@ func uploadWhiteList() []string { // fileName 原始文件名称含后缀,如:logo.png func generateFileName(fileName string) string { fileExt := filepath.Ext(fileName) - // 替换掉后缀和特殊字符保留文件名 + // 去除后缀 newFileName := regular.Replace(fileName, fileExt, "") - newFileName = regular.Replace(newFileName, `[<>:"\\|?*]+`, "") + // 去除非法字符 + newFileName = regular.Replace(newFileName, `[\\/:*?"<>|]`, "") + // 去除空格 + newFileName = regular.Replace(newFileName, `\s`, "_") newFileName = strings.TrimSpace(newFileName) return fmt.Sprintf("%s_%s%s", newFileName, generate.Code(6), fileExt) } diff --git a/src/framework/utils/regular/regular.go b/src/framework/utils/regular/regular.go index 9feebc3..3eeb31c 100644 --- a/src/framework/utils/regular/regular.go +++ b/src/framework/utils/regular/regular.go @@ -48,7 +48,7 @@ func ValidMobile(mobile string) bool { if mobile == "" { return false } - pattern := `^1[3|4|5|6|7|8|9][0-9]\d{8}$` + pattern := `^.{3,}$` // `^1[3|4|5|6|7|8|9][0-9]\d{8}$` match, err := regexp.MatchString(pattern, mobile) if err != nil { return false diff --git a/src/framework/utils/ssh/scp.go b/src/framework/utils/ssh/scp.go index 834ba8e..8151b3a 100644 --- a/src/framework/utils/ssh/scp.go +++ b/src/framework/utils/ssh/scp.go @@ -5,6 +5,7 @@ import ( "os" "os/exec" "path/filepath" + "time" "be.ems/src/framework/config" "be.ems/src/framework/logger" @@ -16,9 +17,9 @@ func FileSCPLocalToNe(neIp, localPath, nePath string) error { // scp /path/to/local/file.txt user@remote-server:/path/to/remote/directory/ neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath) cmd := exec.Command("scp", "-r", localPath, neDir) - _, err := cmd.CombinedOutput() + output, err := cmd.CombinedOutput() if err != nil { - logger.Errorf("FileSCPLocalToNe %s", err.Error()) + logger.Errorf("FileSCPLocalToNe %s => %s", output, err.Error()) return err } return nil @@ -31,13 +32,23 @@ func FileSCPNeToLocal(neIp, nePath, localPath string) error { logger.Errorf("FileSCPNeToLocal MkdirAll err %v", err) return err } + // 如果目标文件已经存在,先将目标文件重命名 + if info, err := os.Stat(localPath); err == nil && !info.IsDir() { + ext := filepath.Ext(localPath) + name := localPath[0 : len(localPath)-len(ext)] + newName := fmt.Sprintf("%s-%s%s", name, time.Now().Format("20060102_150405"), ext) + err := os.Rename(localPath, newName) + if err != nil { + return err + } + } usernameNe := config.Get("ne.user").(string) // scp user@remote-server:/path/to/remote/directory/ /path/to/local/file.txt neDir := fmt.Sprintf("%s@%s:%s", usernameNe, neIp, nePath) cmd := exec.Command("scp", "-r", neDir, localPath) - _, err := cmd.CombinedOutput() + output, err := cmd.CombinedOutput() if err != nil { - logger.Errorf("FileSCPNeToLocal %s", err.Error()) + logger.Errorf("FileSCPNeToLocal %s => %s", output, err.Error()) return err } return nil diff --git a/src/framework/utils/ssh/ssh.go b/src/framework/utils/ssh/ssh.go index fbee80f..1542361 100644 --- a/src/framework/utils/ssh/ssh.go +++ b/src/framework/utils/ssh/ssh.go @@ -11,6 +11,7 @@ import ( "time" "be.ems/src/framework/logger" + "be.ems/src/framework/utils/cmd" gossh "golang.org/x/crypto/ssh" ) @@ -96,20 +97,11 @@ func (c *ConnSSH) Close() { func (c *ConnSSH) NewClientByLocalPrivate() (*ConnSSH, error) { c.Port = 22 c.AuthMode = "1" - usr, err := user.Current() + privateKey, err := c.CurrentUserRsaKey(false) if err != nil { - logger.Errorf("NewClientByLocal get current user => %s", err.Error()) return nil, err } - - // 读取用户默认的私钥文件 - keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir) - key, err := os.ReadFile(keyPath) - if err != nil { - logger.Errorf("NewClientByLocal [%s] read private key => %s", usr.Username, err.Error()) - return nil, err - } - c.PrivateKey = string(key) + c.PrivateKey = privateKey return c.NewClient() } @@ -134,7 +126,55 @@ func (c *ConnSSH) RunCMD(cmd string) (string, error) { return c.LastResult, err } -// NewClient 创建SSH客户端会话对象 +// SendToAuthorizedKeys 发送当前用户私钥到远程服务器进行授权密钥 +func (c *ConnSSH) SendToAuthorizedKeys() error { + publicKey, err := c.CurrentUserRsaKey(true) + if err != nil { + return err + } + authorizedKeysEntry := fmt.Sprintln(strings.TrimSpace(publicKey)) + cmdStr := "echo '" + authorizedKeysEntry + "' >> ~/.ssh/authorized_keys" + _, err = c.RunCMD(cmdStr) + if err != nil { + logger.Errorf("SendAuthorizedKeys echo err %s", err.Error()) + return err + } + return nil +} + +// CurrentUserRsaKey 当前用户OMC使用的RSA私钥 +// 默认读取私钥 +// ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa +// ssh-keygen -y -f ~/.ssh/id_rsa > ~/.ssh/id_rsa.pub +func (c *ConnSSH) CurrentUserRsaKey(publicKey bool) (string, error) { + usr, err := user.Current() + if err != nil { + logger.Errorf("CurrentUserRsaKey get => %s", err.Error()) + return "", err + } + + // 是否存在私钥并创建 + keyPath := fmt.Sprintf("%s/.ssh/id_rsa", usr.HomeDir) + if _, err := os.Stat(keyPath); err != nil { + _, err2 := cmd.ExecWithCheck("ssh-keygen", "-t", "rsa", "-P", "", "-f", keyPath) + if err2 != nil { + logger.Errorf("CurrentUserPrivateKey ssh-keygen [%s] rsa => %s", usr.Username, err2.Error()) + } + } + + // 读取用户默认的文件 + if publicKey { + keyPath = keyPath + ".pub" + } + key, err := os.ReadFile(keyPath) + if err != nil { + logger.Errorf("CurrentUserRsaKey [%s] read => %s", usr.Username, err.Error()) + return "", fmt.Errorf("read file %s fail", keyPath) + } + return string(key), nil +} + +// NewClientSession 创建SSH客户端会话对象 func (c *ConnSSH) NewClientSession(cols, rows int) (*SSHClientSession, error) { sshSession, err := c.Client.NewSession() if err != nil { diff --git a/src/lib_features/account/account.go b/src/lib_features/account/account.go deleted file mode 100644 index df339c2..0000000 --- a/src/lib_features/account/account.go +++ /dev/null @@ -1,39 +0,0 @@ -package libfeatures - -import ( - "time" - - "be.ems/lib/dborm" - "be.ems/lib/oauth" - libConfig "be.ems/restagent/config" - "be.ems/src/framework/logger" - "be.ems/src/framework/redis" -) - -// SessionToken 设置登录会话-兼容旧登录方式 -func SessionToken(username, sourceAddr string) bool { - // token, _ := redis.Get("", "session_token") - // if token != "" { - // se, err := dborm.XormUpdateSessionShakeTime(token) - // if se.AccountId != username || err != nil { - // // 过期时间单位秒 配置1800是半小时 - // expireTime := time.Duration(int64(libConfig.GetExpiresFromConfig())) * time.Second - // redis.SetByExpire("", "session_token", token, expireTime) - // return true - // } - // } - // 不管原先的登录情况,直接插入写入覆盖redis中session - // - token := oauth.GenRandToken("omc") // Generate new token to session ID - affected, err := dborm.XormInsertSession(username, sourceAddr, token, libConfig.GetExpiresFromConfig(), libConfig.GetYamlConfig().Auth.Session) - if err != nil { - logger.Errorf("SessionToken XormInsertSession err %v", err) - } - if affected >= 1 { - // 过期时间单位秒 配置1800是半小时 - expireTime := time.Duration(int64(libConfig.GetExpiresFromConfig())) * time.Second - redis.SetByExpire("", "session_token", token, expireTime) - return true - } - return false -} diff --git a/src/lib_features/readme.md b/src/lib_features/readme.md index 8e91940..57a250c 100644 --- a/src/lib_features/readme.md +++ b/src/lib_features/readme.md @@ -1,5 +1,4 @@ # 外层 lib 和 features 粘合层 - config.go 配置合并: restagent.yaml 文件内容,主要是数据库配置 -- account.go 登录会话生成 token -- session.go 中间件方式设置请求头 token 值 + diff --git a/src/lib_features/session/session.go b/src/lib_features/session/session.go deleted file mode 100644 index 41de9f2..0000000 --- a/src/lib_features/session/session.go +++ /dev/null @@ -1,28 +0,0 @@ -package session - -import ( - "time" - - libConfig "be.ems/restagent/config" - "be.ems/src/framework/redis" - "github.com/gin-gonic/gin" -) - -// SessionHeader 旧登录方式token头 -func SessionHeader() gin.HandlerFunc { - return func(c *gin.Context) { - // 读取登录生成的会话token - token, _ := redis.Get("", "session_token") - if token != "" { - // 过期时间单位秒 配置1800是半小时 - expireTime := time.Duration(int64(libConfig.GetExpiresFromConfig())) * time.Second - redis.SetByExpire("", "session_token", token, expireTime) - c.Request.Header.Set("Accesstoken", token) - } - - // Accesstoken: omc-ce4d0a86-8515-ad51-3249-4913c95f8e34 - // 调用下一个处理程序 - c.Next() - - } -} diff --git a/src/modules/common/controller/account.go b/src/modules/common/controller/account.go index 763fa5d..abfba11 100644 --- a/src/modules/common/controller/account.go +++ b/src/modules/common/controller/account.go @@ -9,7 +9,6 @@ import ( tokenUtils "be.ems/src/framework/utils/token" "be.ems/src/framework/vo" "be.ems/src/framework/vo/result" - libAccount "be.ems/src/lib_features/account" commonModel "be.ems/src/modules/common/model" commonService "be.ems/src/modules/common/service" systemService "be.ems/src/modules/system/service" @@ -83,9 +82,6 @@ func (s *AccountController) Login(c *gin.Context) { ) } - // 设置登录会话-兼容旧登录方式 - libAccount.SessionToken(loginBody.Username, ipaddr) - c.JSON(200, result.OkData(map[string]any{ tokenConstants.RESPONSE_FIELD: tokenStr, })) diff --git a/src/modules/crontask/processor/deleteExpiredRecord/deleteExpiredRecord.go b/src/modules/crontask/processor/deleteExpiredRecord/deleteExpiredRecord.go index 2df3969..e9cd27a 100644 --- a/src/modules/crontask/processor/deleteExpiredRecord/deleteExpiredRecord.go +++ b/src/modules/crontask/processor/deleteExpiredRecord/deleteExpiredRecord.go @@ -25,8 +25,9 @@ type BarProcessor struct { type BarParams struct { Duration int `json:"duration"` TableName string `json:"tableName"` - ColName string `json:"colName"` // column name of time string - Extras string `json:"extras"` // extras condition for where + ColName string `json:"colName"` // column name of time string + Extras string `json:"extras"` // extras condition for where + SessFlag bool `json:"sessFlag"` // session flag, true: session model, false: no session } func (s *BarProcessor) Execute(data any) (any, error) { @@ -74,10 +75,19 @@ func (s *BarProcessor) Execute(data any) (any, error) { where = fmt.Sprintf("NOW()>ADDDATE(`%s`,interval %d day) and %s", params.ColName, params.Duration, params.Extras) } - affected, err := dborm.XormDeleteDataByWhere(where, params.TableName) - if err != nil { - // panic(fmt.Sprintf("Failed to XormDeleteDataByWhere:%v", err)) - return nil, err + var affected int64 = 0 + if params.SessFlag { + affected, err = dborm.XormDeleteDataByWhere(where, params.TableName) + if err != nil { + // panic(fmt.Sprintf("Failed to XormDeleteDataByWhere:%v", err)) + return nil, err + } + } else { + affected, err = dborm.XormDeleteDataByWhereNoSession(where, params.TableName) + if err != nil { + // panic(fmt.Sprintf("Failed to XormDeleteDataByWhere:%v", err)) + return nil, err + } } // 返回结果,用于记录执行结果 diff --git a/src/modules/crontask/processor/genNeStateAlarm/genNeStateAlarm.go b/src/modules/crontask/processor/genNeStateAlarm/genNeStateAlarm.go index c3a260d..443f554 100644 --- a/src/modules/crontask/processor/genNeStateAlarm/genNeStateAlarm.go +++ b/src/modules/crontask/processor/genNeStateAlarm/genNeStateAlarm.go @@ -112,7 +112,8 @@ func (s *BarProcessor) Execute(data any) (any, error) { for _, ne := range nes { //log.Debug("ne:", ne) - sql := fmt.Sprintf("select * from ne_state where ne_type = '%s' and ne_id = '%s' order by timestamp desc limit 1", ne.NeType, ne.NeId) + sql := fmt.Sprintf("select * from ne_state where ne_type='%s' and ne_id='%s' order by `timestamp` desc limit 1", ne.NeType, ne.NeId) + log.Debug("SQL:", sql) neState, err := dborm.XormGetDataBySQL(sql) if err != nil { log.Error("Failed to get ne_state:", err) @@ -120,7 +121,7 @@ func (s *BarProcessor) Execute(data any) (any, error) { } if len(*neState) == 0 { log.Warn("Not found record in ne_state:") - continue + //continue } //log.Debug("neState:", *neState) @@ -149,7 +150,7 @@ func (s *BarProcessor) Execute(data any) (any, error) { var timestamp string if len(*neState) == 0 { log.Infof("Not found ne_state neType:%s, neId:%s", ne.NeType, ne.NeId) - timestamp = ne.UpdateTime + timestamp = ne.UpdateTime.Format(time.DateTime) } else { timestamp = (*neState)[0]["timestamp"] } @@ -201,11 +202,13 @@ func (s *BarProcessor) Execute(data any) (any, error) { var response *resty.Response requestURI := fmt.Sprintf("/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", ne.NeType) - restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port) + //restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port) + restHost := config.GetOMCHostUrl() requestURL := fmt.Sprintf("%s%s", restHost, requestURI) log.Debug("requestURL: POST ", requestURL) 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). @@ -268,7 +271,8 @@ func (s *BarProcessor) Execute(data any) (any, error) { var response *resty.Response requestURI := fmt.Sprintf("/api/rest/faultManagement/v1/elementType/%s/objectType/alarms", ne.NeType) - restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port) + //restHost := fmt.Sprintf("http://127.0.0.1:%d", config.GetYamlConfig().Rest[0].Port) + restHost := config.GetOMCHostUrl() requestURL := fmt.Sprintf("%s%s", restHost, requestURI) log.Debug("requestURL: POST ", requestURL) response, err = client.R(). diff --git a/src/modules/crontask/processor/getStateFromNE/getStateFromNE.go b/src/modules/crontask/processor/getStateFromNE/getStateFromNE.go index b4decc1..98fe8f9 100644 --- a/src/modules/crontask/processor/getStateFromNE/getStateFromNE.go +++ b/src/modules/crontask/processor/getStateFromNE/getStateFromNE.go @@ -116,17 +116,20 @@ func (s *BarProcessor) Execute(data any) (any, error) { log.Trace("response body:", string(response.Body())) state := new(SystemState) _ = json.Unmarshal(response.Body(), &state) - var dateStr *string = nil - if state.ExpiryDate != "" && state.ExpiryDate != "-" { - dateStr = &state.ExpiryDate - } + // var dateStr *string = nil + // if state.ExpiryDate != "" && state.ExpiryDate != "-" { + // dateStr = &state.ExpiryDate + // } neState := new(dborm.NeState) neState.NeType = ne.NeType neState.NeId = ne.NeId neState.Version = state.Version neState.Capability = state.Capability neState.SerialNum = state.SerialNum - neState.ExpiryDate = *dateStr + // if dateStr != nil { + // neState.ExpiryDate = *dateStr + // } + neState.ExpiryDate = state.ExpiryDate cu, _ := json.Marshal(state.CpuUsage) neState.CpuUsage = string(cu) mu, _ := json.Marshal(state.MemUsage) diff --git a/src/modules/monitor/controller/sys_job.go b/src/modules/monitor/controller/sys_job.go index 4847eeb..de8e7dd 100644 --- a/src/modules/monitor/controller/sys_job.go +++ b/src/modules/monitor/controller/sys_job.go @@ -40,12 +40,17 @@ type SysJobController struct { // // GET /list func (s *SysJobController) List(c *gin.Context) { - querys := ctx.QueryMap(c) - data := s.sysJobService.SelectJobPage(querys) - - rows := data["rows"].([]model.SysJob) - // 闭包函数处理多语言 language := ctx.AcceptLanguage(c) + querys := ctx.QueryMap(c) + // 多语言值转key查询 + if v, ok := querys["jobName"]; ok && v != "" { + querys["jobName"] = i18n.TFindKeyPrefix(language, "job", v.(string)) + } + + data := s.sysJobService.SelectJobPage(querys) + rows := data["rows"].([]model.SysJob) + + // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysJob) { for i := range *arr { (*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName) @@ -314,14 +319,21 @@ func (s *SysJobController) ResetQueueJob(c *gin.Context) { func (s *SysJobController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) - data := s.sysJobService.SelectJobPage(querys) - if data["total"].(int64) == 0 { + // querys := ctx.BodyJSONMap(c) + // data := s.sysJobService.SelectJobPage(querys) + // if data["total"].(int64) == 0 { + // // 导出数据记录为空 + // c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) + // return + // } + // rows := data["rows"].([]model.SysJob) + + rows := s.sysJobService.SelectJobList(model.SysJob{}) + if len(rows) <= 0 { // 导出数据记录为空 c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } - rows := data["rows"].([]model.SysJob) // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysJob) { @@ -340,10 +352,10 @@ func (s *SysJobController) Export(c *gin.Context) { "B1": i18n.TKey(language, "job.export.jobName"), "C1": i18n.TKey(language, "job.export.jobGroupName"), "D1": i18n.TKey(language, "job.export.invokeTarget"), - "E1": i18n.TKey(language, "job.export.targetParams"), - "F1": i18n.TKey(language, "job.export.cronExpression"), - "G1": i18n.TKey(language, "job.export.status"), - "H1": i18n.TKey(language, "job.export.remark"), + "E1": i18n.TKey(language, "job.export.cronExpression"), + "F1": i18n.TKey(language, "job.export.status"), + "G1": i18n.TKey(language, "job.export.remark"), + // "E1": i18n.TKey(language, "job.export.targetParams"), } // 读取任务组名字典数据 dictSysJobGroup := s.sysDictDataService.SelectDictDataByType("sys_job_group") @@ -370,10 +382,10 @@ func (s *SysJobController) Export(c *gin.Context) { "B" + idx: row.JobName, "C" + idx: sysJobGroup, "D" + idx: row.InvokeTarget, - "E" + idx: row.TargetParams, - "F" + idx: row.CronExpression, - "G" + idx: statusValue, - "H" + idx: row.Remark, + "E" + idx: row.CronExpression, + "F" + idx: statusValue, + "G" + idx: row.Remark, + // "E" + idx: row.TargetParams, }) } diff --git a/src/modules/monitor/controller/sys_job_log.go b/src/modules/monitor/controller/sys_job_log.go index b3693af..bcfd899 100644 --- a/src/modules/monitor/controller/sys_job_log.go +++ b/src/modules/monitor/controller/sys_job_log.go @@ -39,6 +39,7 @@ type SysJobLogController struct { // // GET /list func (s *SysJobLogController) List(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询参数转换map querys := ctx.QueryMap(c) // 任务ID优先级更高 @@ -47,11 +48,15 @@ func (s *SysJobLogController) List(c *gin.Context) { querys["jobName"] = jobInfo.JobName querys["jobGroup"] = jobInfo.JobGroup } - data := s.sysJobLogService.SelectJobLogPage(querys) + // 多语言值转key查询 + if v, ok := querys["jobName"]; ok && v != "" { + querys["jobName"] = i18n.TFindKeyPrefix(language, "job", v.(string)) + } + data := s.sysJobLogService.SelectJobLogPage(querys) rows := data["rows"].([]model.SysJobLog) + // 闭包函数处理多语言 - language := ctx.AcceptLanguage(c) converI18n := func(language string, arr *[]model.SysJobLog) { for i := range *arr { (*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName) @@ -124,17 +129,24 @@ func (s *SysJobLogController) Clean(c *gin.Context) { // // POST /export func (s *SysJobLogController) Export(c *gin.Context) { + language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) - data := s.sysJobLogService.SelectJobLogPage(querys) - if data["total"].(int64) == 0 { - c.JSON(200, result.ErrMsg("Export data record is empty")) + // querys := ctx.BodyJSONMap(c) + // data := s.sysJobLogService.SelectJobLogPage(querys) + // if data["total"].(int64) == 0 { + // c.JSON(200, result.ErrMsg("Export data record is empty")) + // return + // } + // rows := data["rows"].([]model.SysJobLog) + + rows := s.sysJobLogService.SelectJobLogList(model.SysJobLog{}) + if len(rows) <= 0 { + // 导出数据记录为空 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } - rows := data["rows"].([]model.SysJobLog) // 闭包函数处理多语言 - language := ctx.AcceptLanguage(c) converI18n := func(language string, arr *[]model.SysJobLog) { for i := range *arr { (*arr)[i].JobName = i18n.TKey(language, (*arr)[i].JobName) @@ -150,10 +162,11 @@ func (s *SysJobLogController) Export(c *gin.Context) { "B1": i18n.TKey(language, "job.export.jobName"), "C1": i18n.TKey(language, "job.export.jobGroupName"), "D1": i18n.TKey(language, "job.export.invokeTarget"), - "E1": i18n.TKey(language, "job.export.targetParams"), - "F1": i18n.TKey(language, "job.export.jobID"), - "G1": i18n.TKey(language, "job.export.jobLogStatus"), - "H1": i18n.TKey(language, "job.export.jobLogTime"), + // "E1": i18n.TKey(language, "job.export.targetParams"), + // "F1": i18n.TKey(language, "job.export.jobID"), + "E1": i18n.TKey(language, "job.export.jobLogStatus"), + "F1": i18n.TKey(language, "job.export.jobLogTime"), + "G1": i18n.TKey(language, "log.operate.export.costTime"), } // 读取任务组名字典数据 dictSysJobGroup := s.sysDictDataService.SelectDictDataByType("sys_job_group") @@ -179,10 +192,11 @@ func (s *SysJobLogController) Export(c *gin.Context) { "B" + idx: row.JobName, "C" + idx: sysJobGroup, "D" + idx: row.InvokeTarget, - "E" + idx: row.TargetParams, - "F" + idx: row.JobMsg, - "G" + idx: statusValue, - "H" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DD_HH_MM_SS), + // "E" + idx: row.TargetParams, + // "F" + idx: row.JobMsg, + "E" + idx: statusValue, + "F" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DD_HH_MM_SS), + "G" + idx: row.CostTime, }) } diff --git a/src/modules/monitor/repository/sys_job_log.impl.go b/src/modules/monitor/repository/sys_job_log.impl.go index fc01e61..1f8a0d9 100644 --- a/src/modules/monitor/repository/sys_job_log.impl.go +++ b/src/modules/monitor/repository/sys_job_log.impl.go @@ -6,7 +6,6 @@ import ( "be.ems/src/framework/datasource" "be.ems/src/framework/logger" - "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/repo" "be.ems/src/modules/monitor/model" @@ -80,8 +79,7 @@ func (r *SysJobLogImpl) SelectJobLogPage(query map[string]any) map[string]any { } if ok && beginTime != "" { conditions = append(conditions, "create_time >= ?") - beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD) - params = append(params, beginDate.UnixMilli()) + params = append(params, parse.Number(beginTime.(string))) } endTime, ok := query["endTime"] if !ok { @@ -89,8 +87,7 @@ func (r *SysJobLogImpl) SelectJobLogPage(query map[string]any) map[string]any { } if ok && endTime != "" { conditions = append(conditions, "create_time <= ?") - endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD) - params = append(params, endDate.UnixMilli()) + params = append(params, parse.Number(endTime.(string))) } // 构建查询条件语句 diff --git a/src/modules/network_element/controller/ne_host.go b/src/modules/network_element/controller/ne_host.go index 7bf3955..7baca4b 100644 --- a/src/modules/network_element/controller/ne_host.go +++ b/src/modules/network_element/controller/ne_host.go @@ -354,3 +354,53 @@ func (s *NeHostController) CheckBySSH(c *gin.Context) { c.JSON(200, result.OkData(data)) } + +// 网元主机SSH方式授权免密发送 +// +// POST /authorizedBySSH +func (s *NeHostController) AuthorizedBySSH(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.NeHost + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 本地免密创建链接直连 + sshLink := false + lcoalConnSSH := ssh.ConnSSH{ + User: body.User, + Addr: body.Addr, + Port: body.Port, + } + lcoalClient, err := lcoalConnSSH.NewClientByLocalPrivate() + if err == nil { + sshLink = true + } + defer lcoalClient.Close() + if sshLink { + // 连接主机成功,无需重复免密授权认证 + c.JSON(200, result.OkMsg(i18n.TKey(language, "neHost.okBySSHLink"))) + return + } + + // 创建链接SSH客户端 + var connSSH ssh.ConnSSH + body.CopyTo(&connSSH) + client, err := connSSH.NewClient() + if err != nil { + // 连接主机失败,请检查连接参数后重试 + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neHost.errByHostInfo"))) + return + } + defer client.Close() + + // 发送密钥 + err = client.SendToAuthorizedKeys() + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.Ok(nil)) +} diff --git a/src/modules/network_element/controller/ne_info.go b/src/modules/network_element/controller/ne_info.go index f575ab6..55c10c3 100644 --- a/src/modules/network_element/controller/ne_info.go +++ b/src/modules/network_element/controller/ne_info.go @@ -39,15 +39,15 @@ func (s *NeInfoController) State(c *gin.Context) { language := ctx.AcceptLanguage(c) var querys struct { NeType string `form:"neType" binding:"required"` - NeID string `form:"neId" binding:"required"` + NeId string `form:"neId" binding:"required"` } if err := c.ShouldBindQuery(&querys); err != nil { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) - if neInfo.NeId != querys.NeID || neInfo.IP == "" { + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeId) + if neInfo.NeId != querys.NeId || neInfo.IP == "" { c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) return } @@ -84,17 +84,26 @@ func (s *NeInfoController) State(c *gin.Context) { c.JSON(200, result.OkData(resData)) } -// 网元信息列表 +// 网元neType和neID查询 // -// GET /list -func (s *NeInfoController) List(c *gin.Context) { - querys := ctx.QueryMap(c) - bandStatus := false - if v, ok := querys["bandStatus"]; ok && v != nil { - bandStatus = parse.Boolean(v) +// GET /byTypeAndID +func (s *NeInfoController) NeTypeAndID(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + NeType string `form:"neType" binding:"required"` + NeID string `form:"neId" binding:"required"` } - data := s.neInfoService.SelectPage(querys, bandStatus) - c.JSON(200, result.Ok(data)) + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) + if neInfo.NeId != querys.NeID || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + c.JSON(200, result.OkData(neInfo)) } // 网元信息列表全部无分页 @@ -129,6 +138,85 @@ func (s *NeInfoController) ListAll(c *gin.Context) { c.JSON(200, result.OkData(neList)) } +// 网元端配置文件读取 +// +// GET /configFile +func (s *NeInfoController) ConfigFileRead(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + NeType string `form:"neType" binding:"required"` + NeID string `form:"neId" binding:"required"` + FilePath string `form:"filePath"` // 不带文件路径时进行复制覆盖本地网元配置目录 + } + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) + if neInfo.NeId != querys.NeID || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + data := s.neInfoService.NeConfigFileRead(neInfo, querys.FilePath) + if querys.FilePath == "" { + c.JSON(200, result.OkData(data)) + return + } + if len(data) > 0 { + c.JSON(200, result.OkData(data[0])) + return + } + c.JSON(200, result.ErrMsg("no data")) +} + +// 网元端配置文件写入 +// +// PUT /configFile +func (s *NeInfoController) ConfigFileWrite(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body struct { + NeType string `json:"neType" binding:"required"` + NeID string `json:"neId" binding:"required"` + FilePath string `json:"filePath" binding:"required"` + Content string `json:"content" binding:"required"` + Sync bool `json:"sync"` + } + if err := c.ShouldBindJSON(&body); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeID) + if neInfo.NeId != body.NeID || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + err := s.neInfoService.NeConfigFileWirte(neInfo, body.FilePath, body.Content, body.Sync) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.Ok(nil)) +} + +// 网元信息列表 +// +// GET /list +func (s *NeInfoController) List(c *gin.Context) { + querys := ctx.QueryMap(c) + bandStatus := false + if v, ok := querys["bandStatus"]; ok && v != nil { + bandStatus = parse.Boolean(v) + } + data := s.neInfoService.SelectPage(querys, bandStatus) + c.JSON(200, result.Ok(data)) +} + // 网元信息 // // GET /:infoId @@ -150,28 +238,6 @@ func (s *NeInfoController) Info(c *gin.Context) { c.JSON(200, result.OkData(neHost)) } -// 网元neType和neID查询 -// -// GET / -func (s *NeInfoController) NeTypeAndID(c *gin.Context) { - language := ctx.AcceptLanguage(c) - var querys struct { - NeType string `form:"neType" binding:"required"` - NeID string `form:"neId" binding:"required"` - } - if err := c.ShouldBindQuery(&querys); err != nil { - c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) - return - } - - neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeID) - if neInfo.NeId != querys.NeID || neInfo.IP == "" { - c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) - return - } - c.JSON(200, result.OkData(neInfo)) -} - // 网元信息新增 // // POST / diff --git a/src/modules/network_element/controller/ne_license.go b/src/modules/network_element/controller/ne_license.go new file mode 100644 index 0000000..7022df8 --- /dev/null +++ b/src/modules/network_element/controller/ne_license.go @@ -0,0 +1,301 @@ +package controller + +import ( + "fmt" + "strings" + + "be.ems/src/framework/i18n" + "be.ems/src/framework/utils/ctx" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/vo/result" + "be.ems/src/modules/network_element/model" + neService "be.ems/src/modules/network_element/service" + "github.com/gin-gonic/gin" + "github.com/gin-gonic/gin/binding" +) + +// 实例化控制层 NeLicenseController 结构体 +var NewNeLicense = &NeLicenseController{ + neLicenseService: neService.NewNeLicenseImpl, + neInfoService: neService.NewNeInfoImpl, +} + +// 网元授权激活信息请求 +// +// PATH /license +type NeLicenseController struct { + // 网元授权激活信息服务 + neLicenseService neService.INeLicense + // 网元信息服务 + neInfoService neService.INeInfo +} + +// 网元授权激活信息列表 +// +// GET /list +func (s *NeLicenseController) List(c *gin.Context) { + querys := ctx.QueryMap(c) + data := s.neLicenseService.SelectPage(querys) + + c.JSON(200, result.Ok(data)) +} + +// 网元授权激活信息 +// +// GET /:licenseId +func (s *NeLicenseController) Info(c *gin.Context) { + language := ctx.AcceptLanguage(c) + licenseId := c.Param("licenseId") + if licenseId == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + neLicense := s.neLicenseService.SelectById(licenseId) + if neLicense.ID != licenseId { + // 没有可访问网元授权激活数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData"))) + return + } + + c.JSON(200, result.OkData(neLicense)) +} + +// 网元授权激活信息新增 +// +// POST / +func (s *NeLicenseController) Add(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.NeLicense + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil || body.ID != "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(body.NeType, body.NeId) + if neInfo.NeId != body.NeId || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + // 检查属性值唯一 + uniqueInfo := s.neLicenseService.CheckUniqueTypeAndID(neInfo.NeType, neInfo.NeId, "") + if !uniqueInfo { + // 网元授权激活操作【%s】失败,网元类型信息已存在 + msg := i18n.TTemplate(language, "neLicense.errKeyExists", map[string]any{"name": neInfo.NeType}) + c.JSON(200, result.ErrMsg(msg)) + return + } + + // 读取授权码 + code, _ := s.neLicenseService.ReadLicenseInfo(neInfo) + body.ActivationRequestCode = code + + body.CreateBy = ctx.LoginUserToUserName(c) + insertId := s.neLicenseService.Insert(body) + if insertId != "" { + c.JSON(200, result.Ok(nil)) + return + } + c.JSON(200, result.Err(nil)) +} + +// 网元授权激活信息修改 +// +// PUT / +func (s *NeLicenseController) Edit(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.NeLicense + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil || body.ID == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 检查属性值唯一 + uniqueInfo := s.neLicenseService.CheckUniqueTypeAndID(body.NeType, body.NeId, body.ID) + if !uniqueInfo { + // 网元授权激活操作【%s】失败,网元类型信息已存在 + msg := i18n.TTemplate(language, "neLicense.errKeyExists", map[string]any{"name": body.NeType}) + c.JSON(200, result.ErrMsg(msg)) + return + } + + // 检查是否存在 + neLicense := s.neLicenseService.SelectById(body.ID) + if neLicense.ID != body.ID { + // 没有可访问网元授权激活数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData"))) + return + } + + body.UpdateBy = ctx.LoginUserToUserName(c) + rows := s.neLicenseService.Update(body) + if rows > 0 { + c.JSON(200, result.Ok(nil)) + return + } + c.JSON(200, result.Err(nil)) +} + +// 网元授权激活信息删除 +// +// DELETE /:licenseIds +func (s *NeLicenseController) Remove(c *gin.Context) { + language := ctx.AcceptLanguage(c) + licenseIds := c.Param("licenseIds") + if licenseIds == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + // 处理字符转id数组后去重 + ids := strings.Split(licenseIds, ",") + uniqueIDs := parse.RemoveDuplicates(ids) + if len(uniqueIDs) <= 0 { + c.JSON(200, result.Err(nil)) + return + } + rows, err := s.neLicenseService.DeleteByIds(uniqueIDs) + if err != nil { + c.JSON(200, result.ErrMsg(i18n.TKey(language, err.Error()))) + return + } + msg := i18n.TTemplate(language, "app.common.deleteSuccess", map[string]any{"num": rows}) + c.JSON(200, result.OkMsg(msg)) +} + +// 网元授权激活授权申请码 +// +// GET /code +func (s *NeLicenseController) Code(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + NeType string `form:"neType" binding:"required"` + NeId string `form:"neId" binding:"required"` + } + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeId) + if neInfo.NeId != querys.NeId || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + // 检查是否存在授权记录 + neLicense := s.neLicenseService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId) + if neLicense.NeId != querys.NeId { + // 没有可访问网元授权激活数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData"))) + return + } + + // 更新授权码 + code, licensePath := s.neLicenseService.ReadLicenseInfo(neInfo) + neLicense.ActivationRequestCode = code + if licensePath != "" { + neLicense.LicensePath = licensePath + } else { + neLicense.SerialNum = "" + neLicense.ExpiryDate = "" + neLicense.Status = "0" + } + neLicense.UpdateBy = ctx.LoginUserToUserName(c) + s.neLicenseService.Update(neLicense) + + c.JSON(200, result.OkData(code)) +} + +// 网元授权激活授权文件替换 +// +// POST /change +func (s *NeLicenseController) Change(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var body model.NeLicense + err := c.ShouldBindBodyWith(&body, binding.JSON) + if err != nil || body.HostId == "" { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 检查是否存在授权记录 + neLicense := s.neLicenseService.SelectByNeTypeAndNeID(body.NeType, body.NeId) + if neLicense.NeId != body.NeId { + body.Status = "0" + body.CreateBy = ctx.LoginUserToUserName(c) + body.ID = s.neLicenseService.Insert(body) + } else { + neLicense.LicensePath = body.LicensePath + neLicense.Status = "0" + neLicense.UpdateBy = ctx.LoginUserToUserName(c) + s.neLicenseService.Update(neLicense) + } + + // 进行上传替换 + err = s.neLicenseService.UploadToNeHost(body) + if err != nil { + c.JSON(200, result.ErrMsg(err.Error())) + return + } + c.JSON(200, result.Ok(nil)) +} + +// 网元授权激活状态 +// +// GET /state +func (s *NeLicenseController) State(c *gin.Context) { + language := ctx.AcceptLanguage(c) + var querys struct { + NeType string `form:"neType" binding:"required"` + NeId string `form:"neId" binding:"required"` + } + if err := c.ShouldBindQuery(&querys); err != nil { + c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) + return + } + + // 查询网元获取IP + neInfo := s.neInfoService.SelectNeInfoByNeTypeAndNeID(querys.NeType, querys.NeId) + if neInfo.NeId != querys.NeId || neInfo.IP == "" { + c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.noNEInfo"))) + return + } + + // 检查是否存在授权记录 + neLicense := s.neLicenseService.SelectByNeTypeAndNeID(neInfo.NeType, neInfo.NeId) + if neLicense.NeId != querys.NeId { + // 没有可访问网元授权激活数据! + c.JSON(200, result.ErrMsg(i18n.TKey(language, "neLicense.noData"))) + return + } + + // 查询网元状态 + neState, err := neService.NeState(neInfo) + if err != nil { + c.JSON(200, result.ErrMsg("network element service anomaly")) + return + } + + // 更新授权信息 + neLicense.SerialNum = fmt.Sprint(neState["sn"]) + neLicense.ExpiryDate = fmt.Sprint(neState["expire"]) + code, licensePath := s.neLicenseService.ReadLicenseInfo(neInfo) + neLicense.ActivationRequestCode = code + neLicense.LicensePath = licensePath + neLicense.Status = "1" + neLicense.UpdateBy = ctx.LoginUserToUserName(c) + rows := s.neLicenseService.Update(neLicense) + if rows > 0 { + c.JSON(200, result.OkData(map[string]string{ + "sn": neLicense.SerialNum, + "expire": neLicense.ExpiryDate, + })) + return + } + c.JSON(200, result.Err(nil)) +} diff --git a/src/modules/network_element/controller/ne_software.go b/src/modules/network_element/controller/ne_software.go index 1001392..03d1614 100644 --- a/src/modules/network_element/controller/ne_software.go +++ b/src/modules/network_element/controller/ne_software.go @@ -49,7 +49,7 @@ func (s *NeSoftwareController) Info(c *gin.Context) { neSoftware := s.neSoftwareService.SelectById(softwareId) if neSoftware.ID != softwareId { - // 没有可访问网元版本数据! + // 没有可访问网元包信息数据! c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData"))) return } @@ -64,20 +64,21 @@ func (s *NeSoftwareController) Add(c *gin.Context) { language := ctx.AcceptLanguage(c) var body model.NeSoftware err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || body.ID != "" { + if err != nil || body.Path == "" || body.ID != "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查属性值唯一 - uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndFileNameAndVersion(body.NeType, body.FileName, body.Version, "") + uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndNameAndVersion(body.NeType, body.Name, body.Version, "") if !uniqueSoftware { // 网元软件包操作【%s】失败,网元类型与文件名版本已存在 - msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.FileName}) + msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.Name}) c.JSON(200, result.ErrMsg(msg)) return } + body.CreateBy = ctx.LoginUserToUserName(c) insertId := s.neSoftwareService.Insert(body) if insertId != "" { c.JSON(200, result.Ok(nil)) @@ -93,16 +94,16 @@ func (s *NeSoftwareController) Edit(c *gin.Context) { language := ctx.AcceptLanguage(c) var body model.NeSoftware err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil || body.ID == "" { + if err != nil || body.Path == "" || body.ID == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 检查属性值唯一 - uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndFileNameAndVersion(body.NeType, body.FileName, body.Version, body.ID) + uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndNameAndVersion(body.NeType, body.Name, body.Version, body.ID) if !uniqueSoftware { // 网元软件包操作【%s】失败,网元类型与文件名版本已存在 - msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.FileName}) + msg := i18n.TTemplate(language, "neSoftware.errKeyExists", map[string]any{"name": body.Name}) c.JSON(200, result.ErrMsg(msg)) return } @@ -110,11 +111,12 @@ func (s *NeSoftwareController) Edit(c *gin.Context) { // 检查是否存在 neSoftware := s.neSoftwareService.SelectById(body.ID) if neSoftware.ID != body.ID { - // 没有可访问网元版本数据! + // 没有可访问网元包信息数据! c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData"))) return } + body.UpdateBy = ctx.LoginUserToUserName(c) rows := s.neSoftwareService.Update(body) if rows > 0 { c.JSON(200, result.Ok(nil)) @@ -149,32 +151,40 @@ func (s *NeSoftwareController) Remove(c *gin.Context) { c.JSON(200, result.OkMsg(msg)) } -// 网元软件包安装 +// 网元软件包安装检查 // -// POST /install -func (s *NeSoftwareController) Install(c *gin.Context) { +// POST /checkInstall +func (s *NeSoftwareController) CheckInstall(c *gin.Context) { language := ctx.AcceptLanguage(c) var body model.NeSoftware err := c.ShouldBindBodyWith(&body, binding.JSON) - if err != nil { + if err != nil || body.HostId == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } - // 检查是否存在 - neSoftwares := s.neSoftwareService.SelectList(body) - if len(neSoftwares) == 0 { - // 没有可访问网元版本数据! - c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData"))) - return + // 检查是否存在软件包记录 + neSoftwares := s.neSoftwareService.SelectList(model.NeSoftware{ + NeType: body.NeType, + Name: body.Name, + Version: body.Version, + }) + if len(neSoftwares) <= 0 { + body.CreateBy = ctx.LoginUserToUserName(c) + body.ID = s.neSoftwareService.Insert(body) + } else { + neSoftware := neSoftwares[0] + neSoftware.Path = body.Path + neSoftware.Description = body.Description + neSoftware.UpdateBy = ctx.LoginUserToUserName(c) + s.neSoftwareService.Update(neSoftware) } - neSoftware := neSoftwares[0] - // 进行安装 - output, err := s.neSoftwareService.Install(neSoftware) + // 进行安装检查 + cmdStrArr, err := s.neSoftwareService.UploadToNeHost(body) if err != nil { - c.JSON(200, result.OkData(output)) + c.JSON(200, result.ErrMsg(err.Error())) return } - c.JSON(200, result.Err(nil)) + c.JSON(200, result.OkData(cmdStrArr)) } diff --git a/src/modules/network_element/controller/ne_version.go b/src/modules/network_element/controller/ne_version.go index 8e4710f..5fab991 100644 --- a/src/modules/network_element/controller/ne_version.go +++ b/src/modules/network_element/controller/ne_version.go @@ -78,6 +78,7 @@ func (s *NeVersionController) Add(c *gin.Context) { return } + body.CreateBy = ctx.LoginUserToUserName(c) insertId := s.neVersionService.Insert(body) if insertId != "" { c.JSON(200, result.Ok(nil)) @@ -115,6 +116,7 @@ func (s *NeVersionController) Edit(c *gin.Context) { return } + body.UpdateBy = ctx.LoginUserToUserName(c) rows := s.neVersionService.Update(body) if rows > 0 { c.JSON(200, result.Ok(nil)) diff --git a/src/modules/network_element/model/ne_license.go b/src/modules/network_element/model/ne_license.go new file mode 100644 index 0000000..2f202bc --- /dev/null +++ b/src/modules/network_element/model/ne_license.go @@ -0,0 +1,28 @@ +package model + +// NeLicense 网元授权激活信息 ne_license +type NeLicense struct { + ID string `json:"id" gorm:"id"` + NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型 + NeId string `json:"neId" gorm:"ne_id" binding:"required"` // 网元ID + ActivationRequestCode string `json:"activationRequestCode" gorm:"activation_request_code"` // 激活申请代码 + LicensePath string `json:"licensePath" gorm:"license_path"` // 激活授权文件 + SerialNum string `json:"serialNum" gorm:"serial_num"` // 序列号 + ExpiryDate string `json:"expiryDate" gorm:"expiry_date"` // 许可证到期日期 + Status string `json:"status" gorm:"status"` // 状态 ''ACTIVE'',''INACTIVE'',''PENDING'' + Remark string `json:"remark" gorm:"remark"` // 备注 + CreateBy string `json:"createBy" gorm:"create_by"` // 创建者 + CreateTime int64 `json:"createTime" gorm:"create_time"` // 创建时间 + UpdateBy string `json:"updateBy" gorm:"update_by"` // 更新者 + UpdateTime int64 `json:"updateTime" gorm:"update_time"` // 更新时间 + + // ====== 非数据库字段属性 ====== + + Reload bool `json:"reload,omitempty" gorm:"-"` // 刷新重启网元 + HostId string `json:"hostId,omitempty" gorm:"-"` // 已记录的主机ID +} + +// TableName 表名称 +func (*NeLicense) TableName() string { + return "ne_license" +} diff --git a/src/modules/network_element/model/ne_software.go b/src/modules/network_element/model/ne_software.go index afb6dff..d016616 100644 --- a/src/modules/network_element/model/ne_software.go +++ b/src/modules/network_element/model/ne_software.go @@ -1,18 +1,21 @@ package model -import "time" - // NeSoftware 网元软件包 ne_software type NeSoftware struct { - ID string `json:"id" gorm:"id"` - NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型 - FileName string `json:"fileName" gorm:"file_name" binding:"required"` // 包名称 - Path string `json:"path" gorm:"path"` // 包路径 - Version string `json:"version" gorm:"version" binding:"required"` // 包版本 - Md5Sum string `json:"md5Sum" gorm:"md5_sum"` // --无使用 md5签名 - Status string `json:"status" gorm:"status"` // --无使用 - Comment string `json:"comment" gorm:"comment"` // 包说明 - UpdateTime time.Time `json:"updateTime" gorm:"update_time"` // 上传时间 + ID string `json:"id" gorm:"id"` + NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型 + Name string `json:"name" gorm:"name" binding:"required"` // 包名称 + Path string `json:"path" gorm:"path"` // 包路径 + Version string `json:"version" gorm:"version" binding:"required"` // 包版本 + Description string `json:"description" gorm:"description"` // 包说明 + CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者 + CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间 + UpdateBy string `json:"updateBy" gorm:"column:update_by"` // 更新者 + UpdateTime int64 `json:"updateTime" gorm:"column:update_time"` // 更新时间 + + // ====== 非数据库字段属性 ====== + + HostId string `json:"hostId,omitempty" gorm:"-"` // 已记录的主机ID } // TableName 表名称 diff --git a/src/modules/network_element/model/ne_version.go b/src/modules/network_element/model/ne_version.go index 11a00e6..50f21cc 100644 --- a/src/modules/network_element/model/ne_version.go +++ b/src/modules/network_element/model/ne_version.go @@ -1,20 +1,21 @@ package model -import "time" - // NeVersion 网元版本信息 ne_version type NeVersion struct { - ID string `json:"id" gorm:"id"` - NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型 - NeId string `json:"neId" gorm:"ne_id" binding:"required"` // 网元ID - Version string `json:"version" gorm:"version"` // 当前版本 - FilePath string `json:"filePath" gorm:"file_path"` // 当前软件包 - PreVersion string `json:"preVersion" gorm:"pre_version"` // 上一版本 - PreFile string `json:"preFile" gorm:"pre_file"` // 上一版本软件包 - NewVersion string `json:"newVersion" gorm:"new_version"` // 下一版本 - NewFile string `json:"newFile" gorm:"new_file"` // 下一版本软件包 - Status string `json:"status" gorm:"status" binding:"oneof=Uploaded Inactive Active"` // 当前状态 (Uploaded下一版本上传 Inactive下一版本待激活 Active当前已激活) - UpdateTime time.Time `json:"updateTime" gorm:"update_time"` // 更新时间 + ID string `json:"id" gorm:"id"` + NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型 + NeId string `json:"neId" gorm:"ne_id" binding:"required"` // 网元ID + Version string `json:"version" gorm:"version" binding:"required"` // 当前版本 + Path string `json:"path" gorm:"path" binding:"required"` // 当前软件包 + PreVersion string `json:"preVersion" gorm:"pre_version"` // 上一版本 + PrePath string `json:"prePath" gorm:"pre_path"` // 上一版本软件包 + NewVersion string `json:"newVersion" gorm:"new_version"` // 下一版本 + NewPath string `json:"newPath" gorm:"new_path"` // 下一版本软件包 + Status string `json:"status" gorm:"status"` // 当前状态 (Uploaded下一版本上传 Inactive下一版本待激活 Active当前已激活) + CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者 + CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间 + UpdateBy string `json:"updateBy" gorm:"column:update_by"` // 更新者 + UpdateTime int64 `json:"updateTime" gorm:"column:update_time"` // 更新时间 } // TableName 表名称 diff --git a/src/modules/network_element/model/udm_auth.go b/src/modules/network_element/model/udm_auth.go index 2fe70e2..9069858 100644 --- a/src/modules/network_element/model/udm_auth.go +++ b/src/modules/network_element/model/udm_auth.go @@ -2,14 +2,14 @@ package model // UDMAuth UDM鉴权用户对象 u_auth_user type UDMAuth struct { - ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` - Imsi string `json:"imsi" gorm:"column:imsi"` // SIM卡号 - Amf string `json:"amf" gorm:"column:amf"` // ANF - Status string `json:"status" gorm:"column:status"` // 状态 - Ki string `json:"ki" gorm:"column:ki"` // ki - AlgoIndex string `json:"algoIndex" gorm:"column:algo_index"` // AlgoIndex - Opc string `json:"opc" gorm:"column:opc"` - NeID string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统 + ID string `json:"id" gorm:"column:id;primaryKey;autoIncrement"` // 默认ID + Imsi string `json:"imsi" gorm:"column:imsi"` // SIM卡号 + Amf string `json:"amf" gorm:"column:amf"` // ANF + Status string `json:"status" gorm:"column:status"` // 状态 + Ki string `json:"ki" gorm:"column:ki"` // ki + AlgoIndex string `json:"algoIndex" gorm:"column:algo_index"` // AlgoIndex + Opc string `json:"opc" gorm:"column:opc"` // opc + NeID string `json:"neId" gorm:"column:ne_id"` // UDM网元标识-子系统 } func (UDMAuth) TableName() string { diff --git a/src/modules/network_element/model/udm_sub.go b/src/modules/network_element/model/udm_sub.go index 1aa345c..55a56ef 100644 --- a/src/modules/network_element/model/udm_sub.go +++ b/src/modules/network_element/model/udm_sub.go @@ -25,6 +25,8 @@ type UDMSub struct { ApnContext string `json:"apnContext" gorm:"column:apn_context"` StaticIp string `json:"staticIp" gorm:"column:static_ip"` + // ====== 非数据库字段属性 ====== + SubNum string `json:"subNum,omitempty" gorm:"-"` // 批量数 } diff --git a/src/modules/network_element/network_element.go b/src/modules/network_element/network_element.go index e767da0..e877615 100644 --- a/src/modules/network_element/network_element.go +++ b/src/modules/network_element/network_element.go @@ -41,10 +41,26 @@ func Setup(router *gin.Engine) { // 网元信息 neInfoGroup := neGroup.Group("/info") { + neInfoGroup.GET("/state", + middleware.PreAuthorize(nil), + controller.NewNeInfo.State, + ) + neInfoGroup.GET("/byTypeAndID", + middleware.PreAuthorize(nil), + controller.NewNeInfo.NeTypeAndID, + ) neInfoGroup.GET("/listAll", middleware.PreAuthorize(nil), controller.NewNeInfo.ListAll, ) + neInfoGroup.GET("/configFile", + middleware.PreAuthorize(nil), + controller.NewNeInfo.ConfigFileRead, + ) + neInfoGroup.PUT("/configFile", + middleware.PreAuthorize(nil), + controller.NewNeInfo.ConfigFileWrite, + ) neInfoGroup.GET("/list", middleware.PreAuthorize(nil), controller.NewNeInfo.List, @@ -68,14 +84,6 @@ func Setup(router *gin.Engine) { collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neInfo", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewNeInfo.Remove, ) - neInfoGroup.GET("/state", - middleware.PreAuthorize(nil), - controller.NewNeInfo.State, - ) - neInfoGroup.GET("/byTypeAndID", - middleware.PreAuthorize(nil), - controller.NewNeInfo.NeTypeAndID, - ) } // 网元主机 @@ -119,6 +127,11 @@ func Setup(router *gin.Engine) { collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_OTHER)), controller.NewNeHost.CheckBySSH, ) + neHostGroup.POST("/authorizedBySSH", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neHost", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewNeHost.AuthorizedBySSH, + ) } // 网元主机命令 @@ -203,10 +216,51 @@ func Setup(router *gin.Engine) { collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neSoftware", collectlogs.BUSINESS_TYPE_DELETE)), controller.NewNeSoftware.Remove, ) - neSoftwareGroup.POST("/install", + neSoftwareGroup.POST("/checkInstall", middleware.PreAuthorize(nil), - collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neSoftware", collectlogs.BUSINESS_TYPE_DELETE)), - controller.NewNeSoftware.Install, + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neSoftware", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewNeSoftware.CheckInstall, + ) + } + + // 网元授权激活信息 + neLicenseGroup := neGroup.Group("/license") + { + neLicenseGroup.GET("/list", + middleware.PreAuthorize(nil), + controller.NewNeLicense.List, + ) + neLicenseGroup.GET("/:licenseId", + middleware.PreAuthorize(nil), + controller.NewNeLicense.Info, + ) + neLicenseGroup.POST("", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_INSERT)), + controller.NewNeLicense.Add, + ) + neLicenseGroup.PUT("", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_UPDATE)), + controller.NewNeLicense.Edit, + ) + neLicenseGroup.DELETE("/:licenseIds", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_DELETE)), + controller.NewNeLicense.Remove, + ) + neLicenseGroup.GET("/code", + middleware.PreAuthorize(nil), + controller.NewNeLicense.Code, + ) + neLicenseGroup.POST("/change", + middleware.PreAuthorize(nil), + collectlogs.OperateLog(collectlogs.OptionNew("log.operate.title.neLicense", collectlogs.BUSINESS_TYPE_OTHER)), + controller.NewNeLicense.Change, + ) + neLicenseGroup.GET("/state", + middleware.PreAuthorize(nil), + controller.NewNeLicense.State, ) } diff --git a/src/modules/network_element/repository/ne_info.impl.go b/src/modules/network_element/repository/ne_info.impl.go index 732de0d..85fdea5 100644 --- a/src/modules/network_element/repository/ne_info.impl.go +++ b/src/modules/network_element/repository/ne_info.impl.go @@ -29,6 +29,7 @@ var neListSort = []string{ "N3IWF", "NEF", "LMF", + "MOCNGW", } // 实例化数据层 NeInfoImpl 结构体 diff --git a/src/modules/network_element/repository/ne_license.go b/src/modules/network_element/repository/ne_license.go new file mode 100644 index 0000000..c185d67 --- /dev/null +++ b/src/modules/network_element/repository/ne_license.go @@ -0,0 +1,27 @@ +package repository + +import "be.ems/src/modules/network_element/model" + +// INeLicense 网元授权激活信息 数据层接口 +type INeLicense interface { + // SelectPage 根据条件分页查询字典类型 + SelectPage(query map[string]any) map[string]any + + // SelectList 根据实体查询 + SelectList(neLicense model.NeLicense) []model.NeLicense + + // SelectByIds 通过ID查询 + SelectByIds(ids []string) []model.NeLicense + + // Insert 新增信息 + Insert(neLicense model.NeLicense) string + + // Update 修改信息 + Update(neLicense model.NeLicense) int64 + + // DeleteByIds 批量删除信息 + DeleteByIds(ids []string) int64 + + // CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一 + CheckUniqueTypeAndID(neLicense model.NeLicense) string +} diff --git a/src/modules/network_element/repository/ne_license.impl.go b/src/modules/network_element/repository/ne_license.impl.go new file mode 100644 index 0000000..fcbb1f0 --- /dev/null +++ b/src/modules/network_element/repository/ne_license.impl.go @@ -0,0 +1,333 @@ +package repository + +import ( + "fmt" + "strings" + "time" + + "be.ems/src/framework/datasource" + "be.ems/src/framework/logger" + "be.ems/src/framework/utils/parse" + "be.ems/src/framework/utils/repo" + "be.ems/src/modules/network_element/model" +) + +// 实例化数据层 NewNeLicense 结构体 +var NewNeLicenseImpl = &NeLicenseImpl{ + selectSql: `select + id, ne_type, ne_id, activation_request_code, license_path, serial_num, expiry_date, status, remark, create_by, create_time, update_by, update_time + from ne_license`, + + resultMap: map[string]string{ + "id": "ID", + "ne_type": "NeType", + "ne_id": "NeId", + "activation_request_code": "ActivationRequestCode", + "license_path": "LicensePath", + "serial_num": "SerialNum", + "expiry_date": "ExpiryDate", + "status": "Status", + "remark": "Remark", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", + "update_time": "UpdateTime", + }, +} + +// NeLicenseImpl 网元授权激活信息 数据层处理 +type NeLicenseImpl struct { + // 查询视图对象SQL + selectSql string + // 结果字段与实体映射 + resultMap map[string]string +} + +// convertResultRows 将结果记录转实体结果组 +func (r *NeLicenseImpl) convertResultRows(rows []map[string]any) []model.NeLicense { + arr := make([]model.NeLicense, 0) + for _, row := range rows { + item := model.NeLicense{} + for key, value := range row { + if keyMapper, ok := r.resultMap[key]; ok { + repo.SetFieldValue(&item, keyMapper, value) + } + } + arr = append(arr, item) + } + return arr +} + +// SelectPage 根据条件分页查询字典类型 +func (r *NeLicenseImpl) SelectPage(query map[string]any) map[string]any { + // 查询条件拼接 + var conditions []string + var params []any + if v, ok := query["neType"]; ok && v != "" { + conditions = append(conditions, "ne_type = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["neId"]; ok && v != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["expiryDate"]; ok && v != "" { + conditions = append(conditions, "expiry_date = ?") + params = append(params, strings.Trim(v.(string), " ")) + } + if v, ok := query["createBy"]; ok && v != "" { + conditions = append(conditions, "create_by like concat(?, '%')") + params = append(params, strings.Trim(v.(string), " ")) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + result := map[string]any{ + "total": 0, + "rows": []model.NeHost{}, + } + + // 查询数量 长度为0直接返回 + totalSql := "select count(1) as 'total' from ne_license" + totalRows, err := datasource.RawDB("", totalSql+whereSql, params) + if err != nil { + logger.Errorf("total err => %v", err) + return result + } + total := parse.Number(totalRows[0]["total"]) + if total == 0 { + return result + } else { + result["total"] = total + } + + // 分页 + pageNum, pageSize := repo.PageNumSize(query["pageNum"], query["pageSize"]) + pageSql := " limit ?,? " + params = append(params, pageNum*pageSize) + params = append(params, pageSize) + + // 查询数据 + querySql := r.selectSql + whereSql + pageSql + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + return result + } + + // 转换实体 + result["rows"] = r.convertResultRows(results) + return result +} + +// SelectList 根据实体查询 +func (r *NeLicenseImpl) SelectList(neLicense model.NeLicense) []model.NeLicense { + // 查询条件拼接 + var conditions []string + var params []any + if neLicense.NeType != "" { + conditions = append(conditions, "ne_type = ?") + params = append(params, neLicense.NeType) + } + if neLicense.NeId != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, neLicense.NeId) + } + if neLicense.ExpiryDate != "" { + conditions = append(conditions, "expiry_date = ?") + params = append(params, neLicense.ExpiryDate) + } + if neLicense.CreateBy != "" { + conditions = append(conditions, "create_by like concat(?, '%')") + params = append(params, neLicense.CreateBy) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } + + // 查询数据 + querySql := r.selectSql + whereSql + " order by id asc " + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err => %v", err) + } + + // 转换实体 + return r.convertResultRows(results) +} + +// SelectByIds 通过ID查询 +func (r *NeLicenseImpl) SelectByIds(cmdIds []string) []model.NeLicense { + placeholder := repo.KeyPlaceholderByQuery(len(cmdIds)) + querySql := r.selectSql + " where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(cmdIds) + results, err := datasource.RawDB("", querySql, parameters) + if err != nil { + logger.Errorf("query err => %v", err) + return []model.NeLicense{} + } + // 转换实体 + return r.convertResultRows(results) +} + +// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一 +func (r *NeLicenseImpl) CheckUniqueTypeAndID(neLicense model.NeLicense) string { + // 查询条件拼接 + var conditions []string + var params []any + if neLicense.NeType != "" { + conditions = append(conditions, "ne_type = ?") + params = append(params, neLicense.NeType) + } + if neLicense.NeId != "" { + conditions = append(conditions, "ne_id = ?") + params = append(params, neLicense.NeId) + } + + // 构建查询条件语句 + whereSql := "" + if len(conditions) > 0 { + whereSql += " where " + strings.Join(conditions, " and ") + } else { + return "" + } + + // 查询数据 + querySql := "select id as 'str' from ne_license " + whereSql + " limit 1" + results, err := datasource.RawDB("", querySql, params) + if err != nil { + logger.Errorf("query err %v", err) + return "" + } + if len(results) > 0 { + return fmt.Sprint(results[0]["str"]) + } + return "" +} + +// Insert 新增信息 +func (r *NeLicenseImpl) Insert(neLicense model.NeLicense) string { + // 参数拼接 + params := make(map[string]any) + if neLicense.NeType != "" { + params["ne_type"] = neLicense.NeType + } + if neLicense.NeId != "" { + params["ne_id"] = neLicense.NeId + } + if neLicense.ActivationRequestCode != "" { + params["activation_request_code"] = neLicense.ActivationRequestCode + } + if neLicense.LicensePath != "" { + params["license_path"] = neLicense.LicensePath + } + if neLicense.SerialNum != "" { + params["serial_num"] = neLicense.SerialNum + } + if neLicense.ExpiryDate != "" { + params["expiry_date"] = neLicense.ExpiryDate + } + if neLicense.Status != "" { + params["status"] = neLicense.Status + } + if neLicense.Remark != "" { + params["remark"] = neLicense.Remark + } + if neLicense.CreateBy != "" { + params["create_by"] = neLicense.CreateBy + params["create_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) + sql := "insert into ne_license (" + strings.Join(keys, ",") + ")values(" + placeholder + ")" + + db := datasource.DefaultDB() + // 开启事务 + tx := db.Begin() + // 执行插入 + err := tx.Exec(sql, values...).Error + if err != nil { + logger.Errorf("insert row : %v", err.Error()) + tx.Rollback() + return "" + } + // 获取生成的自增 ID + var insertedID string + err = tx.Raw("select last_insert_id()").Row().Scan(&insertedID) + if err != nil { + logger.Errorf("insert last id : %v", err.Error()) + tx.Rollback() + return "" + } + // 提交事务 + tx.Commit() + return insertedID +} + +// Update 修改信息 +func (r *NeLicenseImpl) Update(neLicense model.NeLicense) int64 { + // 参数拼接 + params := make(map[string]any) + if neLicense.NeType != "" { + params["ne_type"] = neLicense.NeType + } + if neLicense.NeId != "" { + params["ne_id"] = neLicense.NeId + } + if neLicense.ActivationRequestCode != "" { + params["activation_request_code"] = neLicense.ActivationRequestCode + } + if neLicense.LicensePath != "" { + params["license_path"] = neLicense.LicensePath + } + if neLicense.SerialNum != "" { + params["serial_num"] = neLicense.SerialNum + } + if neLicense.ExpiryDate != "" { + params["expiry_date"] = neLicense.ExpiryDate + } + if neLicense.Status != "" { + params["status"] = neLicense.Status + } + if neLicense.Remark != "" { + params["remark"] = neLicense.Remark + } + if neLicense.UpdateBy != "" { + params["update_by"] = neLicense.UpdateBy + params["update_time"] = time.Now().UnixMilli() + } + + // 构建执行语句 + keys, values := repo.KeyValueByUpdate(params) + sql := "update ne_license set " + strings.Join(keys, ",") + " where id = ?" + + // 执行更新 + values = append(values, neLicense.ID) + rows, err := datasource.ExecDB("", sql, values) + if err != nil { + logger.Errorf("update row : %v", err.Error()) + return 0 + } + return rows +} + +// DeleteByIds 批量删除信息 +func (r *NeLicenseImpl) DeleteByIds(cmdIds []string) int64 { + placeholder := repo.KeyPlaceholderByQuery(len(cmdIds)) + sql := "delete from ne_license where id in (" + placeholder + ")" + parameters := repo.ConvertIdsSlice(cmdIds) + results, err := datasource.ExecDB("", sql, parameters) + if err != nil { + logger.Errorf("delete err => %v", err) + return 0 + } + return results +} diff --git a/src/modules/network_element/repository/ne_software.go b/src/modules/network_element/repository/ne_software.go index 98947d2..f6d0f23 100644 --- a/src/modules/network_element/repository/ne_software.go +++ b/src/modules/network_element/repository/ne_software.go @@ -22,6 +22,6 @@ type INeSoftware interface { // DeleteByIds 批量删除信息 DeleteByIds(ids []string) int64 - // CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一 - CheckUniqueTypeAndFileNameAndVersion(neSoftware model.NeSoftware) string + // CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一 + CheckUniqueTypeAndNameAndVersion(neSoftware model.NeSoftware) string } diff --git a/src/modules/network_element/repository/ne_software.impl.go b/src/modules/network_element/repository/ne_software.impl.go index 3116b52..133dd42 100644 --- a/src/modules/network_element/repository/ne_software.impl.go +++ b/src/modules/network_element/repository/ne_software.impl.go @@ -15,18 +15,19 @@ import ( // 实例化数据层 NewNeSoftware 结构体 var NewNeSoftwareImpl = &NeSoftwareImpl{ selectSql: `select - id, ne_type, file_name, path, version, md5_sum, status, comment, update_time + id, ne_type, name, path, version, description, create_by, create_time, update_by, update_time from ne_software`, resultMap: map[string]string{ "id": "ID", "ne_type": "NeType", - "file_name": "FileName", + "name": "Name", "path": "Path", "version": "Version", - "md5_sum": "Md5Sum", - "status": "Status", - "comment": "Comment", + "description": "Description", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", "update_time": "UpdateTime", }, } @@ -63,8 +64,8 @@ func (r *NeSoftwareImpl) SelectPage(query map[string]any) map[string]any { conditions = append(conditions, "ne_type = ?") params = append(params, strings.Trim(v.(string), " ")) } - if v, ok := query["fileName"]; ok && v != "" { - conditions = append(conditions, "file_name like concat(?, '%')") + if v, ok := query["name"]; ok && v != "" { + conditions = append(conditions, "name like concat(?, '%')") params = append(params, strings.Trim(v.(string), " ")) } if v, ok := query["version"]; ok && v != "" { @@ -133,9 +134,9 @@ func (r *NeSoftwareImpl) SelectList(neSoftware model.NeSoftware) []model.NeSoftw conditions = append(conditions, "version = ?") params = append(params, neSoftware.Version) } - if neSoftware.FileName != "" { - conditions = append(conditions, "file_name like concat(?, '%')") - params = append(params, neSoftware.FileName) + if neSoftware.Name != "" { + conditions = append(conditions, "name like concat(?, '%')") + params = append(params, neSoftware.Name) } // 构建查询条件语句 @@ -169,8 +170,8 @@ func (r *NeSoftwareImpl) SelectByIds(cmdIds []string) []model.NeSoftware { return r.convertResultRows(results) } -// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一 -func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neSoftware model.NeSoftware) string { +// CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一 +func (r *NeSoftwareImpl) CheckUniqueTypeAndNameAndVersion(neSoftware model.NeSoftware) string { // 查询条件拼接 var conditions []string var params []any @@ -182,9 +183,9 @@ func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neSoftware model.N conditions = append(conditions, "version = ?") params = append(params, neSoftware.Version) } - if neSoftware.FileName != "" { - conditions = append(conditions, "file_name = ?") - params = append(params, neSoftware.FileName) + if neSoftware.Name != "" { + conditions = append(conditions, "name = ?") + params = append(params, neSoftware.Name) } // 构建查询条件语句 @@ -215,8 +216,8 @@ func (r *NeSoftwareImpl) Insert(neSoftware model.NeSoftware) string { if neSoftware.NeType != "" { params["ne_type"] = neSoftware.NeType } - if neSoftware.FileName != "" { - params["file_name"] = neSoftware.FileName + if neSoftware.Name != "" { + params["name"] = neSoftware.Name } if neSoftware.Path != "" { params["path"] = neSoftware.Path @@ -224,19 +225,11 @@ func (r *NeSoftwareImpl) Insert(neSoftware model.NeSoftware) string { if neSoftware.Version != "" { params["version"] = neSoftware.Version } - if neSoftware.Md5Sum != "" { - params["md5_sum"] = neSoftware.Md5Sum + params["description"] = neSoftware.Description + if neSoftware.CreateBy != "" { + params["create_by"] = neSoftware.CreateBy + params["create_time"] = time.Now().UnixMilli() } - if neSoftware.Status != "" { - params["status"] = neSoftware.Status - } - if neSoftware.Comment != "" { - params["comment"] = neSoftware.Comment - } - if neSoftware.Status != "" { - params["status"] = neSoftware.Status - } - params["update_time"] = time.Now() // 构建执行语句 keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) @@ -272,8 +265,8 @@ func (r *NeSoftwareImpl) Update(neSoftware model.NeSoftware) int64 { if neSoftware.NeType != "" { params["ne_type"] = neSoftware.NeType } - if neSoftware.FileName != "" { - params["file_name"] = neSoftware.FileName + if neSoftware.Name != "" { + params["name"] = neSoftware.Name } if neSoftware.Path != "" { params["path"] = neSoftware.Path @@ -281,19 +274,11 @@ func (r *NeSoftwareImpl) Update(neSoftware model.NeSoftware) int64 { if neSoftware.Version != "" { params["version"] = neSoftware.Version } - if neSoftware.Md5Sum != "" { - params["md5_sum"] = neSoftware.Md5Sum + params["description"] = neSoftware.Description + if neSoftware.UpdateBy != "" { + params["update_by"] = neSoftware.UpdateBy + params["update_time"] = time.Now().UnixMilli() } - if neSoftware.Status != "" { - params["status"] = neSoftware.Status - } - if neSoftware.Comment != "" { - params["comment"] = neSoftware.Comment - } - if neSoftware.Status != "" { - params["status"] = neSoftware.Status - } - params["update_time"] = time.Now() // 构建执行语句 keys, values := repo.KeyValueByUpdate(params) diff --git a/src/modules/network_element/repository/ne_version.impl.go b/src/modules/network_element/repository/ne_version.impl.go index 7bfefcd..7eebfec 100644 --- a/src/modules/network_element/repository/ne_version.impl.go +++ b/src/modules/network_element/repository/ne_version.impl.go @@ -15,7 +15,7 @@ import ( // 实例化数据层 NewNeVersion 结构体 var NewNeVersionImpl = &NeVersionImpl{ selectSql: `select - id, ne_type, ne_id, version, file_path, pre_version, pre_file, new_version, new_file, status, update_time + id, ne_type, ne_id, version, path, pre_version, pre_path, new_version, new_path, status, create_by, create_time, update_by, update_time from ne_version`, resultMap: map[string]string{ @@ -23,12 +23,15 @@ var NewNeVersionImpl = &NeVersionImpl{ "ne_type": "NeType", "ne_id": "NeId", "version": "Version", - "file_path": "FilePath", + "path": "Path", "pre_version": "PreVersion", - "pre_file": "PreFile", + "pre_path": "PrePath", "new_version": "NewVersion", - "new_file": "NewFile", + "new_path": "NewPath", "status": "Status", + "create_by": "CreateBy", + "create_time": "CreateTime", + "update_by": "UpdateBy", "update_time": "UpdateTime", }, } @@ -139,9 +142,9 @@ func (r *NeVersionImpl) SelectList(neVersion model.NeVersion) []model.NeVersion conditions = append(conditions, "version like concat(?, '%')") params = append(params, neVersion.Version) } - if neVersion.FilePath != "" { - conditions = append(conditions, "file_path like concat(?, '%')") - params = append(params, neVersion.FilePath) + if neVersion.Path != "" { + conditions = append(conditions, "path like concat(?, '%')") + params = append(params, neVersion.Path) } // 构建查询条件语句 @@ -151,7 +154,7 @@ func (r *NeVersionImpl) SelectList(neVersion model.NeVersion) []model.NeVersion } // 查询数据 - querySql := r.selectSql + whereSql + " order by update_time asc " + querySql := r.selectSql + whereSql + " order by id asc " results, err := datasource.RawDB("", querySql, params) if err != nil { logger.Errorf("query err => %v", err) @@ -223,25 +226,28 @@ func (r *NeVersionImpl) Insert(neVersion model.NeVersion) string { if neVersion.Version != "" { params["version"] = neVersion.Version } - if neVersion.FilePath != "" { - params["file_path"] = neVersion.FilePath + if neVersion.Path != "" { + params["path"] = neVersion.Path } if neVersion.PreVersion != "" { params["pre_version"] = neVersion.PreVersion } - if neVersion.PreFile != "" { - params["pre_file"] = neVersion.PreFile + if neVersion.PrePath != "" { + params["pre_path"] = neVersion.PrePath } if neVersion.NewVersion != "" { params["new_version"] = neVersion.NewVersion } - if neVersion.NewFile != "" { - params["new_file"] = neVersion.NewFile + if neVersion.NewPath != "" { + params["new_path"] = neVersion.NewPath } if neVersion.Status != "" { params["status"] = neVersion.Status } - params["update_time"] = time.Now() + if neVersion.CreateBy != "" { + params["create_by"] = neVersion.CreateBy + params["create_time"] = time.Now().UnixMilli() + } // 构建执行语句 keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params) @@ -283,25 +289,28 @@ func (r *NeVersionImpl) Update(neVersion model.NeVersion) int64 { if neVersion.Version != "" { params["version"] = neVersion.Version } - if neVersion.FilePath != "" { - params["file_path"] = neVersion.FilePath + if neVersion.Path != "" { + params["path"] = neVersion.Path } if neVersion.PreVersion != "" { params["pre_version"] = neVersion.PreVersion } - if neVersion.PreFile != "" { - params["pre_file"] = neVersion.PreFile + if neVersion.PrePath != "" { + params["pre_path"] = neVersion.PrePath } if neVersion.NewVersion != "" { params["new_version"] = neVersion.NewVersion } - if neVersion.NewFile != "" { - params["new_file"] = neVersion.NewFile + if neVersion.NewPath != "" { + params["new_path"] = neVersion.NewPath } if neVersion.Status != "" { params["status"] = neVersion.Status } - params["update_time"] = time.Now() + if neVersion.UpdateBy != "" { + params["update_by"] = neVersion.UpdateBy + params["update_time"] = time.Now().UnixMilli() + } // 构建执行语句 keys, values := repo.KeyValueByUpdate(params) diff --git a/src/modules/network_element/service/ne_direct_link.go b/src/modules/network_element/service/ne_direct_link.go index 5b239f1..7a4fa12 100644 --- a/src/modules/network_element/service/ne_direct_link.go +++ b/src/modules/network_element/service/ne_direct_link.go @@ -69,6 +69,11 @@ func NeConfigOMC(neInfo model.NeInfo) (map[string]any, error) { return nil, err } + // 200 成功无数据时 + if len(resBytes) == 0 { + return resData, nil + } + // 序列化结果 err = json.Unmarshal(resBytes, &resData) if err != nil { diff --git a/src/modules/network_element/service/ne_info.go b/src/modules/network_element/service/ne_info.go index a231b16..a667c01 100644 --- a/src/modules/network_element/service/ne_info.go +++ b/src/modules/network_element/service/ne_info.go @@ -42,4 +42,13 @@ type INeInfo interface { // CheckUniqueNeTypeAndNeId 校验同类型下标识是否唯一 CheckUniqueNeTypeAndNeId(neType, neId, infoId string) bool + + // NeRunCMD 向网元发送cmd命令 + NeRunCMD(neType, neId, cmd string) (string, error) + + // NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取 + NeConfigFileRead(neInfo model.NeInfo, filePath string) []string + + // NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端 + NeConfigFileWirte(neInfo model.NeInfo, filePath, content string, sync bool) error } diff --git a/src/modules/network_element/service/ne_info.impl.go b/src/modules/network_element/service/ne_info.impl.go index 142b1cc..666617e 100644 --- a/src/modules/network_element/service/ne_info.impl.go +++ b/src/modules/network_element/service/ne_info.impl.go @@ -3,10 +3,14 @@ package service import ( "encoding/json" "fmt" + "os" + "runtime" "strings" "be.ems/src/framework/constants/cachekey" + "be.ems/src/framework/logger" "be.ems/src/framework/redis" + "be.ems/src/framework/utils/ssh" "be.ems/src/modules/network_element/model" "be.ems/src/modules/network_element/repository" ) @@ -28,7 +32,7 @@ type NeInfoImpl struct { // SelectNeInfoByNeTypeAndNeID 通过ne_type和ne_id查询网元信息 func (r *NeInfoImpl) SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeInfo { var neInfo model.NeInfo - key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, neType, neID) + key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, strings.ToUpper(neType), neID) jsonStr, _ := redis.Get("", key) if len(jsonStr) > 7 { err := json.Unmarshal([]byte(jsonStr), &neInfo) @@ -37,7 +41,7 @@ func (r *NeInfoImpl) SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeIn } } else { neInfo = r.neInfoRepository.SelectNeInfoByNeTypeAndNeID(neType, neID) - if neInfo.NeId == neID { + if neInfo.ID != "" && neInfo.NeId == neID { redis.Del("", key) values, _ := json.Marshal(neInfo) redis.Set("", key, string(values)) @@ -49,10 +53,10 @@ func (r *NeInfoImpl) SelectNeInfoByNeTypeAndNeID(neType, neID string) model.NeIn // RefreshByNeTypeAndNeID 通过ne_type和ne_id刷新redis中的缓存 func (r *NeInfoImpl) RefreshByNeTypeAndNeID(neType, neID string) model.NeInfo { var neInfo model.NeInfo - key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, neType, neID) + key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, strings.ToUpper(neType), neID) redis.Del("", key) neInfo = r.neInfoRepository.SelectNeInfoByNeTypeAndNeID(neType, neID) - if neInfo.NeId == neID { + if neInfo.ID != "" && neInfo.NeId == neID { values, _ := json.Marshal(neInfo) redis.Set("", key, string(values)) } @@ -92,7 +96,7 @@ func (r *NeInfoImpl) SelectNeInfoByRmuid(rmUid string) model.NeInfo { } else { neInfos := r.SelectList(neInfo, false) for _, v := range neInfos { - key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, v.NeType, v.NeId) + key := fmt.Sprintf("%s%s:%s", cachekey.NE_KEY, strings.ToUpper(v.NeType), v.NeId) redis.Del("", key) values, _ := json.Marshal(v) redis.Set("", key, string(values)) @@ -124,6 +128,7 @@ func (r *NeInfoImpl) SelectPage(query map[string]any, bandStatus bool) map[strin // 网元状态设置为离线 if v.Status != "1" { v.Status = "1" + (*arr)[i].Status = v.Status r.neInfoRepository.Update(v) } continue @@ -139,6 +144,7 @@ func (r *NeInfoImpl) SelectPage(query map[string]any, bandStatus bool) map[strin } else { v.Status = "0" } + (*arr)[i].Status = v.Status r.neInfoRepository.Update(v) } } @@ -166,6 +172,7 @@ func (r *NeInfoImpl) SelectList(ne model.NeInfo, bandStatus bool) []model.NeInfo // 网元状态设置为离线 if v.Status != "1" { v.Status = "1" + (*neList)[i].Status = v.Status r.neInfoRepository.Update(v) } continue @@ -181,6 +188,7 @@ func (r *NeInfoImpl) SelectList(ne model.NeInfo, bandStatus bool) []model.NeInfo } else { v.Status = "0" } + (*neList)[i].Status = v.Status r.neInfoRepository.Update(v) } } @@ -290,3 +298,139 @@ func (r *NeInfoImpl) CheckUniqueNeTypeAndNeId(neType, neId, infoId string) bool } return uniqueId == "" } + +// NeRunCMD 向网元发送cmd命令 +func (r *NeInfoImpl) NeRunCMD(neType, neId, cmd string) (string, error) { + neInfo := r.SelectNeInfoByNeTypeAndNeID(neType, neId) + if neInfo.NeId != neId { + logger.Errorf("NeRunCMD NeType:%s NeID:%s not found", neType, neId) + return "", fmt.Errorf("neinfo not found") + } + // 带主机信息 + if neInfo.HostIDs != "" { + neInfo.Hosts = r.neHostRepository.SelectByIds(strings.Split(neInfo.HostIDs, ",")) + if len(neInfo.Hosts) <= 0 { + logger.Errorf("NeRunCMD Hosts %s not found", neInfo.HostIDs) + return "", fmt.Errorf("neinfo host not found") + } + } + + neHost := neInfo.Hosts[0] + if neHost.HostType != "ssh" { + logger.Errorf("NeRunCMD Hosts first HostType %s not ssh", neHost.HostType) + return "", fmt.Errorf("neinfo host type not ssh") + } + var connSSH ssh.ConnSSH + neHost.CopyTo(&connSSH) + client, err := connSSH.NewClient() + if err != nil { + logger.Errorf("NeRunCMD NewClient err => %s", err.Error()) + return "", fmt.Errorf("neinfo ssh client new err") + } + defer client.Close() + + // 执行命令 + output, err := client.RunCMD(cmd) + if err != nil { + logger.Errorf("NeRunCMD RunCMD %s err => %s", output, err.Error()) + return "", fmt.Errorf("neinfo ssh run cmd err") + } + + return output, nil +} + +// NeConfigFileRead 网元配置文件读取 网元配置yaml文件复制到本地后通过filePath读取 +func (r *NeInfoImpl) NeConfigFileRead(neInfo model.NeInfo, filePath string) []string { + files := []string{} + neTypeLower := strings.ToLower(neInfo.NeType) + + // 网管本地路径 + omcPath := "/usr/local/etc/omc/ne_config" + if runtime.GOOS == "windows" { + omcPath = fmt.Sprintf("C:%s", omcPath) + } + omcPath = fmt.Sprintf("%s/%s/%s", omcPath, neTypeLower, neInfo.NeId) + + // 读取文件内容 + if filePath != "" { + bytes, err := os.ReadFile(fmt.Sprintf("%s/%s", omcPath, filePath)) + if err != nil { + logger.Warnf("NeConfigFile ReadFile => %s", err.Error()) + return files + } + files = append(files, string(bytes)) + return files + } + + // 删除原有配置文件 + // err := os.RemoveAll(omcPath) + // if err != nil { + // logger.Warnf("NeConfigFile Remove => %s", err.Error()) + // return files + // } + + // 网元端配置路径 + nePath := "/usr/local/etc" + nePath = fmt.Sprintf("%s/%s", nePath, neTypeLower) + + // 各个网元与网元间约定配置文件 + err := ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/oam_manager.yaml", omcPath+"/oam_manager.yaml") + if err == nil { + files = append(files, "oam_manager.yaml") + } + + // 根据情况复制网元特殊配置 + switch neTypeLower { + case "ausf": + err = ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/ausfcfg.yaml", omcPath+"/ausfcfg.yaml") + if err == nil { + files = append(files, "ausfcfg.yaml") + } + case "smf": + ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/smf_conf.yaml", omcPath+"/smf_conf.yaml") + if err == nil { + files = append(files, "smf_conf.yaml") + } + ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/smf_policy.yaml", omcPath+"/smf_policy.yaml") + if err == nil { + files = append(files, "smf_policy.yaml") + } + case "ims": + } + + return files +} + +// NeConfigFileWirte 网元配置文件写入 content内容 sync同步到网元端 +func (r *NeInfoImpl) NeConfigFileWirte(neInfo model.NeInfo, filePath, content string, sync bool) error { + neTypeLower := strings.ToLower(neInfo.NeType) + + // 网管本地路径 + omcPath := "/usr/local/etc/omc/ne_config" + if runtime.GOOS == "windows" { + omcPath = fmt.Sprintf("C:%s", omcPath) + } + localFilePath := fmt.Sprintf("%s/%s/%s/%s", omcPath, neTypeLower, neInfo.NeId, filePath) + + err := os.WriteFile(localFilePath, []byte(content), 0644) + if err != nil { + logger.Warnf("NeConfigFile WriteFile => %s", err.Error()) + return fmt.Errorf("please check if the file exists or write permissions") + } + + // 同步到网元端 + if sync { + // 网元端配置路径 + neFilePath := fmt.Sprintf("/usr/local/etc/%s/%s", neTypeLower, filePath) + // 修改网元文件权限 + r.NeRunCMD(neInfo.NeType, neInfo.NeId, fmt.Sprintf("sudo chmod o+w %s", neFilePath)) + // 复制到网元进行覆盖 + err = ssh.FileSCPLocalToNe(neInfo.IP, localFilePath, neFilePath) + if err != nil { + logger.Warnf("NeConfigFile SyncFile => %s", err.Error()) + return fmt.Errorf("please check if scp remote copy is allowed") + } + } + + return nil +} diff --git a/src/modules/network_element/service/ne_license.go b/src/modules/network_element/service/ne_license.go new file mode 100644 index 0000000..c5ea23a --- /dev/null +++ b/src/modules/network_element/service/ne_license.go @@ -0,0 +1,37 @@ +package service + +import "be.ems/src/modules/network_element/model" + +// INeLicense 网元授权激活信息 服务层接口 +type INeLicense interface { + // SelectPage 根据条件分页查询字典类型 + SelectPage(query map[string]any) map[string]any + + // SelectList 根据实体查询 + SelectList(neLicense model.NeLicense) []model.NeLicense + + // SelectById 通过ID查询 + SelectById(id string) model.NeLicense + + // Insert 新增信息 + Insert(neLicense model.NeLicense) string + + // Update 修改信息 + Update(neLicense model.NeLicense) int64 + + // DeleteByIds 批量删除信息 + DeleteByIds(ids []string) (int64, error) + + // CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一 + CheckUniqueTypeAndID(neType, neId, id string) bool + + // SelectByNeTypeAndNeID 通过ne_type和ne_id查询信息 + SelectByNeTypeAndNeID(neType, neId string) model.NeLicense + + // ReadLicenseInfo 读取授权文件信息 + // 激活申请码, 激活文件 + ReadLicenseInfo(neInfo model.NeInfo) (string, string) + + // UploadToNeHost 授权文件上传到网元主机 + UploadToNeHost(neLicense model.NeLicense) error +} diff --git a/src/modules/network_element/service/ne_license.impl.go b/src/modules/network_element/service/ne_license.impl.go new file mode 100644 index 0000000..d41b191 --- /dev/null +++ b/src/modules/network_element/service/ne_license.impl.go @@ -0,0 +1,183 @@ +package service + +import ( + "fmt" + "os" + "runtime" + "strings" + "time" + + "be.ems/src/framework/utils/file" + "be.ems/src/framework/utils/ssh" + "be.ems/src/modules/network_element/model" + "be.ems/src/modules/network_element/repository" +) + +// 实例化服务层 NeLicenseImpl 结构体 +var NewNeLicenseImpl = &NeLicenseImpl{ + neLicenseRepository: repository.NewNeLicenseImpl, +} + +// NeLicenseImpl 网元授权激活信息 服务层处理 +type NeLicenseImpl struct { + // 网元授权激活信息表 + neLicenseRepository repository.INeLicense +} + +// SelectNeHostPage 分页查询列表数据 +func (r *NeLicenseImpl) SelectPage(query map[string]any) map[string]any { + return r.neLicenseRepository.SelectPage(query) +} + +// SelectConfigList 查询列表 +func (r *NeLicenseImpl) SelectList(neLicense model.NeLicense) []model.NeLicense { + return r.neLicenseRepository.SelectList(neLicense) +} + +// SelectByIds 通过ID查询 +func (r *NeLicenseImpl) SelectById(id string) model.NeLicense { + if id == "" { + return model.NeLicense{} + } + neLicenses := r.neLicenseRepository.SelectByIds([]string{id}) + if len(neLicenses) > 0 { + return neLicenses[0] + } + return model.NeLicense{} +} + +// Insert 新增信息 +func (r *NeLicenseImpl) Insert(neLicense model.NeLicense) string { + return r.neLicenseRepository.Insert(neLicense) +} + +// Update 修改信息 +func (r *NeLicenseImpl) Update(neLicense model.NeLicense) int64 { + return r.neLicenseRepository.Update(neLicense) +} + +// DeleteByIds 批量删除信息 +func (r *NeLicenseImpl) DeleteByIds(ids []string) (int64, error) { + // 检查是否存在 + rowIds := r.neLicenseRepository.SelectByIds(ids) + if len(rowIds) <= 0 { + return 0, fmt.Errorf("neLicense.noData") + } + + if len(rowIds) == len(ids) { + rows := r.neLicenseRepository.DeleteByIds(ids) + return rows, nil + } + // 删除信息失败! + return 0, fmt.Errorf("delete fail") +} + +// SelectByTypeAndID 通过网元类型和网元ID查询 +func (r *NeLicenseImpl) SelectByTypeAndID(neType, neId string) model.NeLicense { + neLicenses := r.neLicenseRepository.SelectList(model.NeLicense{ + NeType: neType, + NeId: neId, + }) + if len(neLicenses) > 0 { + return neLicenses[0] + } + return model.NeLicense{} +} + +// CheckUniqueTypeAndID 校验网元类型和网元ID是否唯一 +func (r *NeLicenseImpl) CheckUniqueTypeAndID(neType, neId, id string) bool { + uniqueId := r.neLicenseRepository.CheckUniqueTypeAndID(model.NeLicense{ + NeType: neType, + NeId: neId, + }) + if uniqueId == id { + return true + } + return uniqueId == "" +} + +// SelectByNeTypeAndNeID 通过ne_type和ne_id查询信息 +func (r *NeLicenseImpl) SelectByNeTypeAndNeID(neType, neId string) model.NeLicense { + neLicenses := r.neLicenseRepository.SelectList(model.NeLicense{ + NeType: neType, + NeId: neId, + }) + if len(neLicenses) > 0 { + return neLicenses[0] + } + return model.NeLicense{} +} + +// ReadLicenseInfo 读取授权文件信息 +// 激活申请码, 激活文件 +func (r *NeLicenseImpl) ReadLicenseInfo(neInfo model.NeInfo) (string, string) { + neTypeLower := strings.ToLower(neInfo.NeType) + // 网管本地路径 + omcPath := "/usr/local/etc/omc/ne_license" + if runtime.GOOS == "windows" { + omcPath = fmt.Sprintf("C:%s", omcPath) + } + omcPath = fmt.Sprintf("%s/%s/%s", omcPath, neTypeLower, neInfo.NeId) + // 网元端授权文件路径 + nePath := fmt.Sprintf("/usr/local/etc/%s/license", neTypeLower) + + // 复制授权申请码到本地 + err := ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/Activation_request_code.txt", omcPath+"/Activation_request_code.txt") + if err != nil { + return "", "" + } + // 读取文件内容 + bytes, err := os.ReadFile(omcPath + "/Activation_request_code.txt") + if err != nil { + return "", "" + } + + // 激活文件 + licensePath := "" + if err = ssh.FileSCPNeToLocal(neInfo.IP, nePath+"/system.ini", omcPath+"/system.ini"); err == nil { + licensePath = omcPath + "/system.ini" + } + return strings.TrimSpace(string(bytes)), licensePath +} + +// UploadToNeHost 授权文件上传到网元主机 +func (r *NeLicenseImpl) UploadToNeHost(neLicense model.NeLicense) error { + + // 检查文件是否存在 + omcLicensePath := file.ParseUploadFilePath(neLicense.LicensePath) + if _, err := os.Stat(omcLicensePath); err != nil { + return fmt.Errorf("file read failure") + } + + // 检查网元主机 + neHostInfo := NewNeHostImpl.SelectById(neLicense.HostId) + if neHostInfo.HostType != "ssh" || neHostInfo.HostID != neLicense.HostId { + return fmt.Errorf("no found host info") + } + + // 网元端授权文件路径 + neTypeLower := strings.ToLower(neLicense.NeType) + neLicensePath := fmt.Sprintf("/usr/local/etc/%s/license", neTypeLower) + // 修改文件夹权限 + NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo chmod o+w %s/", neLicensePath)) + // 尝试备份授权文件 + neLicensePathBack := fmt.Sprintf("%s/system_%s.ini", neLicensePath, time.Now().Format("20060102_150405")) + NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo cp -rf %s/system.ini %s", neLicensePath, neLicensePathBack)) + // 上传授权文件去覆盖 + NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, fmt.Sprintf("sudo chmod o+w %s/system.ini", neLicensePath)) + if err := ssh.FileSCPLocalToNe(neHostInfo.Addr, omcLicensePath, neLicensePath+"/system.ini"); err != nil { + return fmt.Errorf("error uploading license") + } + + // 重启服务 + if neLicense.Reload { + cmdStr := fmt.Sprintf("sudo service %s restart", neTypeLower) + if neTypeLower == "ims" { + cmdStr = "sudo ims-stop && sudo ims-start" + } else if neTypeLower == "omc" { + cmdStr = "sudo /usr/local/omc/bin/omcsvc.sh restart" + } + NewNeInfoImpl.NeRunCMD(neLicense.NeType, neLicense.NeId, cmdStr) + } + return nil +} diff --git a/src/modules/network_element/service/ne_software.go b/src/modules/network_element/service/ne_software.go index c4936ac..5f5e10f 100644 --- a/src/modules/network_element/service/ne_software.go +++ b/src/modules/network_element/service/ne_software.go @@ -22,12 +22,10 @@ type INeSoftware interface { // DeleteByIds 批量删除信息 DeleteByIds(ids []string) (int64, error) - // SelectByVersionAndPath 通过文件版本和路径查询 - SelectByVersionAndPath(version, path string) model.NeSoftware + // CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一 + CheckUniqueTypeAndNameAndVersion(neType, name, version, id string) bool - // CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一 - CheckUniqueTypeAndFileNameAndVersion(neType, fileName, version, id string) bool - - // Install 安装软件包 - Install(neSoftware model.NeSoftware) (string, error) + // UploadToNeHost 安装包上传到网元主机 + // 返回执行命令步骤 + UploadToNeHost(neSoftware model.NeSoftware) ([]string, error) } diff --git a/src/modules/network_element/service/ne_software.impl.go b/src/modules/network_element/service/ne_software.impl.go index 9978f4b..77783a3 100644 --- a/src/modules/network_element/service/ne_software.impl.go +++ b/src/modules/network_element/service/ne_software.impl.go @@ -2,7 +2,12 @@ package service import ( "fmt" + "os" + "path/filepath" + "strings" + "be.ems/src/framework/utils/file" + "be.ems/src/framework/utils/ssh" "be.ems/src/modules/network_element/model" "be.ems/src/modules/network_element/repository" ) @@ -66,24 +71,12 @@ func (r *NeSoftwareImpl) DeleteByIds(ids []string) (int64, error) { return 0, fmt.Errorf("delete fail") } -// SelectByVersionAndPath 通过文件版本和路径查询 -func (r *NeSoftwareImpl) SelectByVersionAndPath(version, path string) model.NeSoftware { - neSoftwares := r.neSoftwareRepository.SelectList(model.NeSoftware{ +// CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一 +func (r *NeSoftwareImpl) CheckUniqueTypeAndNameAndVersion(neType, name, version, id string) bool { + uniqueId := r.neSoftwareRepository.CheckUniqueTypeAndNameAndVersion(model.NeSoftware{ + NeType: neType, + Name: name, Version: version, - Path: path, - }) - if len(neSoftwares) > 0 { - return neSoftwares[0] - } - return model.NeSoftware{} -} - -// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一 -func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neType, fileName, version, id string) bool { - uniqueId := r.neSoftwareRepository.CheckUniqueTypeAndFileNameAndVersion(model.NeSoftware{ - NeType: neType, - FileName: fileName, - Version: version, }) if uniqueId == id { return true @@ -91,7 +84,54 @@ func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neType, fileName, return uniqueId == "" } -// Install 安装软件包 -func (r *NeSoftwareImpl) Install(neSoftware model.NeSoftware) (string, error) { - return "", nil +// UploadToNeHost 安装包上传到网元主机 +// 返回执行命令步骤 +func (r *NeSoftwareImpl) UploadToNeHost(neSoftware model.NeSoftware) ([]string, error) { + cmdStrArr := []string{} + // 检查文件是否存在 + filePath := file.ParseUploadFilePath(neSoftware.Path) + if _, err := os.Stat(filePath); err != nil { + return cmdStrArr, fmt.Errorf("file read failure") + } + fileName := filepath.Base(neSoftware.Path) + if strings.Contains(fileName, "*") { + fileName = strings.ReplaceAll(fileName, "*", "_") + } + nePath := "/tmp" + neFilePath := fmt.Sprintf("%s/%s", nePath, fileName) + + // 检查网元主机 + neHostInfo := NewNeHostImpl.SelectById(neSoftware.HostId) + if neHostInfo.HostType != "ssh" || neHostInfo.HostID != neSoftware.HostId { + return cmdStrArr, fmt.Errorf("no found host info") + } + + // 上传软件包到 /tmp + if err := ssh.FileSCPLocalToNe(neHostInfo.Addr, filePath, neFilePath); err != nil { + return cmdStrArr, fmt.Errorf("error uploading package") + } + + // 安装软件包 + cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo dpkg -i %s", neFilePath)) + + if neSoftware.NeType == "IMS" { + // 公网 PLMN地址 + cmdStrArr = append(cmdStrArr, "sudo /usr/local/etc/ims/default/tools/modipplmn.sh {PUBIP} {MCC} {MNC}") + // 内网 服务地址 + cmdStrArr = append(cmdStrArr, "sudo /usr/local/etc/ims/default/tools/modintraip.sh {PRIIP}") + // 10s后停止服务 + cmdStrArr = append(cmdStrArr, "sudo ims-start") + cmdStrArr = append(cmdStrArr, `nohup sh -c "sleep 10s && sudo ims-stop" > /dev/null 2>&1 &`) + } else { + // 10s后停止服务 + cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo service %s restart", strings.ToLower(neSoftware.NeType))) + cmdStrArr = append(cmdStrArr, fmt.Sprintf(`nohup sh -c "sleep 10s && sudo service %s stop" > /dev/null 2>&1 &`, strings.ToLower(neSoftware.NeType))) + } + + // 删除软件包 + cmdStrArr = append(cmdStrArr, fmt.Sprintf("sudo rm %s", neFilePath)) + + // 结束 + cmdStrArr = append(cmdStrArr, fmt.Sprintf("echo '%s software install successful!'", neSoftware.NeType)) + return cmdStrArr, nil } diff --git a/src/modules/system/controller/sys_config.go b/src/modules/system/controller/sys_config.go index 1b7258e..e697878 100644 --- a/src/modules/system/controller/sys_config.go +++ b/src/modules/system/controller/sys_config.go @@ -35,12 +35,17 @@ type SysConfigController struct { // // GET /list func (s *SysConfigController) List(c *gin.Context) { - querys := ctx.QueryMap(c) - data := s.sysConfigService.SelectConfigPage(querys) - - rows := data["rows"].([]model.SysConfig) - // 闭包函数处理多语言 language := ctx.AcceptLanguage(c) + querys := ctx.QueryMap(c) + // 多语言值转key查询 + if v, ok := querys["configName"]; ok && v != "" { + querys["configName"] = i18n.TFindKeyPrefix(language, "config", v.(string)) + } + + data := s.sysConfigService.SelectConfigPage(querys) + rows := data["rows"].([]model.SysConfig) + + // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysConfig) { for i := range *arr { (*arr)[i].ConfigName = i18n.TKey(language, (*arr)[i].ConfigName) @@ -222,8 +227,10 @@ func (s *SysConfigController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 querys := ctx.BodyJSONMap(c) + querys["pageNum"] = 1 + querys["pageSize"] = 1000 data := s.sysConfigService.SelectConfigPage(querys) - if data["total"].(int64) == 0 { + if parse.Number(data["total"]) == 0 { // 导出数据记录为空 c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return diff --git a/src/modules/system/controller/sys_dept.go b/src/modules/system/controller/sys_dept.go index 6cb582c..4ddfc18 100644 --- a/src/modules/system/controller/sys_dept.go +++ b/src/modules/system/controller/sys_dept.go @@ -35,13 +35,13 @@ func (s *SysDeptController) List(c *gin.Context) { language := ctx.AcceptLanguage(c) var querys struct { // 部门ID - DeptID string `json:"deptId"` + DeptID string `form:"deptId"` // 父部门ID - ParentID string `json:"parentId" ` + ParentID string `form:"parentId" ` // 部门名称 - DeptName string `json:"deptName" ` + DeptName string `form:"deptName" ` // 部门状态(0正常 1停用) - Status string `json:"status"` + Status string `form:"status"` } err := c.ShouldBindQuery(&querys) if err != nil { @@ -49,6 +49,11 @@ func (s *SysDeptController) List(c *gin.Context) { return } + // 多语言值转key查询 + if querys.DeptName != "" { + querys.DeptName = i18n.TFindKeyPrefix(language, "dept", querys.DeptName) + } + SysDeptController := model.SysDept{ DeptID: querys.DeptID, ParentID: querys.ParentID, diff --git a/src/modules/system/controller/sys_dict_data.go b/src/modules/system/controller/sys_dict_data.go index a409a0c..6733988 100644 --- a/src/modules/system/controller/sys_dict_data.go +++ b/src/modules/system/controller/sys_dict_data.go @@ -38,12 +38,17 @@ type SysDictDataController struct { // // GET /list func (s *SysDictDataController) List(c *gin.Context) { - querys := ctx.QueryMap(c) - data := s.sysDictDataService.SelectDictDataPage(querys) - - rows := data["rows"].([]model.SysDictData) - // 闭包函数处理多语言 language := ctx.AcceptLanguage(c) + querys := ctx.QueryMap(c) + // 多语言值转key查询 + if v, ok := querys["dictLabel"]; ok && v != "" { + querys["dictLabel"] = i18n.TFindKeyPrefix(language, "dictData", v.(string)) + } + + data := s.sysDictDataService.SelectDictDataPage(querys) + rows := data["rows"].([]model.SysDictData) + + // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysDictData) { for i := range *arr { if strings.Contains((*arr)[i].DictType, "i18n") { @@ -236,14 +241,21 @@ func (s *SysDictDataController) DictType(c *gin.Context) { func (s *SysDictDataController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) - data := s.sysDictDataService.SelectDictDataPage(querys) - if data["total"].(int64) == 0 { + // querys := ctx.BodyJSONMap(c) + // data := s.sysDictDataService.SelectDictDataPage(querys) + // if data["total"].(int64) == 0 { + // // 导出数据记录为空 + // c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) + // return + // } + // rows := data["rows"].([]model.SysDictData) + + rows := s.sysDictDataService.SelectDictDataList(model.SysDictData{}) + if len(rows) <= 0 { // 导出数据记录为空 c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } - rows := data["rows"].([]model.SysDictData) // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysDictData) { @@ -262,11 +274,10 @@ func (s *SysDictDataController) Export(c *gin.Context) { // 第一行表头标题 headerCells := map[string]string{ "A1": i18n.TKey(language, "dictData.export.code"), - "B1": i18n.TKey(language, "dictData.export.sort"), - "C1": i18n.TKey(language, "dictData.export.label"), - "D1": i18n.TKey(language, "dictData.export.value"), - "E1": i18n.TKey(language, "dictData.export.type"), - "F1": i18n.TKey(language, "dictData.export.status"), + "B1": i18n.TKey(language, "dictData.export.label"), + "C1": i18n.TKey(language, "dictData.export.value"), + "D1": i18n.TKey(language, "dictData.export.sort"), + "E1": i18n.TKey(language, "dictData.export.status"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) @@ -278,11 +289,10 @@ func (s *SysDictDataController) Export(c *gin.Context) { } dataCells = append(dataCells, map[string]any{ "A" + idx: row.DictCode, - "B" + idx: row.DictSort, - "C" + idx: row.DictLabel, - "D" + idx: row.DictValue, - "E" + idx: row.DictType, - "F" + idx: statusValue, + "B" + idx: row.DictLabel, + "C" + idx: row.DictValue, + "D" + idx: row.DictSort, + "E" + idx: statusValue, }) } diff --git a/src/modules/system/controller/sys_dict_type.go b/src/modules/system/controller/sys_dict_type.go index 6a2bdf9..b44807c 100644 --- a/src/modules/system/controller/sys_dict_type.go +++ b/src/modules/system/controller/sys_dict_type.go @@ -36,12 +36,17 @@ type SysDictTypeController struct { // // GET /list func (s *SysDictTypeController) List(c *gin.Context) { - querys := ctx.QueryMap(c) - data := s.sysDictTypeService.SelectDictTypePage(querys) - - rows := data["rows"].([]model.SysDictType) - // 闭包函数处理多语言 language := ctx.AcceptLanguage(c) + querys := ctx.QueryMap(c) + // 多语言值转key查询 + if v, ok := querys["dictName"]; ok && v != "" { + querys["dictName"] = i18n.TFindKeyPrefix(language, "dictType", v.(string)) + } + + data := s.sysDictTypeService.SelectDictTypePage(querys) + rows := data["rows"].([]model.SysDictType) + + // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysDictType) { for i := range *arr { (*arr)[i].DictName = i18n.TKey(language, (*arr)[i].DictName) @@ -239,14 +244,21 @@ func (s *SysDictTypeController) DictOptionselect(c *gin.Context) { func (s *SysDictTypeController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) - data := s.sysDictTypeService.SelectDictTypePage(querys) - if data["total"].(int64) == 0 { + // querys := ctx.BodyJSONMap(c) + // data := s.sysDictTypeService.SelectDictTypePage(querys) + // if data["total"].(int64) == 0 { + // // 导出数据记录为空 + // c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) + // return + // } + // rows := data["rows"].([]model.SysDictType) + + rows := s.sysDictTypeService.SelectDictTypeList(model.SysDictType{}) + if len(rows) <= 0 { // 导出数据记录为空 c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } - rows := data["rows"].([]model.SysDictType) // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysDictType) { diff --git a/src/modules/system/controller/sys_log_login.go b/src/modules/system/controller/sys_log_login.go index 3de3f4d..7a75b49 100644 --- a/src/modules/system/controller/sys_log_login.go +++ b/src/modules/system/controller/sys_log_login.go @@ -60,17 +60,17 @@ func (s *SysLogLoginController) List(c *gin.Context) { // 系统登录日志删除 // -// DELETE /:infoIds +// DELETE /:loginIds func (s *SysLogLoginController) Remove(c *gin.Context) { language := ctx.AcceptLanguage(c) - infoIds := c.Param("infoIds") - if infoIds == "" { + loginIds := c.Param("loginIds") + if loginIds == "" { c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400"))) return } // 处理字符转id数组后去重 - ids := strings.Split(infoIds, ",") + ids := strings.Split(loginIds, ",") uniqueIDs := parse.RemoveDuplicates(ids) if len(uniqueIDs) <= 0 { c.JSON(200, result.Err(nil)) @@ -121,14 +121,21 @@ func (s *SysLogLoginController) Unlock(c *gin.Context) { func (s *SysLogLoginController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) - data := s.sysLogLoginService.SelectSysLogLoginPage(querys) - if data["total"].(int64) == 0 { + // querys := ctx.BodyJSONMap(c) + // data := s.sysLogLoginService.SelectSysLogLoginPage(querys) + // if data["total"].(int64) == 0 { + // // 导出数据记录为空 + // c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) + // return + // } + // rows := data["rows"].([]model.SysLogLogin) + + rows := s.sysLogLoginService.SelectSysLogLoginList(model.SysLogLogin{}) + if len(rows) <= 0 { // 导出数据记录为空 c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } - rows := data["rows"].([]model.SysLogLogin) // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysLogLogin) { @@ -147,13 +154,13 @@ func (s *SysLogLoginController) Export(c *gin.Context) { headerCells := map[string]string{ "A1": i18n.TKey(language, "log.login.export.id"), "B1": i18n.TKey(language, "log.login.export.userName"), - "C1": i18n.TKey(language, "log.login.export.status"), - "D1": i18n.TKey(language, "log.login.export.ip"), - "E1": i18n.TKey(language, "log.login.export.location"), + "C1": i18n.TKey(language, "log.login.export.ip"), + "D1": i18n.TKey(language, "log.login.export.location"), + "E1": i18n.TKey(language, "log.login.export.os"), "F1": i18n.TKey(language, "log.login.export.browser"), - "G1": i18n.TKey(language, "log.login.export.os"), - "H1": i18n.TKey(language, "log.login.export.msg"), - "I1": i18n.TKey(language, "log.login.export.time"), + "G1": i18n.TKey(language, "log.login.export.status"), + "H1": i18n.TKey(language, "log.login.export.time"), + "I1": i18n.TKey(language, "log.login.export.msg"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) @@ -167,13 +174,13 @@ func (s *SysLogLoginController) Export(c *gin.Context) { dataCells = append(dataCells, map[string]any{ "A" + idx: row.LoginID, "B" + idx: row.UserName, - "C" + idx: statusValue, - "D" + idx: row.IPAddr, - "E" + idx: row.LoginLocation, + "C" + idx: row.IPAddr, + "D" + idx: row.LoginLocation, + "E" + idx: row.OS, "F" + idx: row.Browser, - "G" + idx: row.OS, - "H" + idx: row.Msg, - "I" + idx: date.ParseDateToStr(row.LoginTime, date.YYYY_MM_DD_HH_MM_SS), + "G" + idx: statusValue, + "H" + idx: date.ParseDateToStr(row.LoginTime, date.YYYY_MM_DDTHH_MM_SSZ), + "I" + idx: row.Msg, }) } diff --git a/src/modules/system/controller/sys_log_operate.go b/src/modules/system/controller/sys_log_operate.go index 566ecf5..3c542a9 100644 --- a/src/modules/system/controller/sys_log_operate.go +++ b/src/modules/system/controller/sys_log_operate.go @@ -35,12 +35,17 @@ type SysLogOperateController struct { // // GET /list func (s *SysLogOperateController) List(c *gin.Context) { - querys := ctx.QueryMap(c) - data := s.SysLogOperateService.SelectSysLogOperatePage(querys) - - rows := data["rows"].([]model.SysLogOperate) - // 闭包函数处理多语言 language := ctx.AcceptLanguage(c) + querys := ctx.QueryMap(c) + // 多语言值转key查询 + if v, ok := querys["title"]; ok && v != "" { + querys["title"] = i18n.TFindKeyPrefix(language, "log.operate.title", v.(string)) + } + + data := s.SysLogOperateService.SelectSysLogOperatePage(querys) + rows := data["rows"].([]model.SysLogOperate) + + // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysLogOperate) { for i := range *arr { (*arr)[i].Title = i18n.TKey(language, (*arr)[i].Title) @@ -97,14 +102,21 @@ func (s *SysLogOperateController) Clean(c *gin.Context) { func (s *SysLogOperateController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) - data := s.SysLogOperateService.SelectSysLogOperatePage(querys) - if data["total"].(int64) == 0 { + // querys := ctx.BodyJSONMap(c) + // data := s.SysLogOperateService.SelectSysLogOperatePage(querys) + // if data["total"].(int64) == 0 { + // // 导出数据记录为空 + // c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) + // return + // } + // rows := data["rows"].([]model.SysLogOperate) + + rows := s.SysLogOperateService.SelectSysLogOperateList(model.SysLogOperate{}) + if len(rows) <= 0 { // 导出数据记录为空 c.JSON(200, result.ErrMsg(i18n.TKey(language, "app.common.exportEmpty"))) return } - rows := data["rows"].([]model.SysLogOperate) // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysLogOperate) { @@ -122,19 +134,12 @@ func (s *SysLogOperateController) Export(c *gin.Context) { "A1": i18n.TKey(language, "log.operate.export.id"), "B1": i18n.TKey(language, "log.operate.export.title"), "C1": i18n.TKey(language, "log.operate.export.businessType"), - "D1": i18n.TKey(language, "log.operate.export.method"), - "E1": i18n.TKey(language, "log.operate.export.requestMethod"), - "F1": i18n.TKey(language, "log.operate.export.operatorType"), - "G1": i18n.TKey(language, "log.operate.export.operName"), - "H1": i18n.TKey(language, "log.operate.export.deptName"), - "I1": i18n.TKey(language, "log.operate.export.url"), - "J1": i18n.TKey(language, "log.operate.export.ip"), - "K1": i18n.TKey(language, "log.operate.export.location"), - "L1": i18n.TKey(language, "log.operate.export.param"), - "M1": i18n.TKey(language, "log.operate.export.msg"), - "N1": i18n.TKey(language, "log.operate.export.status"), - "O1": i18n.TKey(language, "log.operate.export.costTime"), - "P1": i18n.TKey(language, "log.operate.export.operTime"), + "D1": i18n.TKey(language, "log.operate.export.operName"), + "E1": i18n.TKey(language, "log.operate.export.method"), + "F1": i18n.TKey(language, "log.operate.export.ip"), + "G1": i18n.TKey(language, "log.operate.export.status"), + "H1": i18n.TKey(language, "log.operate.export.operTime"), + "I1": i18n.TKey(language, "log.operate.export.costTime"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) @@ -142,8 +147,36 @@ func (s *SysLogOperateController) Export(c *gin.Context) { idx := strconv.Itoa(i + 2) // 业务类型 businessType := "" - // 操作类别 - operatorType := "" + switch row.BusinessType { + case "0": + // 业务操作类型-其它 + businessType = i18n.TKey(language, "dictData.operType.other") + case "1": + // 业务操作类型-新增 + businessType = i18n.TKey(language, "dictData.operType.add") + case "2": + // 业务操作类型-修改 + businessType = i18n.TKey(language, "dictData.operType.edit") + case "3": + // 业务操作类型-删除 + businessType = i18n.TKey(language, "dictData.operType.delete") + case "4": + // 业务操作类型-授权 + businessType = i18n.TKey(language, "dictData.operType.auth") + case "5": + // 业务操作类型-导出 + businessType = i18n.TKey(language, "dictData.operType.export") + case "6": + // 业务操作类型-导入 + businessType = i18n.TKey(language, "dictData.operType.import") + case "7": + // 业务操作类型-强退 + businessType = i18n.TKey(language, "dictData.operType.forced quit") + case "8": + // 业务操作类型-清空数据 + businessType = i18n.TKey(language, "dictData.operType.clear") + } + // 状态 statusValue := i18n.TKey(language, "dictData.fail") if row.Status == "1" { @@ -153,19 +186,12 @@ func (s *SysLogOperateController) Export(c *gin.Context) { "A" + idx: row.OperID, "B" + idx: row.Title, "C" + idx: businessType, - "D" + idx: row.Method, + "D" + idx: row.OperName, "E" + idx: row.RequestMethod, - "F" + idx: operatorType, - "G" + idx: row.OperName, - "H" + idx: row.DeptName, - "I" + idx: row.OperURL, - "J" + idx: row.OperIP, - "K" + idx: row.OperLocation, - "L" + idx: row.OperParam, - "M" + idx: row.OperMsg, - "N" + idx: statusValue, - "O" + idx: row.CostTime, - "P" + idx: date.ParseDateToStr(row.OperTime, date.YYYY_MM_DD_HH_MM_SS), + "F" + idx: row.OperIP, + "G" + idx: statusValue, + "H" + idx: date.ParseDateToStr(row.OperTime, date.YYYY_MM_DDTHH_MM_SSZ), + "I" + idx: row.CostTime, }) } diff --git a/src/modules/system/controller/sys_menu.go b/src/modules/system/controller/sys_menu.go index d601b29..8454e7d 100644 --- a/src/modules/system/controller/sys_menu.go +++ b/src/modules/system/controller/sys_menu.go @@ -33,9 +33,10 @@ type SysMenuController struct { // // GET /list func (s *SysMenuController) List(c *gin.Context) { + language := ctx.AcceptLanguage(c) query := model.SysMenu{} if v, ok := c.GetQuery("menuName"); ok && v != "" { - query.MenuName = v + query.MenuName = i18n.TFindKeyPrefix(language, "menu", v) } if v, ok := c.GetQuery("status"); ok && v != "" { query.Status = v @@ -48,7 +49,6 @@ func (s *SysMenuController) List(c *gin.Context) { data := s.sysMenuService.SelectMenuList(query, userId) // 闭包函数处理多语言 - language := ctx.AcceptLanguage(c) var converI18n func(language string, arr *[]model.SysMenu) converI18n = func(language string, arr *[]model.SysMenu) { for i := range *arr { diff --git a/src/modules/system/controller/sys_post.go b/src/modules/system/controller/sys_post.go index 53495e9..7d2b658 100644 --- a/src/modules/system/controller/sys_post.go +++ b/src/modules/system/controller/sys_post.go @@ -8,6 +8,7 @@ import ( "be.ems/src/framework/i18n" "be.ems/src/framework/utils/ctx" + "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/file" "be.ems/src/framework/utils/parse" "be.ems/src/framework/vo/result" @@ -35,12 +36,17 @@ type SysPostController struct { // // GET /list func (s *SysPostController) List(c *gin.Context) { - querys := ctx.QueryMap(c) - data := s.sysPostService.SelectPostPage(querys) - - rows := data["rows"].([]model.SysPost) - // 闭包函数处理多语言 language := ctx.AcceptLanguage(c) + querys := ctx.QueryMap(c) + // 多语言值转key查询 + if v, ok := querys["postName"]; ok && v != "" { + querys["postName"] = i18n.TFindKeyPrefix(language, "post", v.(string)) + } + + data := s.sysPostService.SelectPostPage(querys) + rows := data["rows"].([]model.SysPost) + + // 闭包函数处理多语言 converI18n := func(language string, arr *[]model.SysPost) { for i := range *arr { (*arr)[i].PostName = i18n.TKey(language, (*arr)[i].PostName) @@ -204,7 +210,11 @@ func (s *SysPostController) Remove(c *gin.Context) { func (s *SysPostController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) + // querys := ctx.BodyJSONMap(c) + querys := map[string]any{ + "pageNum": 1, + "pageSize": 1000, + } data := s.sysPostService.SelectPostPage(querys) if data["total"].(int64) == 0 { // 导出数据记录为空 @@ -227,10 +237,11 @@ func (s *SysPostController) Export(c *gin.Context) { // 第一行表头标题 headerCells := map[string]string{ "A1": i18n.TKey(language, "post.export.id"), - "B1": i18n.TKey(language, "post.export.code"), - "C1": i18n.TKey(language, "post.export.name"), + "B1": i18n.TKey(language, "post.export.name"), + "C1": i18n.TKey(language, "post.export.code"), "D1": i18n.TKey(language, "post.export.sort"), "E1": i18n.TKey(language, "post.export.status"), + "F1": i18n.TKey(language, "post.export.time"), } // 从第二行开始的数据 dataCells := make([]map[string]any, 0) @@ -242,10 +253,11 @@ func (s *SysPostController) Export(c *gin.Context) { } dataCells = append(dataCells, map[string]any{ "A" + idx: row.PostID, - "B" + idx: row.PostCode, - "C" + idx: row.PostName, + "B" + idx: row.PostName, + "C" + idx: row.PostCode, "D" + idx: row.PostSort, "E" + idx: statusValue, + "F" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DDTHH_MM_SSZ), }) } diff --git a/src/modules/system/controller/sys_role.go b/src/modules/system/controller/sys_role.go index eaa9f0f..be43f91 100644 --- a/src/modules/system/controller/sys_role.go +++ b/src/modules/system/controller/sys_role.go @@ -9,6 +9,7 @@ import ( "be.ems/src/framework/constants/admin" "be.ems/src/framework/i18n" "be.ems/src/framework/utils/ctx" + "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/file" "be.ems/src/framework/utils/parse" "be.ems/src/framework/vo/result" @@ -42,13 +43,18 @@ type SysRoleController struct { // // GET /list func (s *SysRoleController) List(c *gin.Context) { + language := ctx.AcceptLanguage(c) querys := ctx.QueryMap(c) + // 多语言值转key查询 + if v, ok := querys["roleName"]; ok && v != "" { + querys["roleName"] = i18n.TFindKeyPrefix(language, "role", v.(string)) + } + dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") data := s.sysRoleService.SelectRolePage(querys, dataScopeSQL) - rows := data["rows"].([]model.SysRole) + // 闭包函数处理多语言 - language := ctx.AcceptLanguage(c) converI18n := func(language string, arr *[]model.SysRole) { for i := range *arr { (*arr)[i].RoleName = i18n.TKey(language, (*arr)[i].RoleName) @@ -407,7 +413,11 @@ func (s *SysRoleController) AuthUserChecked(c *gin.Context) { func (s *SysRoleController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) + // querys := ctx.BodyJSONMap(c) + querys := map[string]any{ + "pageNum": 1, + "pageSize": 1000, + } dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "") data := s.sysRoleService.SelectRolePage(querys, dataScopeSQL) if data["total"].(int64) == 0 { @@ -434,23 +444,24 @@ func (s *SysRoleController) Export(c *gin.Context) { "B1": i18n.TKey(language, "role.export.name"), "C1": i18n.TKey(language, "role.export.key"), "D1": i18n.TKey(language, "role.export.sort"), - "E1": i18n.TKey(language, "role.export.dataScope"), - "F1": i18n.TKey(language, "role.export.status"), + "E1": i18n.TKey(language, "role.export.status"), + "F1": i18n.TKey(language, "role.export.time"), + // "F1": i18n.TKey(language, "role.export.dataScope"), } // 读取系统角色数据范围字典数据 - dictSysRoleDatascope := s.sysDictDataService.SelectDictDataByType("sys_role_datascope") + // dictSysRoleDatascope := s.sysDictDataService.SelectDictDataByType("sys_role_datascope") // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) // 数据范围 - dataScope := row.DataScope - for _, v := range dictSysRoleDatascope { - if row.DataScope == v.DictValue { - dataScope = i18n.TKey(language, v.DictLabel) - break - } - } + // dataScope := row.DataScope + // for _, v := range dictSysRoleDatascope { + // if row.DataScope == v.DictValue { + // dataScope = i18n.TKey(language, v.DictLabel) + // break + // } + // } // 角色状态 statusValue := i18n.TKey(language, "dictData.disable") if row.Status == "1" { @@ -461,8 +472,9 @@ func (s *SysRoleController) Export(c *gin.Context) { "B" + idx: row.RoleName, "C" + idx: row.RoleKey, "D" + idx: row.RoleSort, - "E" + idx: dataScope, - "F" + idx: statusValue, + "E" + idx: statusValue, + "F" + idx: date.ParseDateToStr(row.CreateTime, date.YYYY_MM_DDTHH_MM_SSZ), + // "F" + idx: dataScope, }) } diff --git a/src/modules/system/controller/sys_user.go b/src/modules/system/controller/sys_user.go index 7730bc9..e5515a1 100644 --- a/src/modules/system/controller/sys_user.go +++ b/src/modules/system/controller/sys_user.go @@ -473,7 +473,11 @@ func (s *SysUserController) Status(c *gin.Context) { func (s *SysUserController) Export(c *gin.Context) { language := ctx.AcceptLanguage(c) // 查询结果,根据查询条件结果,单页最大值限制 - querys := ctx.BodyJSONMap(c) + // querys := ctx.BodyJSONMap(c) + querys := map[string]any{ + "pageNum": 1, + "pageSize": 1000, + } dataScopeSQL := ctx.LoginUserToDataScopeSQL(c, "d", "u") data := s.sysUserService.SelectUserPage(querys, dataScopeSQL) if data["total"].(int64) == 0 { @@ -503,31 +507,31 @@ func (s *SysUserController) Export(c *gin.Context) { "A1": i18n.TKey(language, "user.export.id"), "B1": i18n.TKey(language, "user.export.name"), "C1": i18n.TKey(language, "user.export.nick"), - "D1": i18n.TKey(language, "user.export.email"), - "E1": i18n.TKey(language, "user.export.phone"), - "F1": i18n.TKey(language, "user.export.sex"), - "G1": i18n.TKey(language, "user.export.status"), - "H1": i18n.TKey(language, "user.export.role"), - "I1": i18n.TKey(language, "user.export.deptID"), - "J1": i18n.TKey(language, "user.export.deptName"), - "K1": i18n.TKey(language, "user.export.deptLeader"), - "L1": i18n.TKey(language, "user.export.loginIP"), - "M1": i18n.TKey(language, "user.export.loginDate"), + "D1": i18n.TKey(language, "user.export.role"), + "E1": i18n.TKey(language, "user.export.deptName"), + "F1": i18n.TKey(language, "user.export.loginIP"), + "G1": i18n.TKey(language, "user.export.loginDate"), + "H1": i18n.TKey(language, "user.export.status"), + // "F1": i18n.TKey(language, "user.export.sex"), + // "E1": i18n.TKey(language, "user.export.phone"), + // "D1": i18n.TKey(language, "user.export.email"), + // "I1": i18n.TKey(language, "user.export.deptID"), + // "K1": i18n.TKey(language, "user.export.deptLeader"), } // 读取用户性别字典数据 - dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex") + // dictSysUserSex := s.sysDictDataService.SelectDictDataByType("sys_user_sex") // 从第二行开始的数据 dataCells := make([]map[string]any, 0) for i, row := range rows { idx := strconv.Itoa(i + 2) // 用户性别 - sysUserSex := row.Sex - for _, v := range dictSysUserSex { - if row.Sex == v.DictValue { - sysUserSex = i18n.TKey(language, v.DictLabel) - break - } - } + // sysUserSex := row.Sex + // for _, v := range dictSysUserSex { + // if row.Sex == v.DictValue { + // sysUserSex = i18n.TKey(language, v.DictLabel) + // break + // } + // } // 帐号状态 statusValue := i18n.TKey(language, "dictData.disable") if row.Status == "1" { @@ -536,24 +540,22 @@ func (s *SysUserController) Export(c *gin.Context) { // 用户角色, 默认导出首个 userRole := "" if len(row.Roles) > 0 { - roleID := row.Roles[0].RoleID - roleName := i18n.TKey(language, row.Roles[0].RoleName) - userRole = fmt.Sprintf("%s-%s", roleID, roleName) + userRole = i18n.TKey(language, row.Roles[0].RoleName) } dataCells = append(dataCells, map[string]any{ "A" + idx: row.UserID, "B" + idx: row.UserName, "C" + idx: row.NickName, - "D" + idx: row.Email, - "E" + idx: row.PhoneNumber, - "F" + idx: sysUserSex, - "G" + idx: statusValue, - "H" + idx: userRole, - "I" + idx: row.Dept.DeptID, - "J" + idx: row.Dept.DeptName, - "K" + idx: row.Dept.Leader, - "L" + idx: row.LoginIP, - "M" + idx: date.ParseDateToStr(row.LoginDate, date.YYYY_MM_DD_HH_MM_SS), + "D" + idx: userRole, + "E" + idx: row.Dept.DeptName, + "F" + idx: row.LoginIP, + "G" + idx: date.ParseDateToStr(row.LoginDate, date.YYYY_MM_DD_HH_MM_SS), + "H" + idx: statusValue, + // "E" + idx: row.PhoneNumber, + // "F" + idx: sysUserSex, + // "D" + idx: row.Email, + // "I" + idx: row.Dept.DeptID, + // "K" + idx: row.Dept.Leader, }) } diff --git a/src/modules/system/repository/sys_config.impl.go b/src/modules/system/repository/sys_config.impl.go index 9e499ca..4b32377 100644 --- a/src/modules/system/repository/sys_config.impl.go +++ b/src/modules/system/repository/sys_config.impl.go @@ -7,7 +7,6 @@ import ( "be.ems/src/framework/datasource" "be.ems/src/framework/logger" - "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/repo" "be.ems/src/modules/system/model" @@ -79,8 +78,7 @@ func (r *SysConfigImpl) SelectConfigPage(query map[string]any) map[string]any { } if ok && beginTime != "" { conditions = append(conditions, "create_time >= ?") - beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD) - params = append(params, beginDate.UnixMilli()) + params = append(params, parse.Number(beginTime.(string))) } endTime, ok := query["endTime"] if !ok { @@ -88,8 +86,7 @@ func (r *SysConfigImpl) SelectConfigPage(query map[string]any) map[string]any { } if ok && endTime != "" { conditions = append(conditions, "create_time <= ?") - endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD) - params = append(params, endDate.UnixMilli()) + params = append(params, parse.Number(endTime.(string))) } // 构建查询条件语句 diff --git a/src/modules/system/repository/sys_dict_data.impl.go b/src/modules/system/repository/sys_dict_data.impl.go index 2a4331a..3782a14 100644 --- a/src/modules/system/repository/sys_dict_data.impl.go +++ b/src/modules/system/repository/sys_dict_data.impl.go @@ -69,7 +69,7 @@ func (r *SysDictDataImpl) SelectDictDataPage(query map[string]any) map[string]an } if v, ok := query["dictLabel"]; ok && v != "" { conditions = append(conditions, "dict_label like concat(?, '%')") - params = append(params, v) + params = append(params, strings.TrimSpace(v.(string))) } if v, ok := query["status"]; ok && v != "" { conditions = append(conditions, "status = ?") diff --git a/src/modules/system/repository/sys_dict_type.impl.go b/src/modules/system/repository/sys_dict_type.impl.go index db59146..1da0112 100644 --- a/src/modules/system/repository/sys_dict_type.impl.go +++ b/src/modules/system/repository/sys_dict_type.impl.go @@ -7,7 +7,6 @@ import ( "be.ems/src/framework/datasource" "be.ems/src/framework/logger" - "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/repo" "be.ems/src/modules/system/model" @@ -62,11 +61,11 @@ func (r *SysDictTypeImpl) SelectDictTypePage(query map[string]any) map[string]an var params []any if v, ok := query["dictName"]; ok && v != "" { conditions = append(conditions, "dict_name like concat(?, '%')") - params = append(params, v) + params = append(params, strings.TrimSpace(v.(string))) } if v, ok := query["dictType"]; ok && v != "" { conditions = append(conditions, "dict_type like concat(?, '%')") - params = append(params, v) + params = append(params, strings.TrimSpace(v.(string))) } if v, ok := query["status"]; ok && v != "" { conditions = append(conditions, "status = ?") @@ -78,8 +77,7 @@ func (r *SysDictTypeImpl) SelectDictTypePage(query map[string]any) map[string]an } if ok && beginTime != "" { conditions = append(conditions, "create_time >= ?") - beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD) - params = append(params, beginDate.UnixMilli()) + params = append(params, parse.Number(beginTime.(string))) } endTime, ok := query["endTime"] if !ok { @@ -87,8 +85,7 @@ func (r *SysDictTypeImpl) SelectDictTypePage(query map[string]any) map[string]an } if ok && endTime != "" { conditions = append(conditions, "create_time <= ?") - endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD) - params = append(params, endDate.UnixMilli()) + params = append(params, parse.Number(endTime.(string))) } // 构建查询条件语句 diff --git a/src/modules/system/repository/sys_log_login.impl.go b/src/modules/system/repository/sys_log_login.impl.go index 9a71977..178a745 100644 --- a/src/modules/system/repository/sys_log_login.impl.go +++ b/src/modules/system/repository/sys_log_login.impl.go @@ -6,7 +6,6 @@ import ( "be.ems/src/framework/datasource" "be.ems/src/framework/logger" - "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/repo" "be.ems/src/modules/system/model" @@ -76,8 +75,7 @@ func (r *SysLogLoginImpl) SelectSysLogLoginPage(query map[string]any) map[string } if ok && beginTime != "" { conditions = append(conditions, "login_time >= ?") - beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD_HH_MM_SS) - params = append(params, beginDate.UnixMilli()) + params = append(params, parse.Number(beginTime.(string))) } endTime, ok := query["endTime"] if !ok { @@ -85,8 +83,7 @@ func (r *SysLogLoginImpl) SelectSysLogLoginPage(query map[string]any) map[string } if ok && endTime != "" { conditions = append(conditions, "login_time <= ?") - endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD_HH_MM_SS) - params = append(params, endDate.UnixMilli()) + params = append(params, parse.Number(endTime.(string))) } // 构建查询条件语句 diff --git a/src/modules/system/repository/sys_log_operate.impl.go b/src/modules/system/repository/sys_log_operate.impl.go index 18f5cb4..649c312 100644 --- a/src/modules/system/repository/sys_log_operate.impl.go +++ b/src/modules/system/repository/sys_log_operate.impl.go @@ -6,7 +6,6 @@ import ( "be.ems/src/framework/datasource" "be.ems/src/framework/logger" - "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/repo" "be.ems/src/modules/system/model" @@ -69,7 +68,7 @@ func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[st var params []any if v, ok := query["title"]; ok && v != "" { conditions = append(conditions, "title like concat(?, '%')") - params = append(params, v) + params = append(params, strings.TrimSpace(v.(string))) } if v, ok := query["businessType"]; ok && v != "" { conditions = append(conditions, "business_type = ?") @@ -77,7 +76,7 @@ func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[st } if v, ok := query["operName"]; ok && v != "" { conditions = append(conditions, "oper_name like concat(?, '%')") - params = append(params, v) + params = append(params, strings.TrimSpace(v.(string))) } if v, ok := query["status"]; ok && v != "" { conditions = append(conditions, "status = ?") @@ -89,8 +88,7 @@ func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[st } if ok && beginTime != "" { conditions = append(conditions, "oper_time >= ?") - beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD_HH_MM_SS) - params = append(params, beginDate.UnixMilli()) + params = append(params, parse.Number(beginTime.(string))) } endTime, ok := query["endTime"] if !ok { @@ -98,8 +96,7 @@ func (r *SysLogOperateImpl) SelectSysLogOperatePage(query map[string]any) map[st } if ok && endTime != "" { conditions = append(conditions, "oper_time <= ?") - endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD_HH_MM_SS) - params = append(params, endDate.UnixMilli()) + params = append(params, parse.Number(endTime.(string))) } // 构建查询条件语句 diff --git a/src/modules/system/repository/sys_role.impl.go b/src/modules/system/repository/sys_role.impl.go index 10e5532..8fe89fa 100644 --- a/src/modules/system/repository/sys_role.impl.go +++ b/src/modules/system/repository/sys_role.impl.go @@ -7,7 +7,6 @@ import ( "be.ems/src/framework/datasource" "be.ems/src/framework/logger" - "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/repo" "be.ems/src/modules/system/model" @@ -91,8 +90,7 @@ func (r *SysRoleImpl) SelectRolePage(query map[string]any, dataScopeSQL string) } if ok && beginTime != "" { conditions = append(conditions, "r.create_time >= ?") - beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD) - params = append(params, beginDate.UnixMilli()) + params = append(params, parse.Number(beginTime.(string))) } endTime, ok := query["endTime"] if !ok { @@ -100,8 +98,7 @@ func (r *SysRoleImpl) SelectRolePage(query map[string]any, dataScopeSQL string) } if ok && endTime != "" { conditions = append(conditions, "r.create_time <= ?") - endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD) - params = append(params, endDate.UnixMilli()) + params = append(params, parse.Number(endTime.(string))) } if v, ok := query["deptId"]; ok && v != "" { conditions = append(conditions, `(u.dept_id = ? or u.dept_id in ( @@ -112,7 +109,7 @@ func (r *SysRoleImpl) SelectRolePage(query map[string]any, dataScopeSQL string) } // 构建查询条件语句 - whereSql := " where r.del_flag = '0' " + whereSql := " where r.del_flag = '0' and r.role_id != '1' " if len(conditions) > 0 { whereSql += " and " + strings.Join(conditions, " and ") } diff --git a/src/modules/system/repository/sys_user.impl.go b/src/modules/system/repository/sys_user.impl.go index 89209e3..bbcbe84 100644 --- a/src/modules/system/repository/sys_user.impl.go +++ b/src/modules/system/repository/sys_user.impl.go @@ -8,7 +8,6 @@ import ( "be.ems/src/framework/datasource" "be.ems/src/framework/logger" "be.ems/src/framework/utils/crypto" - "be.ems/src/framework/utils/date" "be.ems/src/framework/utils/parse" "be.ems/src/framework/utils/repo" "be.ems/src/modules/system/model" @@ -156,8 +155,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string) } if ok && beginTime != "" { conditions = append(conditions, "u.login_date >= ?") - beginDate := date.ParseStrToDate(beginTime.(string), date.YYYY_MM_DD) - params = append(params, beginDate.UnixMilli()) + params = append(params, parse.Number(beginTime.(string))) } endTime, ok := query["endTime"] if !ok { @@ -165,8 +163,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string) } if ok && endTime != "" { conditions = append(conditions, "u.login_date <= ?") - endDate := date.ParseStrToDate(endTime.(string), date.YYYY_MM_DD) - params = append(params, endDate.UnixMilli()) + params = append(params, parse.Number(endTime.(string))) } if v, ok := query["deptId"]; ok && v != "" { conditions = append(conditions, "(u.dept_id = ? or u.dept_id in ( select t.dept_id from sys_dept t where find_in_set(?, ancestors) ))") @@ -175,7 +172,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string) } // 构建查询条件语句 - whereSql := " where u.del_flag = '0' " + whereSql := " where u.del_flag = '0' and u.user_id != '1' " if len(conditions) > 0 { whereSql += " and " + strings.Join(conditions, " and ") } @@ -515,7 +512,8 @@ func (r *SysUserImpl) UpdateUser(sysUser model.SysUser) int64 { // DeleteUserByIds 批量删除用户信息 func (r *SysUserImpl) DeleteUserByIds(userIds []string) int64 { placeholder := repo.KeyPlaceholderByQuery(len(userIds)) - sql := "update sys_user set del_flag = '1' where user_id in (" + placeholder + ")" + username := "CASE WHEN user_name = '' THEN user_name WHEN LENGTH(user_name) >= 36 THEN CONCAT('del_', SUBSTRING(user_name, 5, 36)) ELSE CONCAT('del_', user_name) END" + sql := fmt.Sprintf("update sys_user set del_flag = '1', user_name = %s where user_id in (%s)", username, placeholder) parameters := repo.ConvertIdsSlice(userIds) results, err := datasource.ExecDB("", sql, parameters) if err != nil { diff --git a/src/modules/system/service/sys_user.impl.go b/src/modules/system/service/sys_user.impl.go index d188627..8f1baf2 100644 --- a/src/modules/system/service/sys_user.impl.go +++ b/src/modules/system/service/sys_user.impl.go @@ -32,7 +32,7 @@ func (r *SysUserImpl) SelectUserPage(query map[string]any, dataScopeSQL string) // SelectUserList 根据条件查询用户列表 func (r *SysUserImpl) SelectUserList(sysUser model.SysUser, dataScopeSQL string) []model.SysUser { - return []model.SysUser{} + return r.sysUserRepository.SelectUserList(sysUser, dataScopeSQL) } // SelectAllocatedPage 根据条件分页查询分配用户角色列表 diff --git a/src/modules/trace/service/tcpdump.impl.go b/src/modules/trace/service/tcpdump.impl.go index 938fd74..5fb1c2e 100644 --- a/src/modules/trace/service/tcpdump.impl.go +++ b/src/modules/trace/service/tcpdump.impl.go @@ -143,7 +143,8 @@ func (s *TcpdumpImpl) DumpUPF(neType, neId, cmdStr string) (string, string, erro timeStr := date.ParseDateToStr(time.Now(), date.YYYYMMDDHHMMSS) fileName := fmt.Sprintf("%s_%s", timeStr, neTypeID) // UPF标准版本telnet脚本 - scriptStr := "set pcapCmd [lindex $argv 0]\nspawn telnet localhost 5002\nexpect \"upfd1# \"\nsend \"$pcapCmd\\n\"\nexpect \"upfd1# \"\nsend \"quit\\n\"\nexpect \"eof\"" + scriptStr := "set pcapCmd [lindex $argv 0]\nspawn telnet " + neInfo.IP + " 5002\nexpect \"upfd1# \"\nsend \"$pcapCmd\\n\"\nexpect \"upfd1# \"\nsend \"quit\\n\"\nexpect \"eof\"" + // scriptStr := "set pcapCmd [lindex $argv 0]\nspawn telnet localhost 5002\nexpect \"upfd1# \"\nsend \"$pcapCmd\\n\"\nexpect \"upfd1# \"\nsend \"quit\\n\"\nexpect \"eof\"" writePcapFile := fmt.Sprintf("echo '%s' > pcapUPF.sh\n %s chmod +x pcapUPF.sh", scriptStr, withSudo) writeLogFile := fmt.Sprintf("> %s.log 2>&1 \ncat %s.log", fileName, fileName) diff --git a/src/modules/ws/controller/ws.go b/src/modules/ws/controller/ws.go index b9051c4..50fd01f 100644 --- a/src/modules/ws/controller/ws.go +++ b/src/modules/ws/controller/ws.go @@ -196,11 +196,11 @@ func (s *WSController) SSH(c *gin.Context) { wsClient.MsgChan <- msgByte // 退出ssh登录 - if strings.LastIndex(outputStr, "logout\r\n") != -1 { - time.Sleep(1 * time.Second) - s.wsService.CloseClient(wsClient.ID) - return - } + // if strings.LastIndex(outputStr, "logout\r\n") != -1 { + // time.Sleep(1 * time.Second) + // s.wsService.CloseClient(wsClient.ID) + // return + // } } } }() @@ -283,11 +283,11 @@ func (s *WSController) Telnet(c *gin.Context) { wsClient.MsgChan <- msgByte // 退出telnet登录 - if strings.LastIndex(outputStr, "logout\r\n") != -1 { - time.Sleep(1 * time.Second) - s.wsService.CloseClient(wsClient.ID) - return - } + // if strings.LastIndex(outputStr, "logout\r\n") != -1 { + // time.Sleep(1 * time.Second) + // s.wsService.CloseClient(wsClient.ID) + // return + // } } } }() diff --git a/src/modules/ws/service/ws_receive.impl.go b/src/modules/ws/service/ws_receive.impl.go index 00648e2..3df4930 100644 --- a/src/modules/ws/service/ws_receive.impl.go +++ b/src/modules/ws/service/ws_receive.impl.go @@ -3,6 +3,7 @@ package service import ( "encoding/json" "fmt" + "io" "time" "be.ems/src/framework/logger" @@ -83,6 +84,11 @@ func (s *WSReceiveImpl) AsyncReceive(client *model.WSClient, reqMsg model.WSRequ logger.Warnf("ws AsyncReceive UID %s err: %s", client.BindUid, err.Error()) msgByte, _ := json.Marshal(result.ErrMsg(err.Error())) client.MsgChan <- msgByte + if err == io.EOF { + // 等待1s后关闭连接 + time.Sleep(1 * time.Second) + client.StopChan <- struct{}{} + } return } if len(resByte) > 0 {