From a8280476d0a493888a72ddfed4ba03ee70b59928 Mon Sep 17 00:00:00 2001 From: TsMask <340112800@qq.com> Date: Mon, 1 Apr 2024 16:55:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E7=BD=91=E5=85=83=E6=8E=88=E6=9D=83?= =?UTF-8?q?=E6=BF=80=E6=B4=BB=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../network_element/controller/ne_license.go | 301 ++++++++++++++++ .../network_element/model/ne_license.go | 28 ++ .../network_element/repository/ne_license.go | 27 ++ .../repository/ne_license.impl.go | 333 ++++++++++++++++++ .../network_element/service/ne_license.go | 37 ++ .../service/ne_license.impl.go | 183 ++++++++++ 6 files changed, 909 insertions(+) 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/src/modules/network_element/controller/ne_license.go b/src/modules/network_element/controller/ne_license.go new file mode 100644 index 00000000..7022df85 --- /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/model/ne_license.go b/src/modules/network_element/model/ne_license.go new file mode 100644 index 00000000..2f202bc6 --- /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/repository/ne_license.go b/src/modules/network_element/repository/ne_license.go new file mode 100644 index 00000000..c185d67e --- /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 00000000..fcbb1f0d --- /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/service/ne_license.go b/src/modules/network_element/service/ne_license.go new file mode 100644 index 00000000..c5ea23a1 --- /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 00000000..d41b1918 --- /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 +}