Merge branch 'main' of http://192.168.0.229:3180/OMC/ems_backend
This commit is contained in:
88
features/firewall/api_firewall.go
Normal file
88
features/firewall/api_firewall.go
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
package firewall
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"ems.agt/features/firewall/model"
|
||||||
|
"ems.agt/features/firewall/service"
|
||||||
|
"ems.agt/lib/core/utils/ctx"
|
||||||
|
"ems.agt/lib/core/vo/result"
|
||||||
|
"ems.agt/lib/services"
|
||||||
|
"ems.agt/restagent/config"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 防火墙管理接口添加到路由
|
||||||
|
func Routers() []services.RouterItem {
|
||||||
|
// 实例化控制层 FirewallApi 结构体
|
||||||
|
var apis = &FirewallApi{
|
||||||
|
firewallService: *service.NewServiceFirewall,
|
||||||
|
}
|
||||||
|
|
||||||
|
rs := [...]services.RouterItem{
|
||||||
|
{
|
||||||
|
Method: "GET",
|
||||||
|
Pattern: "/base",
|
||||||
|
Handler: apis.BaseInfo,
|
||||||
|
Middleware: nil, //midware.Authorize(nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Method: "POST",
|
||||||
|
Pattern: "/rule",
|
||||||
|
Handler: apis.Rule,
|
||||||
|
Middleware: nil, //midware.Authorize(nil),
|
||||||
|
},
|
||||||
|
// 添加更多的 Router 对象...
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成两组前缀路由
|
||||||
|
rsPrefix := []services.RouterItem{}
|
||||||
|
for _, v := range rs {
|
||||||
|
path := "/firewallManage/{apiVersion}" + v.Pattern
|
||||||
|
// 固定前缀
|
||||||
|
v.Pattern = config.DefaultUriPrefix + path
|
||||||
|
rsPrefix = append(rsPrefix, v)
|
||||||
|
// 可配置
|
||||||
|
v.Pattern = config.UriPrefix + path
|
||||||
|
rsPrefix = append(rsPrefix, v)
|
||||||
|
}
|
||||||
|
return rsPrefix
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防火墙管理
|
||||||
|
//
|
||||||
|
// PATH /firewallManage
|
||||||
|
type FirewallApi struct {
|
||||||
|
firewallService service.ServiceFirewall
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取防火墙基础信息
|
||||||
|
//
|
||||||
|
// GET /base
|
||||||
|
func (s *FirewallApi) BaseInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
data, err := s.firewallService.LoadBaseInfo()
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取防火墙规则列表分页
|
||||||
|
//
|
||||||
|
// GET /rule
|
||||||
|
func (s *FirewallApi) Rule(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var body model.RuleQuerys
|
||||||
|
err := ctx.ShouldBindJSON(r, &body)
|
||||||
|
if err != nil || body.Type == "" {
|
||||||
|
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
data, err := s.firewallService.RulePage(body)
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(w, 400, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
|
}
|
||||||
13
features/firewall/model/firewall.go
Normal file
13
features/firewall/model/firewall.go
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type Firewall struct {
|
||||||
|
ID int64 `json:"id" xorm:"id"`
|
||||||
|
CreatedAt int64 `json:"createdAt" xorm:"created_at"`
|
||||||
|
UpdatedAt int64 `json:"updatedAt" xorm:"updated_at"`
|
||||||
|
Type string `json:"type" xorm:"type"`
|
||||||
|
Port string `json:"port" xorm:"port"`
|
||||||
|
Protocol string `json:"protocol" xorm:"protocol"`
|
||||||
|
Address string `json:"address" xorm:"address"`
|
||||||
|
Strategy string `json:"strategy" xorm:"strategy"`
|
||||||
|
Description string `json:"description" xorm:"description"`
|
||||||
|
}
|
||||||
64
features/firewall/model/firewall_vo.go
Normal file
64
features/firewall/model/firewall_vo.go
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
type FirewallBaseInfo struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Version string `json:"version"`
|
||||||
|
PingStatus string `json:"pingStatus"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RuleQuerys struct {
|
||||||
|
PageNum int `json:"pageNum" validate:"required,number"`
|
||||||
|
PageSize int `json:"pageSize" validate:"required,number"`
|
||||||
|
Info string `json:"info"`
|
||||||
|
Status string `json:"status"`
|
||||||
|
Strategy string `json:"strategy"`
|
||||||
|
Type string `json:"type" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FirewallOperation struct {
|
||||||
|
Operation string `json:"operation" validate:"required,oneof=start stop disablePing enablePing"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PortRuleOperate struct {
|
||||||
|
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Port string `json:"port" validate:"required"`
|
||||||
|
Protocol string `json:"protocol" validate:"required,oneof=tcp udp tcp/udp"`
|
||||||
|
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||||
|
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateFirewallDescription struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Port string `json:"port"`
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||||
|
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddrRuleOperate struct {
|
||||||
|
Operation string `json:"operation" validate:"required,oneof=add remove"`
|
||||||
|
Address string `json:"address" validate:"required"`
|
||||||
|
Strategy string `json:"strategy" validate:"required,oneof=accept drop"`
|
||||||
|
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type PortRuleUpdate struct {
|
||||||
|
OldRule PortRuleOperate `json:"oldRule"`
|
||||||
|
NewRule PortRuleOperate `json:"newRule"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type AddrRuleUpdate struct {
|
||||||
|
OldRule AddrRuleOperate `json:"oldRule"`
|
||||||
|
NewRule AddrRuleOperate `json:"newRule"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BatchRuleOperate struct {
|
||||||
|
Type string `json:"type" validate:"required"`
|
||||||
|
Rules []PortRuleOperate `json:"rules"`
|
||||||
|
}
|
||||||
133
features/firewall/repo/repo_firewall.go
Normal file
133
features/firewall/repo/repo_firewall.go
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
package repo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ems.agt/features/firewall/model"
|
||||||
|
"ems.agt/lib/core/datasource"
|
||||||
|
"ems.agt/lib/log"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化数据层 RepoFirewall 结构体
|
||||||
|
var NewRepoFirewall = &RepoFirewall{
|
||||||
|
selectSql: `select
|
||||||
|
id, created_at, updated_at, type, port, protocol, address, strategy, description
|
||||||
|
from monitor_firewall`,
|
||||||
|
|
||||||
|
resultMap: map[string]string{
|
||||||
|
"id": "ID",
|
||||||
|
"created_at": "CreatedAt",
|
||||||
|
"updated_at": "UpdatedAt",
|
||||||
|
"type": "Type",
|
||||||
|
"port": "Port",
|
||||||
|
"protocol": "Protocol",
|
||||||
|
"address": "Address",
|
||||||
|
"strategy": "Strategy",
|
||||||
|
"description": "Description",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// RepoFirewall 防火墙 数据层处理
|
||||||
|
type RepoFirewall struct {
|
||||||
|
// 查询视图对象SQL
|
||||||
|
selectSql string
|
||||||
|
// 结果字段与实体映射
|
||||||
|
resultMap map[string]string
|
||||||
|
}
|
||||||
|
|
||||||
|
// convertResultRows 将结果记录转实体结果组
|
||||||
|
func (r *RepoFirewall) convertResultRows(rows []map[string]any) []model.Firewall {
|
||||||
|
arr := make([]model.Firewall, 0)
|
||||||
|
for _, row := range rows {
|
||||||
|
UdmUser := model.Firewall{}
|
||||||
|
for key, value := range row {
|
||||||
|
if keyMapper, ok := r.resultMap[key]; ok {
|
||||||
|
datasource.SetFieldValue(&UdmUser, keyMapper, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
arr = append(arr, UdmUser)
|
||||||
|
}
|
||||||
|
return arr
|
||||||
|
}
|
||||||
|
|
||||||
|
// List 根据实体查询
|
||||||
|
func (r *RepoFirewall) List(f model.Firewall) []model.Firewall {
|
||||||
|
// 查询条件拼接
|
||||||
|
var conditions []string
|
||||||
|
var params []any
|
||||||
|
if f.Type != "" {
|
||||||
|
conditions = append(conditions, "type = ?")
|
||||||
|
params = append(params, f.Type)
|
||||||
|
}
|
||||||
|
if f.Protocol != "" {
|
||||||
|
conditions = append(conditions, "protocol = ?")
|
||||||
|
params = append(params, f.Protocol)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建查询条件语句
|
||||||
|
whereSql := ""
|
||||||
|
if len(conditions) > 0 {
|
||||||
|
whereSql += " where " + strings.Join(conditions, " and ")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询数据
|
||||||
|
querySql := r.selectSql + whereSql
|
||||||
|
results, err := datasource.RawDB("", querySql, params)
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("query err => %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换实体
|
||||||
|
return r.convertResultRows(results)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Insert 新增实体
|
||||||
|
func (r *RepoFirewall) Insert(f model.Firewall) int64 {
|
||||||
|
results, err := datasource.DefaultDB().Table("monitor_firewall").Insert(f)
|
||||||
|
if err != nil {
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update 修改更新
|
||||||
|
func (r *RepoFirewall) Update(f model.Firewall) int64 {
|
||||||
|
// 查询先
|
||||||
|
var fd model.Firewall
|
||||||
|
if f.Type == "port" {
|
||||||
|
has, err := datasource.DefaultDB().Table("monitor_firewall").Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", "port", f.Port, f.Protocol, f.Address, f.Strategy).Get(&fd)
|
||||||
|
if !has || err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
has, err := datasource.DefaultDB().Table("monitor_firewall").Where("type = ? AND address = ? AND strategy = ?", "address", f.Address, f.Strategy).Get(&fd)
|
||||||
|
if !has || err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f.ID = fd.ID
|
||||||
|
|
||||||
|
results, err := datasource.DefaultDB().Table("monitor_firewall").Where("id = ?", f.ID).Update(f)
|
||||||
|
if err != nil {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete 删除实体
|
||||||
|
func (r *RepoFirewall) Delete(id int64) int64 {
|
||||||
|
results, err := datasource.DefaultDB().Table("u_sub_user").Where("id = ?", id).Delete()
|
||||||
|
if err != nil {
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
|
||||||
|
// DeleteFirewallRecord 删除实体
|
||||||
|
func (r *RepoFirewall) DeleteFirewallRecord(fType, port, protocol, address, strategy string) int64 {
|
||||||
|
results, err := datasource.DefaultDB().Table("u_sub_user").Where("type = ? AND port = ? AND protocol = ? AND address = ? AND strategy = ?", fType, port, protocol, address, strategy).Delete()
|
||||||
|
if err != nil {
|
||||||
|
return results
|
||||||
|
}
|
||||||
|
return results
|
||||||
|
}
|
||||||
207
features/firewall/service/service_firewall.go
Normal file
207
features/firewall/service/service_firewall.go
Normal file
@@ -0,0 +1,207 @@
|
|||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ems.agt/features/firewall/model"
|
||||||
|
"ems.agt/features/firewall/repo"
|
||||||
|
"ems.agt/lib/core/cmd"
|
||||||
|
"ems.agt/lib/core/utils/firewall"
|
||||||
|
fireClient "ems.agt/lib/core/utils/firewall/client"
|
||||||
|
"ems.agt/lib/core/utils/scan"
|
||||||
|
)
|
||||||
|
|
||||||
|
// 实例化服务层 ServiceFirewall 结构体
|
||||||
|
var NewServiceFirewall = &ServiceFirewall{
|
||||||
|
repoFirewall: *repo.NewRepoFirewall,
|
||||||
|
}
|
||||||
|
|
||||||
|
// ServiceFirewall 防火墙 服务层处理
|
||||||
|
type ServiceFirewall struct {
|
||||||
|
repoFirewall repo.RepoFirewall
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadBaseInfo 获取防火墙基础信息
|
||||||
|
func (s *ServiceFirewall) LoadBaseInfo() (model.FirewallBaseInfo, error) {
|
||||||
|
var baseInfo model.FirewallBaseInfo
|
||||||
|
baseInfo.PingStatus = s.pingStatus()
|
||||||
|
baseInfo.Status = "not running"
|
||||||
|
baseInfo.Version = "-"
|
||||||
|
baseInfo.Name = "-"
|
||||||
|
client, err := firewall.NewFirewallClient()
|
||||||
|
if err != nil {
|
||||||
|
if err.Error() == "no such type" {
|
||||||
|
return baseInfo, nil
|
||||||
|
}
|
||||||
|
return baseInfo, err
|
||||||
|
}
|
||||||
|
baseInfo.Name = client.Name()
|
||||||
|
baseInfo.Status, err = client.Status()
|
||||||
|
if err != nil {
|
||||||
|
return baseInfo, err
|
||||||
|
}
|
||||||
|
if baseInfo.Status == "not running" {
|
||||||
|
return baseInfo, err
|
||||||
|
}
|
||||||
|
baseInfo.Version, err = client.Version()
|
||||||
|
if err != nil {
|
||||||
|
return baseInfo, err
|
||||||
|
}
|
||||||
|
return baseInfo, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// LoadBaseInfo 获取防火墙基础信息
|
||||||
|
func (s *ServiceFirewall) RulePage(querys model.RuleQuerys) (map[string]any, error) {
|
||||||
|
var (
|
||||||
|
datas []fireClient.FireInfo
|
||||||
|
backDatas []fireClient.FireInfo
|
||||||
|
)
|
||||||
|
|
||||||
|
data := map[string]any{
|
||||||
|
"total": 0,
|
||||||
|
"rows": backDatas,
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := firewall.NewFirewallClient()
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
if querys.Type == "port" {
|
||||||
|
ports, err := client.ListPort()
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
if len(querys.Info) != 0 {
|
||||||
|
for _, port := range ports {
|
||||||
|
if strings.Contains(port.Port, querys.Info) {
|
||||||
|
datas = append(datas, port)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
datas = ports
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
addrs, err := client.ListAddress()
|
||||||
|
if err != nil {
|
||||||
|
return data, err
|
||||||
|
}
|
||||||
|
if len(querys.Info) != 0 {
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if strings.Contains(addr.Address, querys.Info) {
|
||||||
|
datas = append(datas, addr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
datas = addrs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var datasFilterStatus []fireClient.FireInfo
|
||||||
|
if len(querys.Status) != 0 {
|
||||||
|
for _, data := range datas {
|
||||||
|
portItem, _ := strconv.Atoi(data.Port)
|
||||||
|
if querys.Status == "free" && !scan.ScanPortWithProto(portItem, data.Protocol) {
|
||||||
|
datasFilterStatus = append(datasFilterStatus, data)
|
||||||
|
}
|
||||||
|
if querys.Status == "used" && scan.ScanPortWithProto(portItem, data.Protocol) {
|
||||||
|
datasFilterStatus = append(datasFilterStatus, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
datasFilterStatus = datas
|
||||||
|
}
|
||||||
|
var datasFilterStrategy []fireClient.FireInfo
|
||||||
|
if len(querys.Strategy) != 0 {
|
||||||
|
for _, data := range datasFilterStatus {
|
||||||
|
if querys.Strategy == data.Strategy {
|
||||||
|
datasFilterStrategy = append(datasFilterStrategy, data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
datasFilterStrategy = datasFilterStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
total, start, end := len(datasFilterStrategy), (querys.PageNum-1)*querys.PageSize, querys.PageNum*querys.PageSize
|
||||||
|
if start > total {
|
||||||
|
backDatas = make([]fireClient.FireInfo, 0)
|
||||||
|
} else {
|
||||||
|
if end >= total {
|
||||||
|
end = total
|
||||||
|
}
|
||||||
|
backDatas = datasFilterStrategy[start:end]
|
||||||
|
}
|
||||||
|
|
||||||
|
datasFromDB := s.repoFirewall.List(model.Firewall{})
|
||||||
|
for i := 0; i < len(backDatas); i++ {
|
||||||
|
for _, des := range datasFromDB {
|
||||||
|
if querys.Type != des.Type {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if backDatas[i].Port == des.Port && querys.Type == "port" &&
|
||||||
|
backDatas[i].Protocol == des.Protocol &&
|
||||||
|
backDatas[i].Strategy == des.Strategy &&
|
||||||
|
backDatas[i].Address == des.Address {
|
||||||
|
backDatas[i].Description = des.Description
|
||||||
|
break
|
||||||
|
}
|
||||||
|
if querys.Type == "address" && backDatas[i].Strategy == des.Strategy && backDatas[i].Address == des.Address {
|
||||||
|
backDatas[i].Description = des.Description
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if querys.Type == "port" {
|
||||||
|
for i := 0; i < len(backDatas); i++ {
|
||||||
|
port, _ := strconv.Atoi(backDatas[i].Port)
|
||||||
|
backDatas[i].IsUsed = scan.ScanPort(port)
|
||||||
|
if backDatas[i].Protocol == "udp" {
|
||||||
|
backDatas[i].IsUsed = scan.ScanUDPPort(port)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
go s.cleanUnUsedData(client)
|
||||||
|
|
||||||
|
return data, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceFirewall) pingStatus() string {
|
||||||
|
if _, err := os.Stat("/etc/sysctl.conf"); err != nil {
|
||||||
|
return "None"
|
||||||
|
}
|
||||||
|
sudo := cmd.SudoHandleCmd()
|
||||||
|
command := fmt.Sprintf("%s cat /etc/sysctl.conf | grep net/ipv4/icmp_echo_ignore_all= ", sudo)
|
||||||
|
stdout, _ := cmd.Exec(command)
|
||||||
|
if stdout == "net/ipv4/icmp_echo_ignore_all=1\n" {
|
||||||
|
return "Enable"
|
||||||
|
}
|
||||||
|
return "Disable"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *ServiceFirewall) cleanUnUsedData(client firewall.FirewallClient) {
|
||||||
|
list, _ := client.ListPort()
|
||||||
|
addressList, _ := client.ListAddress()
|
||||||
|
list = append(list, addressList...)
|
||||||
|
if len(list) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
records := s.repoFirewall.List(model.Firewall{})
|
||||||
|
if len(records) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
for _, item := range list {
|
||||||
|
for i := 0; i < len(records); i++ {
|
||||||
|
if records[i].Port == item.Port && records[i].Protocol == item.Protocol && records[i].Strategy == item.Strategy && records[i].Address == item.Address {
|
||||||
|
records = append(records[:i], records[i+1:]...)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, record := range records {
|
||||||
|
_ = s.repoFirewall.Delete(record.ID)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -187,6 +187,9 @@ func NeInfoByUDM(neId string) (*dborm.NeInfo, error) {
|
|||||||
log.Error("dborm.XormGetNeInfo is failed:", err)
|
log.Error("dborm.XormGetNeInfo is failed:", err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if neInfo == nil || neInfo.Ip == "" {
|
||||||
|
return nil, fmt.Errorf("not ne_info or not IP")
|
||||||
|
}
|
||||||
return neInfo, nil
|
return neInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -203,6 +206,7 @@ type UdmUserApi struct {
|
|||||||
// GET /auths
|
// GET /auths
|
||||||
func (s *UdmUserApi) UdmAuthUserList(w http.ResponseWriter, r *http.Request) {
|
func (s *UdmUserApi) UdmAuthUserList(w http.ResponseWriter, r *http.Request) {
|
||||||
querys := ctx.QueryMap(r)
|
querys := ctx.QueryMap(r)
|
||||||
|
querys["neId"] = "-"
|
||||||
data := s.authUser.Page(querys)
|
data := s.authUser.Page(querys)
|
||||||
ctx.JSON(w, 200, result.Ok(data))
|
ctx.JSON(w, 200, result.Ok(data))
|
||||||
}
|
}
|
||||||
@@ -217,6 +221,7 @@ func (s *UdmUserApi) UdmAuthUserSave(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
neId = "-"
|
||||||
data := s.authUser.Save(neId)
|
data := s.authUser.Save(neId)
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -246,7 +251,7 @@ func (s *UdmUserApi) UdmAuthUserInfo(w http.ResponseWriter, r *http.Request) {
|
|||||||
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
neId = "-"
|
||||||
var userInfo model.UdmAuthUser
|
var userInfo model.UdmAuthUser
|
||||||
list := s.authUser.List(model.UdmAuthUser{NeID: neId, Imsi: imsi})
|
list := s.authUser.List(model.UdmAuthUser{NeID: neId, Imsi: imsi})
|
||||||
if len(list) > 0 {
|
if len(list) > 0 {
|
||||||
@@ -300,7 +305,8 @@ func (s *UdmUserApi) UdmAuthUserAdd(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
s.authUser.Insert(neInfo.NeId, body)
|
neId = "-"
|
||||||
|
s.authUser.Insert(neId, body)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -340,7 +346,8 @@ func (s *UdmUserApi) UdmAuthUserAdds(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
s.authUser.Inserts(neInfo.NeId, body, num)
|
neId = "-"
|
||||||
|
s.authUser.Inserts(neId, body, num)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -392,7 +399,8 @@ func (s *UdmUserApi) UdmAuthUserEdit(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
s.authUser.Update(neInfo.NeId, body)
|
neId = "-"
|
||||||
|
s.authUser.Update(neId, body)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -425,6 +433,7 @@ func (s *UdmUserApi) UdmAuthUserRemove(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
|
neId = "-"
|
||||||
s.authUser.Delete(neId, imsi)
|
s.authUser.Delete(neId, imsi)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
@@ -459,6 +468,7 @@ func (s *UdmUserApi) UdmAuthUserRemoves(w http.ResponseWriter, r *http.Request)
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
|
neId = "-"
|
||||||
s.authUser.Deletes(neId, imsi, num)
|
s.authUser.Deletes(neId, imsi, num)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
@@ -473,15 +483,16 @@ func (s *UdmUserApi) UdmAuthUserExport(w http.ResponseWriter, r *http.Request) {
|
|||||||
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
neId = "-"
|
||||||
list := s.authUser.List(model.UdmAuthUser{NeID: neId})
|
list := s.authUser.List(model.UdmAuthUser{NeID: neId})
|
||||||
// 文件名
|
// 文件名
|
||||||
fileName := fmt.Sprintf("OMC_AUTH_USER_EXPORT_%s_%d.csv", neId, time.Now().UnixMilli())
|
fileName := fmt.Sprintf("OMC_AUTH_USER_EXPORT_%s_%d.csv", neId, time.Now().UnixMilli())
|
||||||
filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
||||||
// 转换数据
|
// 转换数据
|
||||||
data := [][]string{}
|
data := [][]string{}
|
||||||
data = append(data, []string{"imsi", "ki", "amf", "algo", "opc", "status"})
|
data = append(data, []string{"imsi", "ki", "amf", "algo", "opc"})
|
||||||
for _, v := range list {
|
for _, v := range list {
|
||||||
data = append(data, []string{v.Imsi, v.Ki, v.Amf, v.AlgoIndex, v.Opc, v.Status})
|
data = append(data, []string{v.Imsi, v.Ki, v.Amf, v.AlgoIndex, v.Opc})
|
||||||
}
|
}
|
||||||
// 输出到文件
|
// 输出到文件
|
||||||
err := file.WriterCSVFile(data, filePath)
|
err := file.WriterCSVFile(data, filePath)
|
||||||
@@ -502,6 +513,17 @@ func (s *UdmUserApi) UdmAuthUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取文件名
|
||||||
|
_, fileHeader, err := r.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(fileHeader.Filename, ".csv") {
|
||||||
|
ctx.JSON(w, 200, result.ErrMsg("请上传CSV格式文件,内容字段imsi, ki, algo, amf, opc"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
neInfo, err := NeInfoByUDM(neId)
|
neInfo, err := NeInfoByUDM(neId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||||
@@ -509,7 +531,7 @@ func (s *UdmUserApi) UdmAuthUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 文件名
|
// 文件名
|
||||||
fileName := fmt.Sprintf("OMC_AUTH_USER_IMPORT_%s_%d.csv", neId, time.Now().UnixMilli())
|
fileName := fmt.Sprintf("OMC_AUTH_USER_IMPORT_%s_%d_%s", neId, time.Now().UnixMilli(), fileHeader.Filename)
|
||||||
filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
||||||
dstPath := conf.Get("mml.upload").(string)
|
dstPath := conf.Get("mml.upload").(string)
|
||||||
// 输出保存文件
|
// 输出保存文件
|
||||||
@@ -526,7 +548,7 @@ func (s *UdmUserApi) UdmAuthUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := fmt.Sprintf("import authdat:path=%s", fmt.Sprintf("%s%s", dstPath, fileName))
|
msg := fmt.Sprintf("import authdat:path=%s", fmt.Sprintf("%s/%s", dstPath, fileName))
|
||||||
|
|
||||||
// 发送MML
|
// 发送MML
|
||||||
data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg)
|
data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg)
|
||||||
@@ -537,10 +559,10 @@ func (s *UdmUserApi) UdmAuthUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
data := file.ReadCSVFile(filePath)
|
data := file.ReadCSVFile(filePath)
|
||||||
|
neId = "-"
|
||||||
s.authUser.InsertCSV(neId, data)
|
s.authUser.InsertCSV(neId, data)
|
||||||
}
|
}
|
||||||
// ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
ctx.FileAttachment(w, r, filePath, fileName)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// UDM签约用户
|
// UDM签约用户
|
||||||
@@ -548,6 +570,7 @@ func (s *UdmUserApi) UdmAuthUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
// GET /subs
|
// GET /subs
|
||||||
func (s *UdmUserApi) UdmSubUserList(w http.ResponseWriter, r *http.Request) {
|
func (s *UdmUserApi) UdmSubUserList(w http.ResponseWriter, r *http.Request) {
|
||||||
querys := ctx.QueryMap(r)
|
querys := ctx.QueryMap(r)
|
||||||
|
querys["neId"] = "-"
|
||||||
data := s.subUser.Page(querys)
|
data := s.subUser.Page(querys)
|
||||||
ctx.JSON(w, 200, result.Ok(data))
|
ctx.JSON(w, 200, result.Ok(data))
|
||||||
}
|
}
|
||||||
@@ -562,6 +585,7 @@ func (s *UdmUserApi) UdmSubUserSave(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
neId = "-"
|
||||||
data := s.subUser.Save(neId)
|
data := s.subUser.Save(neId)
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -592,6 +616,7 @@ func (s *UdmUserApi) UdmSubUserInfo(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
neId = "-"
|
||||||
var userInfo model.UdmSubUser
|
var userInfo model.UdmSubUser
|
||||||
list := s.subUser.List(model.UdmSubUser{NeID: neId, Imsi: imsi})
|
list := s.subUser.List(model.UdmSubUser{NeID: neId, Imsi: imsi})
|
||||||
if len(list) > 0 {
|
if len(list) > 0 {
|
||||||
@@ -668,7 +693,8 @@ func (s *UdmUserApi) UdmSubUserAdd(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
s.subUser.Insert(neInfo.NeId, body)
|
neId = "-"
|
||||||
|
s.subUser.Insert(neId, body)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -713,7 +739,8 @@ func (s *UdmUserApi) UdmSubUserAdds(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
s.subUser.Inserts(neInfo.NeId, body, num)
|
neId = "-"
|
||||||
|
s.subUser.Inserts(neId, body, num)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -752,7 +779,8 @@ func (s *UdmUserApi) UdmSubUserAdd4G(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
s.subUser.Insert4G(neInfo.NeId, body)
|
neId = "-"
|
||||||
|
s.subUser.Insert4G(neId, body)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -809,6 +837,7 @@ func (s *UdmUserApi) UdmSubUserEdit(w http.ResponseWriter, r *http.Request) {
|
|||||||
if body.SmData != "" {
|
if body.SmData != "" {
|
||||||
msg += fmt.Sprintf(",sm_data=%s", body.SmData)
|
msg += fmt.Sprintf(",sm_data=%s", body.SmData)
|
||||||
}
|
}
|
||||||
|
msg += fmt.Sprintf(",static_ip=%s", body.StaticIp)
|
||||||
|
|
||||||
// 发送MML
|
// 发送MML
|
||||||
data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg)
|
data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg)
|
||||||
@@ -819,7 +848,8 @@ func (s *UdmUserApi) UdmSubUserEdit(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
s.subUser.Update(neInfo.NeId, body)
|
neId = "-"
|
||||||
|
s.subUser.Update(neId, body)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -857,6 +887,7 @@ func (s *UdmUserApi) UdmSubUser4GIP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
|
neId = "-"
|
||||||
s.subUser.Update4GIP(neId, body)
|
s.subUser.Update4GIP(neId, body)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
@@ -896,6 +927,7 @@ func (s *UdmUserApi) UdmSubUserSmData(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
|
neId = "-"
|
||||||
s.subUser.UpdateSmData(neId, body)
|
s.subUser.UpdateSmData(neId, body)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
@@ -929,6 +961,7 @@ func (s *UdmUserApi) UdmSubUserRemove(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
|
neId = "-"
|
||||||
s.subUser.Delete(neId, imsi)
|
s.subUser.Delete(neId, imsi)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
@@ -963,7 +996,8 @@ func (s *UdmUserApi) UdmSubUserRemoves(w http.ResponseWriter, r *http.Request) {
|
|||||||
|
|
||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
s.authUser.Deletes(neId, imsi, num)
|
neId = "-"
|
||||||
|
s.subUser.Deletes(neId, imsi, num)
|
||||||
}
|
}
|
||||||
ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
}
|
}
|
||||||
@@ -977,6 +1011,7 @@ func (s *UdmUserApi) UdmSubUserExport(w http.ResponseWriter, r *http.Request) {
|
|||||||
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
ctx.JSON(w, 400, result.CodeMsg(400, "参数错误"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
neId = "-"
|
||||||
list := s.subUser.List(model.UdmSubUser{NeID: neId})
|
list := s.subUser.List(model.UdmSubUser{NeID: neId})
|
||||||
// 文件名
|
// 文件名
|
||||||
fileName := fmt.Sprintf("OMC_AUTH_USER_EXPORT_%s_%d.csv", neId, time.Now().UnixMilli())
|
fileName := fmt.Sprintf("OMC_AUTH_USER_EXPORT_%s_%d.csv", neId, time.Now().UnixMilli())
|
||||||
@@ -1006,6 +1041,17 @@ func (s *UdmUserApi) UdmSubUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 获取文件名
|
||||||
|
_, fileHeader, err := r.FormFile("file")
|
||||||
|
if err != nil {
|
||||||
|
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !strings.HasSuffix(fileHeader.Filename, ".csv") {
|
||||||
|
ctx.JSON(w, 200, result.ErrMsg("请上传CSV格式文件,内容字段imsi, msisdn, ambr, nssai, arfb, sar,rat, cn, smf_sel, sm_dat,eps_dat"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
neInfo, err := NeInfoByUDM(neId)
|
neInfo, err := NeInfoByUDM(neId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
ctx.JSON(w, 200, result.ErrMsg(err.Error()))
|
||||||
@@ -1013,7 +1059,7 @@ func (s *UdmUserApi) UdmSubUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 文件名
|
// 文件名
|
||||||
fileName := fmt.Sprintf("OMC_SUB_USER_IMPORT_%s_%d.csv", neId, time.Now().UnixMilli())
|
fileName := fmt.Sprintf("OMC_SUB_USER_IMPORT_%s_%d_%s", neId, time.Now().UnixMilli(), fileHeader.Filename)
|
||||||
filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
filePath := fmt.Sprintf("%s/upload/mml/%s", conf.Get("ne.omcdir"), fileName)
|
||||||
dstPath := conf.Get("mml.upload").(string)
|
dstPath := conf.Get("mml.upload").(string)
|
||||||
// 输出保存文件
|
// 输出保存文件
|
||||||
@@ -1030,7 +1076,7 @@ func (s *UdmUserApi) UdmSubUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
msg := fmt.Sprintf("import udmuser:path=%s", fmt.Sprintf("%s%s", dstPath, fileName))
|
msg := fmt.Sprintf("import udmuser:path=%s", fmt.Sprintf("%s/%s", dstPath, fileName))
|
||||||
|
|
||||||
// 发送MML
|
// 发送MML
|
||||||
data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg)
|
data, err := mmlclient.MMLSendMsgToString(neInfo.Ip, msg)
|
||||||
@@ -1041,8 +1087,8 @@ func (s *UdmUserApi) UdmSubUserImport(w http.ResponseWriter, r *http.Request) {
|
|||||||
// 命令ok时
|
// 命令ok时
|
||||||
if strings.Contains(data, "ok") {
|
if strings.Contains(data, "ok") {
|
||||||
data := file.ReadCSVFile(filePath)
|
data := file.ReadCSVFile(filePath)
|
||||||
s.authUser.InsertCSV(neId, data)
|
neId = "-"
|
||||||
|
s.subUser.InsertCSV(neId, data)
|
||||||
}
|
}
|
||||||
// ctx.JSON(w, 200, result.OkData(data))
|
ctx.JSON(w, 200, result.OkData(data))
|
||||||
ctx.FileAttachment(w, r, filePath, fileName)
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,14 +210,16 @@ func (r *RepoUdmSubUser) Inserts(neID string, subUser model.UdmSubUser, num stri
|
|||||||
subUser.Imsi = fmt.Sprint(imsiV + i)
|
subUser.Imsi = fmt.Sprint(imsiV + i)
|
||||||
subUser.Msisdn = fmt.Sprint(msisdnV + i)
|
subUser.Msisdn = fmt.Sprint(msisdnV + i)
|
||||||
// IP会自动递增
|
// IP会自动递增
|
||||||
parts := strings.Split(subUser.StaticIp, ".")
|
if subUser.StaticIp != "" {
|
||||||
lastPart := parts[3]
|
parts := strings.Split(subUser.StaticIp, ".")
|
||||||
lastNum, _ := strconv.Atoi(lastPart)
|
lastPart := parts[3]
|
||||||
lastNum += i
|
lastNum, _ := strconv.Atoi(lastPart)
|
||||||
newLastPart := strconv.Itoa(lastNum)
|
lastNum += i
|
||||||
parts[3] = newLastPart
|
newLastPart := strconv.Itoa(lastNum)
|
||||||
newIP := strings.Join(parts, ".")
|
parts[3] = newLastPart
|
||||||
subUser.StaticIp = newIP
|
newIP := strings.Join(parts, ".")
|
||||||
|
subUser.StaticIp = newIP
|
||||||
|
}
|
||||||
results, err := datasource.DefaultDB().Table("u_sub_user").Insert(subUser)
|
results, err := datasource.DefaultDB().Table("u_sub_user").Insert(subUser)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
insertNum += results
|
insertNum += results
|
||||||
@@ -289,6 +291,7 @@ func (r *RepoUdmSubUser) Update(neID string, authUser model.UdmSubUser) int64 {
|
|||||||
if authUser.EpsDat != "" && authUser.EpsDat != user.EpsDat {
|
if authUser.EpsDat != "" && authUser.EpsDat != user.EpsDat {
|
||||||
user.EpsDat = authUser.EpsDat
|
user.EpsDat = authUser.EpsDat
|
||||||
}
|
}
|
||||||
|
user.StaticIp = authUser.StaticIp
|
||||||
|
|
||||||
results, err := datasource.DefaultDB().Table("u_sub_user").Where("imsi = ? and ne_id = ?", user.Imsi, user.NeID).Update(user)
|
results, err := datasource.DefaultDB().Table("u_sub_user").Where("imsi = ? and ne_id = ?", user.Imsi, user.NeID).Update(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"ems.agt/lib/dborm"
|
|
||||||
"ems.agt/lib/log"
|
|
||||||
)
|
|
||||||
|
|
||||||
func UDMNeInfo(neId string) (*dborm.NeInfo, error) {
|
|
||||||
neInfo, err := dborm.XormGetNeInfo("UDM", neId)
|
|
||||||
if err != nil {
|
|
||||||
log.Error("dborm.XormGetNeInfo is failed:", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return neInfo, nil
|
|
||||||
}
|
|
||||||
@@ -69,7 +69,7 @@ func (r *ServiceUdmAuthUser) InsertCSV(neID string, data []map[string]string) in
|
|||||||
if s, ok := v["opc"]; ok {
|
if s, ok := v["opc"]; ok {
|
||||||
authUser.Opc = s
|
authUser.Opc = s
|
||||||
}
|
}
|
||||||
r.repoAuthUser.Insert(neID, authUser)
|
num += r.repoAuthUser.Insert(neID, authUser)
|
||||||
}
|
}
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ func (r *ServiceUdmSubUser) InsertCSV(neID string, data []map[string]string) int
|
|||||||
if s, ok := v["eps_dat"]; ok {
|
if s, ok := v["eps_dat"]; ok {
|
||||||
subUser.EpsDat = s
|
subUser.EpsDat = s
|
||||||
}
|
}
|
||||||
r.repoSunUser.Insert(neID, subUser)
|
num += r.repoSunUser.Insert(neID, subUser)
|
||||||
}
|
}
|
||||||
return num
|
return num
|
||||||
}
|
}
|
||||||
|
|||||||
201
lib/core/cmd/cmd.go
Normal file
201
lib/core/cmd/cmd.go
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"os/exec"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Exec(cmdStr string) (string, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 20*time.Second)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.Command("bash", "-c", cmdStr)
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
err := cmd.Run()
|
||||||
|
if ctx.Err() == context.DeadlineExceeded {
|
||||||
|
return "", fmt.Errorf("errCmdTimeout %v", err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
errMsg := ""
|
||||||
|
if len(stderr.String()) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
|
||||||
|
}
|
||||||
|
if len(stdout.String()) != 0 {
|
||||||
|
if len(errMsg) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String())
|
||||||
|
} else {
|
||||||
|
errMsg = fmt.Sprintf("stdout: %s", stdout.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errMsg, err
|
||||||
|
}
|
||||||
|
return stdout.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecWithTimeOut(cmdStr string, timeout time.Duration) (string, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.Command("bash", "-c", cmdStr)
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
err := cmd.Run()
|
||||||
|
if ctx.Err() == context.DeadlineExceeded {
|
||||||
|
return "", fmt.Errorf("errCmdTimeout %v", err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
errMsg := ""
|
||||||
|
if len(stderr.String()) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
|
||||||
|
}
|
||||||
|
if len(stdout.String()) != 0 {
|
||||||
|
if len(errMsg) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String())
|
||||||
|
} else {
|
||||||
|
errMsg = fmt.Sprintf("stdout: %s", stdout.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errMsg, err
|
||||||
|
}
|
||||||
|
return stdout.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecCronjobWithTimeOut(cmdStr string, workdir string, timeout time.Duration) (string, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), timeout)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.Command("bash", "-c", cmdStr)
|
||||||
|
cmd.Dir = workdir
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
err := cmd.Run()
|
||||||
|
if ctx.Err() == context.DeadlineExceeded {
|
||||||
|
return "", fmt.Errorf("errCmdTimeout %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
errMsg := ""
|
||||||
|
if len(stderr.String()) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("stderr:\n %s", stderr.String())
|
||||||
|
}
|
||||||
|
if len(stdout.String()) != 0 {
|
||||||
|
if len(errMsg) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("%s \n\n; stdout:\n %s", errMsg, stdout.String())
|
||||||
|
} else {
|
||||||
|
errMsg = fmt.Sprintf("stdout:\n %s", stdout.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errMsg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func Execf(cmdStr string, a ...interface{}) (string, error) {
|
||||||
|
cmd := exec.Command("bash", "-c", fmt.Sprintf(cmdStr, a...))
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
errMsg := ""
|
||||||
|
if len(stderr.String()) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
|
||||||
|
}
|
||||||
|
if len(stdout.String()) != 0 {
|
||||||
|
if len(errMsg) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String())
|
||||||
|
} else {
|
||||||
|
errMsg = fmt.Sprintf("stdout: %s", stdout.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errMsg, err
|
||||||
|
}
|
||||||
|
return stdout.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecWithCheck(name string, a ...string) (string, error) {
|
||||||
|
cmd := exec.Command(name, a...)
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
err := cmd.Run()
|
||||||
|
if err != nil {
|
||||||
|
errMsg := ""
|
||||||
|
if len(stderr.String()) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
|
||||||
|
}
|
||||||
|
if len(stdout.String()) != 0 {
|
||||||
|
if len(errMsg) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String())
|
||||||
|
} else {
|
||||||
|
errMsg = fmt.Sprintf("stdout: %s", stdout.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errMsg, err
|
||||||
|
}
|
||||||
|
return stdout.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecScript(scriptPath, workDir string) (string, error) {
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
cmd := exec.Command("bash", scriptPath)
|
||||||
|
cmd.Dir = workDir
|
||||||
|
var stdout, stderr bytes.Buffer
|
||||||
|
cmd.Stdout = &stdout
|
||||||
|
cmd.Stderr = &stderr
|
||||||
|
err := cmd.Run()
|
||||||
|
if ctx.Err() == context.DeadlineExceeded {
|
||||||
|
return "", fmt.Errorf("errCmdTimeout %v", err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
errMsg := ""
|
||||||
|
if len(stderr.String()) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("stderr: %s", stderr.String())
|
||||||
|
}
|
||||||
|
if len(stdout.String()) != 0 {
|
||||||
|
if len(errMsg) != 0 {
|
||||||
|
errMsg = fmt.Sprintf("%s; stdout: %s", errMsg, stdout.String())
|
||||||
|
} else {
|
||||||
|
errMsg = fmt.Sprintf("stdout: %s", stdout.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errMsg, err
|
||||||
|
}
|
||||||
|
return stdout.String(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func CheckIllegal(args ...string) bool {
|
||||||
|
if args == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
for _, arg := range args {
|
||||||
|
if strings.Contains(arg, "&") || strings.Contains(arg, "|") || strings.Contains(arg, ";") ||
|
||||||
|
strings.Contains(arg, "$") || strings.Contains(arg, "'") || strings.Contains(arg, "`") ||
|
||||||
|
strings.Contains(arg, "(") || strings.Contains(arg, ")") || strings.Contains(arg, "\"") {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func HasNoPasswordSudo() bool {
|
||||||
|
cmd2 := exec.Command("sudo", "-n", "ls")
|
||||||
|
err2 := cmd2.Run()
|
||||||
|
return err2 == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func SudoHandleCmd() string {
|
||||||
|
cmd := exec.Command("sudo", "-n", "ls")
|
||||||
|
if err := cmd.Run(); err == nil {
|
||||||
|
return "sudo "
|
||||||
|
}
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
func Which(name string) bool {
|
||||||
|
_, err := exec.LookPath(name)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
@@ -49,7 +49,7 @@ func MMLSendMsgToString(ip, msg string) (string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 命令成功
|
// 命令成功
|
||||||
if strings.HasPrefix(str, "command ok") {
|
if strings.Contains(str, "ok") {
|
||||||
return str, nil
|
return str, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
34
lib/core/utils/firewall/client.go
Normal file
34
lib/core/utils/firewall/client.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
package firewall
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"ems.agt/lib/core/utils/firewall/client"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FirewallClient interface {
|
||||||
|
Name() string // ufw firewalld
|
||||||
|
Start() error
|
||||||
|
Stop() error
|
||||||
|
Reload() error
|
||||||
|
Status() (string, error) // running not running
|
||||||
|
Version() (string, error)
|
||||||
|
|
||||||
|
ListPort() ([]client.FireInfo, error)
|
||||||
|
ListAddress() ([]client.FireInfo, error)
|
||||||
|
|
||||||
|
Port(port client.FireInfo, operation string) error
|
||||||
|
RichRules(rule client.FireInfo, operation string) error
|
||||||
|
PortForward(info client.Forward, operation string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFirewallClient() (FirewallClient, error) {
|
||||||
|
if _, err := os.Stat("/usr/sbin/firewalld"); err == nil {
|
||||||
|
return client.NewFirewalld()
|
||||||
|
}
|
||||||
|
if _, err := os.Stat("/usr/sbin/ufw"); err == nil {
|
||||||
|
return client.NewUfw()
|
||||||
|
}
|
||||||
|
return nil, errors.New("no such type")
|
||||||
|
}
|
||||||
209
lib/core/utils/firewall/client/firewalld.go
Normal file
209
lib/core/utils/firewall/client/firewalld.go
Normal file
@@ -0,0 +1,209 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"ems.agt/lib/core/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Firewall struct{}
|
||||||
|
|
||||||
|
func NewFirewalld() (*Firewall, error) {
|
||||||
|
return &Firewall{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) Name() string {
|
||||||
|
return "firewalld"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) Status() (string, error) {
|
||||||
|
stdout, _ := cmd.Exec("firewall-cmd --state")
|
||||||
|
if stdout == "running\n" {
|
||||||
|
return "running", nil
|
||||||
|
}
|
||||||
|
return "not running", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) Version() (string, error) {
|
||||||
|
stdout, err := cmd.Exec("firewall-cmd --version")
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("load the firewall version failed, err: %s", stdout)
|
||||||
|
}
|
||||||
|
return strings.ReplaceAll(stdout, "\n ", ""), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) Start() error {
|
||||||
|
stdout, err := cmd.Exec("systemctl start firewalld")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("enable the firewall failed, err: %s", stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) Stop() error {
|
||||||
|
stdout, err := cmd.Exec("systemctl stop firewalld")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("stop the firewall failed, err: %s", stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) Reload() error {
|
||||||
|
stdout, err := cmd.Exec("firewall-cmd --reload")
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("reload firewall failed, err: %s", stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) ListPort() ([]FireInfo, error) {
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
var datas []FireInfo
|
||||||
|
wg.Add(2)
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
stdout, err := cmd.Exec("firewall-cmd --zone=public --list-ports")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ports := strings.Split(strings.ReplaceAll(stdout, "\n", ""), " ")
|
||||||
|
for _, port := range ports {
|
||||||
|
if len(port) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
var itemPort FireInfo
|
||||||
|
if strings.Contains(port, "/") {
|
||||||
|
itemPort.Port = strings.Split(port, "/")[0]
|
||||||
|
itemPort.Protocol = strings.Split(port, "/")[1]
|
||||||
|
}
|
||||||
|
itemPort.Strategy = "accept"
|
||||||
|
datas = append(datas, itemPort)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
defer wg.Done()
|
||||||
|
stdout1, err := cmd.Exec("firewall-cmd --zone=public --list-rich-rules")
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
rules := strings.Split(stdout1, "\n")
|
||||||
|
for _, rule := range rules {
|
||||||
|
if len(rule) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
itemRule := f.loadInfo(rule)
|
||||||
|
if len(itemRule.Port) != 0 && itemRule.Family == "ipv4" {
|
||||||
|
datas = append(datas, itemRule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
wg.Wait()
|
||||||
|
return datas, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) ListAddress() ([]FireInfo, error) {
|
||||||
|
stdout, err := cmd.Exec("firewall-cmd --zone=public --list-rich-rules")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var datas []FireInfo
|
||||||
|
rules := strings.Split(stdout, "\n")
|
||||||
|
for _, rule := range rules {
|
||||||
|
if len(rule) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
itemRule := f.loadInfo(rule)
|
||||||
|
if len(itemRule.Port) == 0 && len(itemRule.Address) != 0 {
|
||||||
|
datas = append(datas, itemRule)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return datas, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) Port(port FireInfo, operation string) error {
|
||||||
|
if cmd.CheckIllegal(operation, port.Protocol, port.Port) {
|
||||||
|
return fmt.Errorf("errCmdIllegal %v", port)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout, err := cmd.Execf("firewall-cmd --zone=public --%s-port=%s/%s --permanent", operation, port.Port, port.Protocol)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s port failed, err: %s", operation, stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) RichRules(rule FireInfo, operation string) error {
|
||||||
|
if cmd.CheckIllegal(operation, rule.Address, rule.Protocol, rule.Port, rule.Strategy) {
|
||||||
|
return fmt.Errorf("errCmdIllegal %v", rule)
|
||||||
|
}
|
||||||
|
ruleStr := ""
|
||||||
|
if strings.Contains(rule.Address, "-") {
|
||||||
|
std, err := cmd.Execf("firewall-cmd --permanent --new-ipset=%s --type=hash:ip", rule.Address)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("add new ipset failed, err: %s", std)
|
||||||
|
}
|
||||||
|
std2, err := cmd.Execf("firewall-cmd --permanent --ipset=%s --add-entry=%s", rule.Address, rule.Address)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("add entry to ipset failed, err: %s", std2)
|
||||||
|
}
|
||||||
|
if err := f.Reload(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ruleStr = fmt.Sprintf("rule source ipset=%s %s", rule.Address, rule.Strategy)
|
||||||
|
} else {
|
||||||
|
ruleStr = "rule family=ipv4 "
|
||||||
|
if len(rule.Address) != 0 {
|
||||||
|
ruleStr += fmt.Sprintf("source address=%s ", rule.Address)
|
||||||
|
}
|
||||||
|
if len(rule.Port) != 0 {
|
||||||
|
ruleStr += fmt.Sprintf("port port=%s ", rule.Port)
|
||||||
|
}
|
||||||
|
if len(rule.Protocol) != 0 {
|
||||||
|
ruleStr += fmt.Sprintf("protocol=%s ", rule.Protocol)
|
||||||
|
}
|
||||||
|
ruleStr += rule.Strategy
|
||||||
|
}
|
||||||
|
stdout, err := cmd.Execf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", operation, ruleStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s rich rules failed, err: %s", operation, stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) PortForward(info Forward, operation string) error {
|
||||||
|
ruleStr := fmt.Sprintf("firewall-cmd --%s-forward-port=port=%s:proto=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.Target)
|
||||||
|
if len(info.Address) != 0 {
|
||||||
|
ruleStr = fmt.Sprintf("firewall-cmd --%s-forward-port=port=%s:proto=%s:toaddr=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.Address, info.Target)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout, err := cmd.Exec(ruleStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s port forward failed, err: %s", operation, stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Firewall) loadInfo(line string) FireInfo {
|
||||||
|
var itemRule FireInfo
|
||||||
|
ruleInfo := strings.Split(strings.ReplaceAll(line, "\"", ""), " ")
|
||||||
|
for _, item := range ruleInfo {
|
||||||
|
switch {
|
||||||
|
case strings.Contains(item, "family="):
|
||||||
|
itemRule.Family = strings.ReplaceAll(item, "family=", "")
|
||||||
|
case strings.Contains(item, "ipset="):
|
||||||
|
itemRule.Address = strings.ReplaceAll(item, "ipset=", "")
|
||||||
|
case strings.Contains(item, "address="):
|
||||||
|
itemRule.Address = strings.ReplaceAll(item, "address=", "")
|
||||||
|
case strings.Contains(item, "port="):
|
||||||
|
itemRule.Port = strings.ReplaceAll(item, "port=", "")
|
||||||
|
case strings.Contains(item, "protocol="):
|
||||||
|
itemRule.Protocol = strings.ReplaceAll(item, "protocol=", "")
|
||||||
|
case item == "accept" || item == "drop" || item == "reject":
|
||||||
|
itemRule.Strategy = item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return itemRule
|
||||||
|
}
|
||||||
20
lib/core/utils/firewall/client/info.go
Normal file
20
lib/core/utils/firewall/client/info.go
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
type FireInfo struct {
|
||||||
|
Family string `json:"family"` // ipv4 ipv6
|
||||||
|
Address string `json:"address"` // Anywhere
|
||||||
|
Port string `json:"port"`
|
||||||
|
Protocol string `json:"protocol"` // tcp udp tcp/udp
|
||||||
|
Strategy string `json:"strategy"` // accept drop
|
||||||
|
|
||||||
|
APPName string `json:"appName"`
|
||||||
|
IsUsed bool `json:"isUsed"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Forward struct {
|
||||||
|
Protocol string `json:"protocol"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
Port string `json:"port"`
|
||||||
|
Target string `json:"target"`
|
||||||
|
}
|
||||||
238
lib/core/utils/firewall/client/ufw.go
Normal file
238
lib/core/utils/firewall/client/ufw.go
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"ems.agt/lib/core/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Ufw struct {
|
||||||
|
CmdStr string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewUfw() (*Ufw, error) {
|
||||||
|
var ufw Ufw
|
||||||
|
if cmd.HasNoPasswordSudo() {
|
||||||
|
ufw.CmdStr = "sudo ufw"
|
||||||
|
} else {
|
||||||
|
ufw.CmdStr = "ufw"
|
||||||
|
}
|
||||||
|
return &ufw, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) Name() string {
|
||||||
|
return "ufw"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) Status() (string, error) {
|
||||||
|
stdout, _ := cmd.Execf("%s status | grep Status", f.CmdStr)
|
||||||
|
if stdout == "Status: active\n" {
|
||||||
|
return "running", nil
|
||||||
|
}
|
||||||
|
stdout1, _ := cmd.Execf("%s status | grep 状态", f.CmdStr)
|
||||||
|
if stdout1 == "状态: 激活\n" {
|
||||||
|
return "running", nil
|
||||||
|
}
|
||||||
|
return "not running", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) Version() (string, error) {
|
||||||
|
stdout, err := cmd.Execf("%s version | grep ufw", f.CmdStr)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("load the firewall status failed, err: %s", stdout)
|
||||||
|
}
|
||||||
|
info := strings.ReplaceAll(stdout, "\n", "")
|
||||||
|
return strings.ReplaceAll(info, "ufw ", ""), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) Start() error {
|
||||||
|
stdout, err := cmd.Execf("echo y | %s enable", f.CmdStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("enable the firewall failed, err: %s", stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) Stop() error {
|
||||||
|
stdout, err := cmd.Execf("%s disable", f.CmdStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("stop the firewall failed, err: %s", stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) Reload() error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) ListPort() ([]FireInfo, error) {
|
||||||
|
stdout, err := cmd.Execf("%s status verbose", f.CmdStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
portInfos := strings.Split(stdout, "\n")
|
||||||
|
var datas []FireInfo
|
||||||
|
isStart := false
|
||||||
|
for _, line := range portInfos {
|
||||||
|
if strings.HasPrefix(line, "-") {
|
||||||
|
isStart = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !isStart {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
itemFire := f.loadInfo(line, "port")
|
||||||
|
if len(itemFire.Port) != 0 && itemFire.Port != "Anywhere" && !strings.Contains(itemFire.Port, ".") {
|
||||||
|
itemFire.Port = strings.ReplaceAll(itemFire.Port, ":", "-")
|
||||||
|
datas = append(datas, itemFire)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return datas, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) ListAddress() ([]FireInfo, error) {
|
||||||
|
stdout, err := cmd.Execf("%s status verbose", f.CmdStr)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
portInfos := strings.Split(stdout, "\n")
|
||||||
|
var datas []FireInfo
|
||||||
|
isStart := false
|
||||||
|
for _, line := range portInfos {
|
||||||
|
if strings.HasPrefix(line, "-") {
|
||||||
|
isStart = true
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !isStart {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if !strings.Contains(line, " IN") {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
itemFire := f.loadInfo(line, "address")
|
||||||
|
if strings.Contains(itemFire.Port, ".") {
|
||||||
|
itemFire.Address += ("-" + itemFire.Port)
|
||||||
|
itemFire.Port = ""
|
||||||
|
}
|
||||||
|
if len(itemFire.Port) == 0 && len(itemFire.Address) != 0 {
|
||||||
|
datas = append(datas, itemFire)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return datas, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) Port(port FireInfo, operation string) error {
|
||||||
|
switch port.Strategy {
|
||||||
|
case "accept":
|
||||||
|
port.Strategy = "allow"
|
||||||
|
case "drop":
|
||||||
|
port.Strategy = "deny"
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupport strategy %s", port.Strategy)
|
||||||
|
}
|
||||||
|
if cmd.CheckIllegal(port.Protocol, port.Port) {
|
||||||
|
return fmt.Errorf("errCmdIllegal %v", port)
|
||||||
|
}
|
||||||
|
|
||||||
|
command := fmt.Sprintf("%s %s %s", f.CmdStr, port.Strategy, port.Port)
|
||||||
|
if operation == "remove" {
|
||||||
|
command = fmt.Sprintf("%s delete %s %s", f.CmdStr, port.Strategy, port.Port)
|
||||||
|
}
|
||||||
|
if len(port.Protocol) != 0 {
|
||||||
|
command += fmt.Sprintf("/%s", port.Protocol)
|
||||||
|
}
|
||||||
|
stdout, err := cmd.Exec(command)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s port failed, err: %s", operation, stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) RichRules(rule FireInfo, operation string) error {
|
||||||
|
switch rule.Strategy {
|
||||||
|
case "accept":
|
||||||
|
rule.Strategy = "allow"
|
||||||
|
case "drop":
|
||||||
|
rule.Strategy = "deny"
|
||||||
|
default:
|
||||||
|
return fmt.Errorf("unsupport strategy %s", rule.Strategy)
|
||||||
|
}
|
||||||
|
|
||||||
|
if cmd.CheckIllegal(operation, rule.Protocol, rule.Address, rule.Port) {
|
||||||
|
return fmt.Errorf("errCmdIllegal %v", rule)
|
||||||
|
}
|
||||||
|
|
||||||
|
ruleStr := fmt.Sprintf("%s %s ", f.CmdStr, rule.Strategy)
|
||||||
|
if operation == "remove" {
|
||||||
|
ruleStr = fmt.Sprintf("%s delete %s ", f.CmdStr, rule.Strategy)
|
||||||
|
}
|
||||||
|
if len(rule.Protocol) != 0 {
|
||||||
|
ruleStr += fmt.Sprintf("proto %s ", rule.Protocol)
|
||||||
|
}
|
||||||
|
if strings.Contains(rule.Address, "-") {
|
||||||
|
ruleStr += fmt.Sprintf("from %s to %s ", strings.Split(rule.Address, "-")[0], strings.Split(rule.Address, "-")[1])
|
||||||
|
} else {
|
||||||
|
ruleStr += fmt.Sprintf("from %s ", rule.Address)
|
||||||
|
}
|
||||||
|
if len(rule.Port) != 0 {
|
||||||
|
ruleStr += fmt.Sprintf("to any port %s ", rule.Port)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout, err := cmd.Exec(ruleStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s rich rules failed, err: %s", operation, stdout)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) PortForward(info Forward, operation string) error {
|
||||||
|
ruleStr := fmt.Sprintf("firewall-cmd --%s-forward-port=port=%s:proto=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.Target)
|
||||||
|
if len(info.Address) != 0 {
|
||||||
|
ruleStr = fmt.Sprintf("firewall-cmd --%s-forward-port=port=%s:proto=%s:toaddr=%s:toport=%s --permanent", operation, info.Port, info.Protocol, info.Address, info.Target)
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout, err := cmd.Exec(ruleStr)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("%s port forward failed, err: %s", operation, stdout)
|
||||||
|
}
|
||||||
|
if err := f.Reload(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *Ufw) loadInfo(line string, fireType string) FireInfo {
|
||||||
|
fields := strings.Fields(line)
|
||||||
|
var itemInfo FireInfo
|
||||||
|
if len(fields) < 4 {
|
||||||
|
return itemInfo
|
||||||
|
}
|
||||||
|
if fields[1] == "(v6)" {
|
||||||
|
return itemInfo
|
||||||
|
}
|
||||||
|
if fields[0] == "Anywhere" && fireType != "port" {
|
||||||
|
itemInfo.Strategy = "drop"
|
||||||
|
if fields[1] == "ALLOW" {
|
||||||
|
itemInfo.Strategy = "accept"
|
||||||
|
}
|
||||||
|
itemInfo.Address = fields[3]
|
||||||
|
return itemInfo
|
||||||
|
}
|
||||||
|
if strings.Contains(fields[0], "/") {
|
||||||
|
itemInfo.Port = strings.Split(fields[0], "/")[0]
|
||||||
|
itemInfo.Protocol = strings.Split(fields[0], "/")[1]
|
||||||
|
} else {
|
||||||
|
itemInfo.Port = fields[0]
|
||||||
|
itemInfo.Protocol = "tcp/udp"
|
||||||
|
}
|
||||||
|
itemInfo.Family = "ipv4"
|
||||||
|
if fields[1] == "ALLOW" {
|
||||||
|
itemInfo.Strategy = "accept"
|
||||||
|
} else {
|
||||||
|
itemInfo.Strategy = "drop"
|
||||||
|
}
|
||||||
|
itemInfo.Address = fields[3]
|
||||||
|
|
||||||
|
return itemInfo
|
||||||
|
}
|
||||||
31
lib/core/utils/scan/scan.go
Normal file
31
lib/core/utils/scan/scan.go
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
package scan
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
func ScanPort(port int) bool {
|
||||||
|
ln, err := net.Listen("tcp", ":"+strconv.Itoa(port))
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
defer ln.Close()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScanUDPPort(port int) bool {
|
||||||
|
ln, err := net.ListenUDP("udp", &net.UDPAddr{IP: net.IPv4(127, 0, 0, 1), Port: port})
|
||||||
|
if err != nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
defer ln.Close()
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func ScanPortWithProto(port int, proto string) bool {
|
||||||
|
if proto == "udp" {
|
||||||
|
return ScanUDPPort(port)
|
||||||
|
}
|
||||||
|
return ScanPort(port)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user