package udmuser import ( "fmt" "net/http" "strconv" "strings" "time" "ems.agt/features/udm_user/model" "ems.agt/features/udm_user/service" "ems.agt/lib/core/conf" mmlclient "ems.agt/lib/core/mml_client" "ems.agt/lib/core/utils/ctx" "ems.agt/lib/core/vo/result" "ems.agt/lib/dborm" "ems.agt/lib/log" "ems.agt/lib/midware" "ems.agt/lib/services" "ems.agt/restagent/config" "ems.agt/src/framework/middleware/collectlogs" "ems.agt/src/framework/utils/file" "ems.agt/src/framework/utils/ssh" ) // UDM 用户信息接口添加到路由 func Routers() []services.RouterItem { // 实例化控制层 SysDictTypeApi 结构体 var apis = &UdmUserApi{ authUser: *service.NewServiceUdmAuthUser, subUser: *service.NewServiceUdmSubUser, } rs := [...]services.RouterItem{ // UDM鉴权用户 { Method: "GET", Pattern: "/auths", Handler: apis.UdmAuthUserList, Middleware: midware.Authorize(nil), }, { Method: "POST", Pattern: "/authSave/{neId}", Handler: apis.UdmAuthUserSave, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM Authentication User", collectlogs.BUSINESS_TYPE_INSERT)), }, { Method: "GET", Pattern: "/auth/{neId}/{imsi}", Handler: apis.UdmAuthUserInfo, Middleware: midware.Authorize(nil), }, { Method: "POST", Pattern: "/auth/{neId}", Handler: apis.UdmAuthUserAdd, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM Authentication User", collectlogs.BUSINESS_TYPE_INSERT)), }, { Method: "POST", Pattern: "/auth/{neId}/{num}", Handler: apis.UdmAuthUserAdds, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM Authentication User", collectlogs.BUSINESS_TYPE_INSERT)), }, { Method: "PUT", Pattern: "/auth/{neId}", Handler: apis.UdmAuthUserEdit, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM Authentication User", collectlogs.BUSINESS_TYPE_UPDATE)), }, { Method: "DELETE", Pattern: "/auth/{neId}/{imsi}", Handler: apis.UdmAuthUserRemove, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM Authentication User", collectlogs.BUSINESS_TYPE_DELETE)), }, { Method: "DELETE", Pattern: "/auth/{neId}/{imsi}/{num}", Handler: apis.UdmAuthUserRemoves, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM Authentication User", collectlogs.BUSINESS_TYPE_DELETE)), }, { Method: "POST", Pattern: "/authExport", Handler: apis.UdmAuthUserExport, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM Authentication User", collectlogs.BUSINESS_TYPE_EXPORT)), }, { Method: "POST", Pattern: "/authImport/{neId}", Handler: apis.UdmAuthUserImport, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM Authentication User", collectlogs.BUSINESS_TYPE_IMPORT)), }, // UDM签约用户 { Method: "GET", Pattern: "/subs", Handler: apis.UdmSubUserList, Middleware: midware.Authorize(nil), }, { Method: "POST", Pattern: "/subSave/{neId}", Handler: apis.UdmSubUserSave, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_INSERT)), }, { Method: "GET", Pattern: "/subInfo/{neId}/{imsi}", Handler: apis.UdmSubUserInfo, Middleware: midware.Authorize(nil), }, { Method: "POST", Pattern: "/sub/{neId}", Handler: apis.UdmSubUserAdd, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_INSERT)), }, { Method: "POST", Pattern: "/sub/{neId}/{num}", Handler: apis.UdmSubUserAdds, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_INSERT)), }, { Method: "PUT", Pattern: "/sub/{neId}", Handler: apis.UdmSubUserEdit, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_UPDATE)), }, { Method: "PUT", Pattern: "/sub4gIP/{neId}", Handler: apis.UdmSubUser4GIP, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_UPDATE)), }, { Method: "PUT", Pattern: "/subSmData/{neId}", Handler: apis.UdmSubUserSmData, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_UPDATE)), }, { Method: "DELETE", Pattern: "/sub/{neId}/{imsi}", Handler: apis.UdmSubUserRemove, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_DELETE)), }, { Method: "DELETE", Pattern: "/sub/{neId}/{imsi}/{num}", Handler: apis.UdmSubUserRemoves, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_DELETE)), }, { Method: "POST", Pattern: "/subExport", Handler: apis.UdmSubUserExport, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_EXPORT)), }, { Method: "POST", Pattern: "/subImport/{neId}", Handler: apis.UdmSubUserImport, Middleware: midware.LogOperate(collectlogs.OptionNew("UDM contracted users", collectlogs.BUSINESS_TYPE_IMPORT)), }, // 添加更多的 Router 对象... } // 生成两组前缀路由 rsPrefix := []services.RouterItem{} for _, v := range rs { path := "/udmUserManage/{apiVersion}" + v.Pattern // 固定前缀 v.Pattern = config.DefaultUriPrefix + path rsPrefix = append(rsPrefix, v) // 可配置 v.Pattern = config.UriPrefix + path rsPrefix = append(rsPrefix, v) } return rsPrefix } // NeInfoByUDM 网元信息 func NeInfoByUDM(neId string) (*dborm.NeInfo, error) { neInfo, err := dborm.XormGetNeInfo("UDM", neId) if err != nil { log.Error("dborm.XormGetNeInfo is failed:", err) return nil, err } if neInfo == nil || neInfo.Ip == "" { return nil, fmt.Errorf("not ne_info or not IP") } return neInfo, nil } // UDM 用户 // // PATH /udmUserManage type UdmUserApi struct { authUser service.ServiceUdmAuthUser subUser service.ServiceUdmSubUser } // UDM鉴权用户 // // GET /auths func (s *UdmUserApi) UdmAuthUserList(w http.ResponseWriter, r *http.Request) { querys := ctx.QueryMap(r) querys["neId"] = "" data := s.authUser.Page(querys) ctx.JSON(w, 200, result.Ok(data)) } // UDM鉴权用户-获取全部保存数据库 // // POST /authSave/{neId} func (s *UdmUserApi) UdmAuthUserSave(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neId = "" data := s.authUser.Save(neId) ctx.JSON(w, 200, result.OkData(data)) } // UDM鉴权用户-信息 // // GET /authInfo/{neId}/{imsi} func (s *UdmUserApi) UdmAuthUserInfo(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") imsi := ctx.Param(r, "imsi") if neId == "" || imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("dsp authdat:imsi=%s", imsi) // 发送MML data, err := mmlclient.MMLSendMsgToMap(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } neId = "" var userInfo model.UdmAuthUser list := s.authUser.List(model.UdmAuthUser{NeID: neId, Imsi: imsi}) if len(list) > 0 { userInfo = list[0] } else { userInfo = model.UdmAuthUser{ Imsi: imsi, Amf: data["amf"], AlgoIndex: data["algo"], Opc: data["opc"], Ki: data["ki"], } s.authUser.Insert(neId, userInfo) } ctx.JSON(w, 200, result.OkData(userInfo)) } // UDM鉴权用户-增加 // // POST /{neId} func (s *UdmUserApi) UdmAuthUserAdd(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmAuthUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("add authdat:imsi=%s,ki=%s,amf=%s,algo=%s,opc=%s", body.Imsi, body.Ki, body.Amf, body.AlgoIndex, body.Opc) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.authUser.Insert(neId, body) } ctx.JSON(w, 200, result.OkData(data)) } // UDM鉴权用户-批量添加 // // POST /{neId}/{num} func (s *UdmUserApi) UdmAuthUserAdds(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") num := ctx.Param(r, "num") if neId == "" || num == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmAuthUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("bad authdat:start_imsi=%s,sub_num=%s,ki=%s,amf=%s,algo=%s", body.Imsi, num, body.Ki, body.Amf, body.AlgoIndex) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.authUser.Inserts(neId, body, num) } ctx.JSON(w, 200, result.OkData(data)) } // UDM鉴权用户-修改 // // PUT /{neId} func (s *UdmUserApi) UdmAuthUserEdit(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmAuthUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("mod authdata:imsi=%s", body.Imsi) // 修改的参数名称 if body.Ki != "" { msg += fmt.Sprintf(",ki=%s", body.Ki) } if body.Amf != "" { msg += fmt.Sprintf(",amf=%s", body.Amf) } if body.AlgoIndex != "" { msg += fmt.Sprintf(",algo=%s", body.AlgoIndex) } if body.Opc != "" { msg += fmt.Sprintf(",opc=%s", body.Opc) } // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.authUser.Update(neId, body) } ctx.JSON(w, 200, result.OkData(data)) } // UDM鉴权用户-删除 // // DELETE /{neId}/{imsi} func (s *UdmUserApi) UdmAuthUserRemove(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") imsi := ctx.Param(r, "imsi") if neId == "" || imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("del authdat:imsi=%s", imsi) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.authUser.Delete(neId, imsi) } ctx.JSON(w, 200, result.OkData(data)) } // UDM鉴权用户-批量删除 // // DELETE /{neId}/{imsi}/{num} func (s *UdmUserApi) UdmAuthUserRemoves(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") imsi := ctx.Param(r, "imsi") num := ctx.Param(r, "num") if neId == "" || imsi == "" || num == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("bde authdat:start_imsi=%s,sub_num=%s", imsi, num) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.authUser.Deletes(neId, imsi, num) } ctx.JSON(w, 200, result.OkData(data)) } // UDM鉴权用户-导出 // // POST /authExport func (s *UdmUserApi) UdmAuthUserExport(w http.ResponseWriter, r *http.Request) { var body struct { NeId string `json:"neId"` Type string `json:"type"` } err := ctx.ShouldBindJSON(r, &body) if err != nil || body.NeId == "" || body.Type == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } if !(body.Type == "csv" || body.Type == "txt") { ctx.JSON(w, 200, result.ErrMsg("Export file types support CSV and txt")) return } neId := "" list := s.authUser.List(model.UdmAuthUser{NeID: neId}) // 文件名 fileName := fmt.Sprintf("OMC_AUTH_USER_EXPORT_%s_%d.%s", neId, time.Now().UnixMilli(), body.Type) filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName) if body.Type == "csv" { // 转换数据 data := [][]string{} data = append(data, []string{"imsi", "ki", "amf", "algo", "opc"}) for _, v := range list { data = append(data, []string{v.Imsi, v.Ki, v.Amf, v.AlgoIndex, v.Opc}) } // 输出到文件 err := file.WriterCSVFile(data, filePath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } } if body.Type == "txt" { // 转换数据 data := [][]string{} for _, v := range list { data = append(data, []string{v.Imsi, v.Ki, v.Amf, v.AlgoIndex, v.Opc}) } // 输出到文件 err = file.WriterTxtFile(data, filePath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } } ctx.FileAttachment(w, r, filePath, fileName) } // UDM鉴权用户-导入 // // POST /authImport/{neId} func (s *UdmUserApi) UdmAuthUserImport(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } // 获取文件名 _, fileHeader, err := r.FormFile("file") if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } if !(strings.HasSuffix(fileHeader.Filename, ".csv") || strings.HasSuffix(fileHeader.Filename, ".txt")) { ctx.JSON(w, 200, result.ErrMsg("Please upload files in. csv and. txt formats with content fields: imsi,ki,algo,amf,opc")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 文件名 fileName := fmt.Sprintf("OMC_AUTH_USER_IMPORT_%s_%d_%s", neId, time.Now().UnixMilli(), fileHeader.Filename) localPath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName) nePath := conf.Get("mml.upload").(string) // 输出保存文件 err = ctx.SaveUploadedFile(r, localPath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 复制到远程 err = ssh.FileSCPLocalToNe(neInfo.Ip, localPath, nePath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("import authdat:path=%s", fmt.Sprintf("%s/%s", nePath, fileName)) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { if strings.HasSuffix(fileHeader.Filename, ".csv") { data := file.ReadCSVFile(localPath) neId = "" go s.authUser.InsertCSV(neId, data) } if strings.HasSuffix(fileHeader.Filename, ".txt") { data := file.ReadTxtFile(localPath) neId = "" go s.authUser.InsertTxt(neId, data) } } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户 // // GET /subs func (s *UdmUserApi) UdmSubUserList(w http.ResponseWriter, r *http.Request) { querys := ctx.QueryMap(r) querys["neId"] = "" data := s.subUser.Page(querys) ctx.JSON(w, 200, result.Ok(data)) } // UDM签约用户-获取全部保存数据库 // // POST /subSave/{neId} func (s *UdmUserApi) UdmSubUserSave(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neId = "" data := s.subUser.Save(neId) ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-信息 // // GET /subInfo/{neId}/{imsi} func (s *UdmUserApi) UdmSubUserInfo(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") imsi := ctx.Param(r, "imsi") if neId == "" || imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("dsp udmuser:imsi=%s", imsi) // 发送MML data, err := mmlclient.MMLSendMsgToMap(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } neId = "" var userInfo model.UdmSubUser list := s.subUser.List(model.UdmSubUser{NeID: neId, Imsi: imsi}) if len(list) > 0 { userInfo = list[0] } else { cnType, _ := strconv.ParseInt(data["CNType"][:4], 0, 64) rat, _ := strconv.ParseInt(data["RAT"][:4], 0, 64) userInfo = model.UdmSubUser{ Imsi: imsi, Msisdn: data["MSISDN"], Ambr: data["AMBR"], Arfb: data["AreaForbidden"], Cn: fmt.Sprint(cnType), SmData: data["SM-Data(snssai+dnn[1..n])"], Sar: data["ServiceAreaRestriction"], Nssai: data["NSSAI"], SmfSel: data["Smf-Selection"], Rat: fmt.Sprint(rat), } // 1,64,24,65,def_eps,1,2,010200000000,- if v, ok := data["EPS-Data"]; ok { userInfo.EpsDat = v arr := strings.Split(v, ",") userInfo.EpsFlag = arr[0] userInfo.EpsOdb = arr[1] userInfo.HplmnOdb = arr[2] userInfo.Ard = arr[3] userInfo.Epstpl = arr[4] userInfo.ContextId = arr[5] userInfo.ApnContext = arr[7] userInfo.StaticIp = arr[8] } s.subUser.Insert(neId, userInfo) } ctx.JSON(w, 200, result.OkData(userInfo)) } // UDM签约用户-增加 // // POST /{neId} func (s *UdmUserApi) UdmSubUserAdd(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmSubUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("add udmuser:imsi=%s,msisdn=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s", body.Imsi, body.Msisdn, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext) // static_ip指给4G UE分配的静态IP,没有可不带此字段名,批量添加IP会自动递增 if body.StaticIp != "" { msg += fmt.Sprintf(",static_ip=%s", body.StaticIp) } // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.subUser.Insert(neId, body) } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-批量添加 // // POST /{neId}/{num} func (s *UdmUserApi) UdmSubUserAdds(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") num := ctx.Param(r, "num") if neId == "" || num == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmSubUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("bad udmuser:start_imsi=%s,start_msisdn=%s,sub_num=%s,ambr=%s,nssai=%s,arfb=%s,sar=%s,rat=%s,cn=%s,smf_sel=%s,sm_data=%s,eps_flag=%s,eps_odb=%s,hplmn_odb=%s,ard=%s,epstpl=%s,context_id=%s,apn_context=%s", body.Imsi, body.Msisdn, num, body.Ambr, body.Nssai, body.Arfb, body.Sar, body.Rat, body.Cn, body.SmfSel, body.SmData, body.EpsFlag, body.EpsOdb, body.HplmnOdb, body.Ard, body.Epstpl, body.ContextId, body.ApnContext) // static_ip指给4G UE分配的静态IP,没有可不带此字段名,批量添加IP会自动递增 if body.StaticIp != "" { msg += fmt.Sprintf(",static_ip=%s", body.StaticIp) } // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.subUser.Inserts(neId, body, num) } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-批量添加4G用户 // // POST /sub4G/{neId} func (s *UdmUserApi) UdmSubUserAdd4G(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmSubUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" || body.SubNum == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("bmd udmuser:start_imsi=%s,sub_num=%s,eps_flag=%s", body.Imsi, body.SubNum, body.EpsFlag) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.subUser.Insert4G(neId, body) } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-修改 // // PUT /{neId} func (s *UdmUserApi) UdmSubUserEdit(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmSubUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("mod udmuser:imsi=%s", body.Imsi) // 修改的参数名称 if body.Msisdn != "" { msg += fmt.Sprintf(",msisdn=%s", body.Msisdn) } if body.Ambr != "" { msg += fmt.Sprintf(",ambr=%s", body.Ambr) } if body.Nssai != "" { msg += fmt.Sprintf(",nssai=%s", body.Nssai) } if body.Arfb != "" { msg += fmt.Sprintf(",arfb=%s", body.Arfb) } if body.Sar != "" { msg += fmt.Sprintf(",sar=%s", body.Sar) } if body.Rat != "" { msg += fmt.Sprintf(",rat=%s", body.Rat) } if body.Cn != "" { msg += fmt.Sprintf(",cn=%s", body.Cn) } if body.SmfSel != "" { msg += fmt.Sprintf(",smf_sel=%s", body.SmfSel) } if body.SmData != "" { msg += fmt.Sprintf(",sm_data=%s", body.SmData) } if body.EpsDat != "" { msg += fmt.Sprintf(",eps_dat=%s", body.EpsDat) } if body.EpsFlag != "" { msg += fmt.Sprintf(",eps_flag=%s", body.EpsFlag) } if body.EpsOdb != "" { msg += fmt.Sprintf(",eps_odb=%s", body.EpsOdb) } if body.HplmnOdb != "" { msg += fmt.Sprintf(",hplmn_odb=%s", body.HplmnOdb) } if body.Epstpl != "" { msg += fmt.Sprintf(",epstpl=%s", body.Epstpl) } if body.Ard != "" { msg += fmt.Sprintf(",ard=%s", body.Ard) } if body.ContextId != "" { msg += fmt.Sprintf(",context_id=%s", body.ContextId) } if body.ApnContext != "" { msg += fmt.Sprintf(",apn_context=%s", body.ApnContext) } if body.StaticIp != "" { msg += fmt.Sprintf(",static_ip=%s", body.StaticIp) } // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.subUser.Update(neId, body) } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-批量修改4G IP // // PUT /sub4gIP/{neId} func (s *UdmUserApi) UdmSubUser4GIP(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmSubUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" || body.SubNum == "" || body.StaticIp == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("bmd udmuser:start_imsi=%s,sub_num=%s,static_ip=%s", body.Imsi, body.SubNum, body.StaticIp) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.subUser.Update4GIP(neId, body) } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-批量修改sm-data // // PUT /subSmData/{neId} func (s *UdmUserApi) UdmSubUserSmData(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } var body model.UdmSubUser err := ctx.ShouldBindJSON(r, &body) if err != nil || body.Imsi == "" || body.SubNum == "" || body.SmData == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 3-000003&internet-10.10.1.1&ims-10.11.1.1 msg := fmt.Sprintf("bmd udmuser:start_imsi=%s,sub_num=%s,sm_data=%s", body.Imsi, body.SubNum, body.SmData) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.subUser.UpdateSmData(neId, body) } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-删除 // // DELETE /{neId}/{imsi} func (s *UdmUserApi) UdmSubUserRemove(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") imsi := ctx.Param(r, "imsi") if neId == "" || imsi == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("del udmuser:imsi=%s", imsi) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.subUser.Delete(neId, imsi) } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-批量删除 // // DELETE /{neId}/{imsi}/{num} func (s *UdmUserApi) UdmSubUserRemoves(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") imsi := ctx.Param(r, "imsi") num := ctx.Param(r, "num") if neId == "" || imsi == "" || num == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("bde udmuser:start_imsi=%s,sub_num=%s", imsi, num) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { neId = "" s.subUser.Deletes(neId, imsi, num) } ctx.JSON(w, 200, result.OkData(data)) } // UDM签约用户-导出 // // POST /subExport func (s *UdmUserApi) UdmSubUserExport(w http.ResponseWriter, r *http.Request) { var body struct { NeId string `json:"neId"` Type string `json:"type"` } err := ctx.ShouldBindJSON(r, &body) if err != nil || body.NeId == "" || body.Type == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } if !(body.Type == "csv" || body.Type == "txt") { ctx.JSON(w, 200, result.ErrMsg("Export file type support csv、txt")) return } neId := "" list := s.subUser.List(model.UdmSubUser{NeID: neId}) // 文件名 fileName := fmt.Sprintf("OMC_AUTH_USER_EXPORT_%s_%d.%s", neId, time.Now().UnixMilli(), body.Type) filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName) if body.Type == "csv" { // 转换数据 data := [][]string{} data = append(data, []string{"imsi", "msisdn", "ambr", "arfb", "sar", "rat", "cn", "smf_sel", "sm_dat", "eps_dat"}) for _, v := range list { data = append(data, []string{v.Imsi, v.Msisdn, v.Ambr, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, v.EpsDat}) } // 输出到文件 err = file.WriterCSVFile(data, filePath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } } if body.Type == "txt" { // 转换数据 data := [][]string{} for _, v := range list { data = append(data, []string{v.Imsi, v.Msisdn, v.Ambr, v.Arfb, v.Sar, v.Rat, v.Cn, v.SmfSel, v.SmData, v.EpsDat}) } // 输出到文件 err = file.WriterTxtFile(data, filePath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } } ctx.FileAttachment(w, r, filePath, fileName) } // UDM签约用户-导入 // // POST /subImport/{neId} func (s *UdmUserApi) UdmSubUserImport(w http.ResponseWriter, r *http.Request) { neId := ctx.Param(r, "neId") if neId == "" { ctx.JSON(w, 400, result.CodeMsg(400, "parameter error")) return } // 获取文件名 _, fileHeader, err := r.FormFile("file") if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } if !(strings.HasSuffix(fileHeader.Filename, ".csv") || strings.HasSuffix(fileHeader.Filename, ".txt")) { ctx.JSON(w, 200, result.ErrMsg("Please upload files in. csv and. txt formats with content fields: imsi,msisdn,ambr,nssai,arfb,sar,rat,cn,smf_sel,sm_dat,eps_dat")) return } neInfo, err := NeInfoByUDM(neId) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 文件名 fileName := fmt.Sprintf("OMC_SUB_USER_IMPORT_%s_%d_%s", neId, time.Now().UnixMilli(), fileHeader.Filename) localPath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName) nePath := conf.Get("mml.upload").(string) // 输出保存文件 err = ctx.SaveUploadedFile(r, localPath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 复制到远程 err = ssh.FileSCPLocalToNe(neInfo.Ip, localPath, nePath) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } msg := fmt.Sprintf("import udmuser:path=%s", fmt.Sprintf("%s/%s", nePath, fileName)) // 发送MML data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg) if err != nil { ctx.JSON(w, 200, result.ErrMsg(err.Error())) return } // 命令ok时 if strings.Contains(data, "ok") { if strings.HasSuffix(fileHeader.Filename, ".csv") { data := file.ReadCSVFile(localPath) neId = "" go s.subUser.InsertCSV(neId, data) } if strings.HasSuffix(fileHeader.Filename, ".txt") { data := file.ReadTxtFile(localPath) neId = "" go s.subUser.InsertTxt(neId, data) } } ctx.JSON(w, 200, result.OkData(data)) }