feat: 网元软件包信息

This commit is contained in:
TsMask
2024-04-01 16:57:15 +08:00
parent a8280476d0
commit 715cf8ab18
6 changed files with 142 additions and 106 deletions

View File

@@ -49,7 +49,7 @@ func (s *NeSoftwareController) Info(c *gin.Context) {
neSoftware := s.neSoftwareService.SelectById(softwareId) neSoftware := s.neSoftwareService.SelectById(softwareId)
if neSoftware.ID != softwareId { if neSoftware.ID != softwareId {
// 没有可访问网元版本数据! // 没有可访问网元包信息数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData"))) c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData")))
return return
} }
@@ -64,20 +64,21 @@ func (s *NeSoftwareController) Add(c *gin.Context) {
language := ctx.AcceptLanguage(c) language := ctx.AcceptLanguage(c)
var body model.NeSoftware var body model.NeSoftware
err := c.ShouldBindBodyWith(&body, binding.JSON) 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"))) c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return return
} }
// 检查属性值唯一 // 检查属性值唯一
uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndFileNameAndVersion(body.NeType, body.FileName, body.Version, "") uniqueSoftware := s.neSoftwareService.CheckUniqueTypeAndNameAndVersion(body.NeType, body.Name, body.Version, "")
if !uniqueSoftware { if !uniqueSoftware {
// 网元软件包操作【%s】失败网元类型与文件名版本已存在 // 网元软件包操作【%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)) c.JSON(200, result.ErrMsg(msg))
return return
} }
body.CreateBy = ctx.LoginUserToUserName(c)
insertId := s.neSoftwareService.Insert(body) insertId := s.neSoftwareService.Insert(body)
if insertId != "" { if insertId != "" {
c.JSON(200, result.Ok(nil)) c.JSON(200, result.Ok(nil))
@@ -93,16 +94,16 @@ func (s *NeSoftwareController) Edit(c *gin.Context) {
language := ctx.AcceptLanguage(c) language := ctx.AcceptLanguage(c)
var body model.NeSoftware var body model.NeSoftware
err := c.ShouldBindBodyWith(&body, binding.JSON) 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"))) c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return 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 { if !uniqueSoftware {
// 网元软件包操作【%s】失败网元类型与文件名版本已存在 // 网元软件包操作【%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)) c.JSON(200, result.ErrMsg(msg))
return return
} }
@@ -110,11 +111,12 @@ func (s *NeSoftwareController) Edit(c *gin.Context) {
// 检查是否存在 // 检查是否存在
neSoftware := s.neSoftwareService.SelectById(body.ID) neSoftware := s.neSoftwareService.SelectById(body.ID)
if neSoftware.ID != body.ID { if neSoftware.ID != body.ID {
// 没有可访问网元版本数据! // 没有可访问网元包信息数据!
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData"))) c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData")))
return return
} }
body.UpdateBy = ctx.LoginUserToUserName(c)
rows := s.neSoftwareService.Update(body) rows := s.neSoftwareService.Update(body)
if rows > 0 { if rows > 0 {
c.JSON(200, result.Ok(nil)) c.JSON(200, result.Ok(nil))
@@ -149,32 +151,40 @@ func (s *NeSoftwareController) Remove(c *gin.Context) {
c.JSON(200, result.OkMsg(msg)) c.JSON(200, result.OkMsg(msg))
} }
// 网元软件包安装 // 网元软件包安装检查
// //
// POST /install // POST /checkInstall
func (s *NeSoftwareController) Install(c *gin.Context) { func (s *NeSoftwareController) CheckInstall(c *gin.Context) {
language := ctx.AcceptLanguage(c) language := ctx.AcceptLanguage(c)
var body model.NeSoftware var body model.NeSoftware
err := c.ShouldBindBodyWith(&body, binding.JSON) 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"))) c.JSON(400, result.CodeMsg(400, i18n.TKey(language, "app.common.err400")))
return return
} }
// 检查是否存在 // 检查是否存在软件包记录
neSoftwares := s.neSoftwareService.SelectList(body) neSoftwares := s.neSoftwareService.SelectList(model.NeSoftware{
if len(neSoftwares) == 0 { NeType: body.NeType,
// 没有可访问网元版本数据! Name: body.Name,
c.JSON(200, result.ErrMsg(i18n.TKey(language, "neSoftware.noData"))) Version: body.Version,
return })
} if len(neSoftwares) <= 0 {
body.CreateBy = ctx.LoginUserToUserName(c)
body.ID = s.neSoftwareService.Insert(body)
} else {
neSoftware := neSoftwares[0] neSoftware := neSoftwares[0]
neSoftware.Path = body.Path
neSoftware.Description = body.Description
neSoftware.UpdateBy = ctx.LoginUserToUserName(c)
s.neSoftwareService.Update(neSoftware)
}
// 进行安装 // 进行安装检查
output, err := s.neSoftwareService.Install(neSoftware) cmdStrArr, err := s.neSoftwareService.UploadToNeHost(body)
if err != nil { if err != nil {
c.JSON(200, result.OkData(output)) c.JSON(200, result.ErrMsg(err.Error()))
return return
} }
c.JSON(200, result.Err(nil)) c.JSON(200, result.OkData(cmdStrArr))
} }

View File

@@ -1,18 +1,21 @@
package model package model
import "time"
// NeSoftware 网元软件包 ne_software // NeSoftware 网元软件包 ne_software
type NeSoftware struct { type NeSoftware struct {
ID string `json:"id" gorm:"id"` ID string `json:"id" gorm:"id"`
NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型 NeType string `json:"neType" gorm:"ne_type" binding:"required"` // 网元类型
FileName string `json:"fileName" gorm:"file_name" binding:"required"` // 包名称 Name string `json:"name" gorm:"name" binding:"required"` // 包名称
Path string `json:"path" gorm:"path"` // 包路径 Path string `json:"path" gorm:"path"` // 包路径
Version string `json:"version" gorm:"version" binding:"required"` // 包版本 Version string `json:"version" gorm:"version" binding:"required"` // 包版本
Md5Sum string `json:"md5Sum" gorm:"md5_sum"` // --无使用 md5签名 Description string `json:"description" gorm:"description"` // 包说明
Status string `json:"status" gorm:"status"` // --无使用 CreateBy string `json:"createBy" gorm:"column:create_by"` // 创建者
Comment string `json:"comment" gorm:"comment"` // 包说明 CreateTime int64 `json:"createTime" gorm:"column:create_time"` // 创建时间
UpdateTime time.Time `json:"updateTime" gorm:"update_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 表名称 // TableName 表名称

View File

@@ -22,6 +22,6 @@ type INeSoftware interface {
// DeleteByIds 批量删除信息 // DeleteByIds 批量删除信息
DeleteByIds(ids []string) int64 DeleteByIds(ids []string) int64
// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一 // CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一
CheckUniqueTypeAndFileNameAndVersion(neSoftware model.NeSoftware) string CheckUniqueTypeAndNameAndVersion(neSoftware model.NeSoftware) string
} }

View File

@@ -15,18 +15,19 @@ import (
// 实例化数据层 NewNeSoftware 结构体 // 实例化数据层 NewNeSoftware 结构体
var NewNeSoftwareImpl = &NeSoftwareImpl{ var NewNeSoftwareImpl = &NeSoftwareImpl{
selectSql: `select 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`, from ne_software`,
resultMap: map[string]string{ resultMap: map[string]string{
"id": "ID", "id": "ID",
"ne_type": "NeType", "ne_type": "NeType",
"file_name": "FileName", "name": "Name",
"path": "Path", "path": "Path",
"version": "Version", "version": "Version",
"md5_sum": "Md5Sum", "description": "Description",
"status": "Status", "create_by": "CreateBy",
"comment": "Comment", "create_time": "CreateTime",
"update_by": "UpdateBy",
"update_time": "UpdateTime", "update_time": "UpdateTime",
}, },
} }
@@ -63,8 +64,8 @@ func (r *NeSoftwareImpl) SelectPage(query map[string]any) map[string]any {
conditions = append(conditions, "ne_type = ?") conditions = append(conditions, "ne_type = ?")
params = append(params, strings.Trim(v.(string), " ")) params = append(params, strings.Trim(v.(string), " "))
} }
if v, ok := query["fileName"]; ok && v != "" { if v, ok := query["name"]; ok && v != "" {
conditions = append(conditions, "file_name like concat(?, '%')") conditions = append(conditions, "name like concat(?, '%')")
params = append(params, strings.Trim(v.(string), " ")) params = append(params, strings.Trim(v.(string), " "))
} }
if v, ok := query["version"]; ok && v != "" { if v, ok := query["version"]; ok && v != "" {
@@ -133,9 +134,9 @@ func (r *NeSoftwareImpl) SelectList(neSoftware model.NeSoftware) []model.NeSoftw
conditions = append(conditions, "version = ?") conditions = append(conditions, "version = ?")
params = append(params, neSoftware.Version) params = append(params, neSoftware.Version)
} }
if neSoftware.FileName != "" { if neSoftware.Name != "" {
conditions = append(conditions, "file_name like concat(?, '%')") conditions = append(conditions, "name like concat(?, '%')")
params = append(params, neSoftware.FileName) params = append(params, neSoftware.Name)
} }
// 构建查询条件语句 // 构建查询条件语句
@@ -169,8 +170,8 @@ func (r *NeSoftwareImpl) SelectByIds(cmdIds []string) []model.NeSoftware {
return r.convertResultRows(results) return r.convertResultRows(results)
} }
// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一 // CheckUniqueTypeAndNameAndVersion 校验网元类型和文件名版本是否唯一
func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neSoftware model.NeSoftware) string { func (r *NeSoftwareImpl) CheckUniqueTypeAndNameAndVersion(neSoftware model.NeSoftware) string {
// 查询条件拼接 // 查询条件拼接
var conditions []string var conditions []string
var params []any var params []any
@@ -182,9 +183,9 @@ func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neSoftware model.N
conditions = append(conditions, "version = ?") conditions = append(conditions, "version = ?")
params = append(params, neSoftware.Version) params = append(params, neSoftware.Version)
} }
if neSoftware.FileName != "" { if neSoftware.Name != "" {
conditions = append(conditions, "file_name = ?") conditions = append(conditions, "name = ?")
params = append(params, neSoftware.FileName) params = append(params, neSoftware.Name)
} }
// 构建查询条件语句 // 构建查询条件语句
@@ -215,8 +216,8 @@ func (r *NeSoftwareImpl) Insert(neSoftware model.NeSoftware) string {
if neSoftware.NeType != "" { if neSoftware.NeType != "" {
params["ne_type"] = neSoftware.NeType params["ne_type"] = neSoftware.NeType
} }
if neSoftware.FileName != "" { if neSoftware.Name != "" {
params["file_name"] = neSoftware.FileName params["name"] = neSoftware.Name
} }
if neSoftware.Path != "" { if neSoftware.Path != "" {
params["path"] = neSoftware.Path params["path"] = neSoftware.Path
@@ -224,19 +225,11 @@ func (r *NeSoftwareImpl) Insert(neSoftware model.NeSoftware) string {
if neSoftware.Version != "" { if neSoftware.Version != "" {
params["version"] = neSoftware.Version params["version"] = neSoftware.Version
} }
if neSoftware.Md5Sum != "" { params["description"] = neSoftware.Description
params["md5_sum"] = neSoftware.Md5Sum 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) keys, placeholder, values := repo.KeyPlaceholderValueByInsert(params)
@@ -272,8 +265,8 @@ func (r *NeSoftwareImpl) Update(neSoftware model.NeSoftware) int64 {
if neSoftware.NeType != "" { if neSoftware.NeType != "" {
params["ne_type"] = neSoftware.NeType params["ne_type"] = neSoftware.NeType
} }
if neSoftware.FileName != "" { if neSoftware.Name != "" {
params["file_name"] = neSoftware.FileName params["name"] = neSoftware.Name
} }
if neSoftware.Path != "" { if neSoftware.Path != "" {
params["path"] = neSoftware.Path params["path"] = neSoftware.Path
@@ -281,19 +274,11 @@ func (r *NeSoftwareImpl) Update(neSoftware model.NeSoftware) int64 {
if neSoftware.Version != "" { if neSoftware.Version != "" {
params["version"] = neSoftware.Version params["version"] = neSoftware.Version
} }
if neSoftware.Md5Sum != "" { params["description"] = neSoftware.Description
params["md5_sum"] = neSoftware.Md5Sum 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) keys, values := repo.KeyValueByUpdate(params)

View File

@@ -22,12 +22,10 @@ type INeSoftware interface {
// DeleteByIds 批量删除信息 // DeleteByIds 批量删除信息
DeleteByIds(ids []string) (int64, error) DeleteByIds(ids []string) (int64, error)
// SelectByVersionAndPath 通过文件版本和路径查询 // CheckUniqueTypeAndNameAndVersion 校验网元类型和文件版本是否唯一
SelectByVersionAndPath(version, path string) model.NeSoftware CheckUniqueTypeAndNameAndVersion(neType, name, version, id string) bool
// CheckUniqueTypeAndFileNameAndVersion 校验网元类型和文件名版本是否唯一 // UploadToNeHost 安装包上传到网元主机
CheckUniqueTypeAndFileNameAndVersion(neType, fileName, version, id string) bool // 返回执行命令步骤
UploadToNeHost(neSoftware model.NeSoftware) ([]string, error)
// Install 安装软件包
Install(neSoftware model.NeSoftware) (string, error)
} }

View File

@@ -2,7 +2,12 @@ package service
import ( import (
"fmt" "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/model"
"be.ems/src/modules/network_element/repository" "be.ems/src/modules/network_element/repository"
) )
@@ -66,23 +71,11 @@ func (r *NeSoftwareImpl) DeleteByIds(ids []string) (int64, error) {
return 0, fmt.Errorf("delete fail") return 0, fmt.Errorf("delete fail")
} }
// SelectByVersionAndPath 通过文件版本和路径查询 // CheckUniqueTypeAndNameAndVersion 校验网元类型和文件版本是否唯一
func (r *NeSoftwareImpl) SelectByVersionAndPath(version, path string) model.NeSoftware { func (r *NeSoftwareImpl) CheckUniqueTypeAndNameAndVersion(neType, name, version, id string) bool {
neSoftwares := r.neSoftwareRepository.SelectList(model.NeSoftware{ uniqueId := r.neSoftwareRepository.CheckUniqueTypeAndNameAndVersion(model.NeSoftware{
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, NeType: neType,
FileName: fileName, Name: name,
Version: version, Version: version,
}) })
if uniqueId == id { if uniqueId == id {
@@ -91,7 +84,54 @@ func (r *NeSoftwareImpl) CheckUniqueTypeAndFileNameAndVersion(neType, fileName,
return uniqueId == "" return uniqueId == ""
} }
// Install 安装软件包 // UploadToNeHost 安装包上传到网元主机
func (r *NeSoftwareImpl) Install(neSoftware model.NeSoftware) (string, error) { // 返回执行命令步骤
return "", nil 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
} }