mirror of
https://github.com/TeaOSLab/EdgeAdmin.git
synced 2025-11-03 20:40:26 +08:00
增加批量增加节点IP接口
This commit is contained in:
@@ -1,14 +1,17 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"github.com/iwind/TeaGo/types"
|
||||
"math/big"
|
||||
"net"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// 将IP转换为整型
|
||||
// IP2Long 将IP转换为整型
|
||||
func IP2Long(ip string) uint64 {
|
||||
s := net.ParseIP(ip)
|
||||
if len(s) != 16 {
|
||||
@@ -23,7 +26,7 @@ func IP2Long(ip string) uint64 {
|
||||
return uint64(binary.BigEndian.Uint32(s.To4()))
|
||||
}
|
||||
|
||||
// 判断是否为IPv4
|
||||
// IsIPv4 判断是否为IPv4
|
||||
func IsIPv4(ip string) bool {
|
||||
if !regexp.MustCompile(`^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$`).MatchString(ip) {
|
||||
return false
|
||||
@@ -34,10 +37,100 @@ func IsIPv4(ip string) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
// 判断是否为IPv6
|
||||
// IsIPv6 判断是否为IPv6
|
||||
func IsIPv6(ip string) bool {
|
||||
if !strings.Contains(ip, ":") {
|
||||
return false
|
||||
}
|
||||
return len(net.ParseIP(ip)) == net.IPv6len
|
||||
}
|
||||
|
||||
// ExtractIP 分解IP
|
||||
// 只支持D段掩码的CIDR
|
||||
// 最多只记录255个值
|
||||
func ExtractIP(ipStrings string) ([]string, error) {
|
||||
ipStrings = strings.ReplaceAll(ipStrings, " ", "")
|
||||
|
||||
// CIDR
|
||||
if strings.Contains(ipStrings, "/") {
|
||||
_, cidrNet, err := net.ParseCIDR(ipStrings)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var index = strings.Index(ipStrings, "/")
|
||||
var ipFrom = ipStrings[:index]
|
||||
var bits = types.Int(ipStrings[index+1:])
|
||||
if bits < 24 {
|
||||
return nil, errors.New("CIDR bits should be greater than 24")
|
||||
}
|
||||
|
||||
var ipv4 = net.ParseIP(ipFrom).To4()
|
||||
if len(ipv4) == 0 {
|
||||
return nil, errors.New("support IPv4 only")
|
||||
}
|
||||
|
||||
var result = []string{}
|
||||
ipv4[3] = 0 // 从0开始
|
||||
for i := 0; i <= 255; i++ {
|
||||
if cidrNet.Contains(ipv4) {
|
||||
result = append(result, ipv4.String())
|
||||
}
|
||||
ipv4 = NextIP(ipv4)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// IP Range
|
||||
if strings.Contains(ipStrings, "-") {
|
||||
var index = strings.Index(ipStrings, "-")
|
||||
var ipFromString = ipStrings[:index]
|
||||
var ipToString = ipStrings[index+1:]
|
||||
|
||||
var ipFrom = net.ParseIP(ipFromString).To4()
|
||||
if len(ipFrom) == 0 {
|
||||
return nil, errors.New("invalid ip '" + ipFromString + "'")
|
||||
}
|
||||
|
||||
var ipTo = net.ParseIP(ipToString).To4()
|
||||
if len(ipTo) == 0 {
|
||||
return nil, errors.New("invalid ip '" + ipToString + "'")
|
||||
}
|
||||
|
||||
if bytes.Compare(ipFrom, ipTo) > 0 {
|
||||
ipFrom, ipTo = ipTo, ipFrom
|
||||
}
|
||||
|
||||
var result = []string{}
|
||||
for i := 0; i < 255; i++ {
|
||||
if bytes.Compare(ipFrom, ipTo) > 0 {
|
||||
break
|
||||
}
|
||||
result = append(result, ipFrom.String())
|
||||
ipFrom = NextIP(ipFrom)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
return []string{ipStrings}, nil
|
||||
}
|
||||
|
||||
// NextIP IP增加1
|
||||
func NextIP(prevIP net.IP) net.IP {
|
||||
var ip = make(net.IP, len(prevIP))
|
||||
copy(ip, prevIP)
|
||||
var index = len(ip) - 1
|
||||
for {
|
||||
if ip[index] == 255 {
|
||||
ip[index] = 0
|
||||
index--
|
||||
if index < 0 {
|
||||
break
|
||||
}
|
||||
} else {
|
||||
ip[index]++
|
||||
break
|
||||
}
|
||||
}
|
||||
return ip
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net"
|
||||
"testing"
|
||||
)
|
||||
|
||||
@@ -83,3 +84,27 @@ func TestIsIPv6(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestExtractIP(t *testing.T) {
|
||||
t.Log(ExtractIP("192.168.1.100"))
|
||||
}
|
||||
|
||||
func TestExtractIP_CIDR(t *testing.T) {
|
||||
t.Log(ExtractIP("192.168.2.100/24"))
|
||||
}
|
||||
|
||||
func TestExtractIP_Range(t *testing.T) {
|
||||
t.Log(ExtractIP("192.168.2.100 - 192.168.4.2"))
|
||||
}
|
||||
|
||||
func TestNextIP(t *testing.T) {
|
||||
for _, ip := range []string{"192.168.1.1", "0.0.0.0", "255.255.255.255", "192.168.2.255", "192.168.255.255"} {
|
||||
t.Log(ip+":", NextIP(net.ParseIP(ip).To4()))
|
||||
}
|
||||
}
|
||||
|
||||
func TestNextIP_Copy(t *testing.T) {
|
||||
var ip = net.ParseIP("192.168.1.100")
|
||||
var nextIP = NextIP(ip)
|
||||
t.Log(ip, nextIP)
|
||||
}
|
||||
@@ -3,6 +3,7 @@ package cluster
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/default/clusters/grants/grantutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
@@ -167,9 +168,13 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
nodeId := createResp.NodeId
|
||||
|
||||
// IP地址
|
||||
var resultIPAddresses = []string{}
|
||||
for _, addr := range ipAddresses {
|
||||
var resultAddrIds = []int64{}
|
||||
|
||||
addrId := addr.GetInt64("id")
|
||||
if addrId > 0 {
|
||||
resultAddrIds = append(resultAddrIds, addrId)
|
||||
_, err = this.RPC().NodeIPAddressRPC().UpdateNodeIPAddressNodeId(this.AdminContext(), &pb.UpdateNodeIPAddressNodeIdRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeId: nodeId,
|
||||
@@ -178,20 +183,50 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
|
||||
resultIPAddresses = append(resultIPAddresses, addr.GetString("ip"))
|
||||
} else {
|
||||
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: addr.GetString("ip"),
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
var ipStrings = addr.GetString("ip")
|
||||
result, err := utils.ExtractIP(ipStrings)
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
this.Fail("节点创建成功,但是保存IP失败:" + err.Error())
|
||||
}
|
||||
|
||||
resultIPAddresses = append(resultIPAddresses, result...)
|
||||
|
||||
if len(result) == 1 {
|
||||
// 单个创建
|
||||
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: result[0],
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
addrId = createResp.NodeIPAddressId
|
||||
resultAddrIds = append(resultAddrIds, addrId)
|
||||
} else if len(result) > 1 {
|
||||
// 批量创建
|
||||
createResp, err := this.RPC().NodeIPAddressRPC().CreateNodeIPAddresses(this.AdminContext(), &pb.CreateNodeIPAddressesRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleNode,
|
||||
Name: addr.GetString("name"),
|
||||
IpList: result,
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
GroupValue: ipStrings,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
resultAddrIds = append(resultAddrIds, createResp.NodeIPAddressIds...)
|
||||
}
|
||||
addrId = createResp.NodeIPAddressId
|
||||
}
|
||||
|
||||
// 阈值
|
||||
@@ -202,13 +237,16 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
_, err = this.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(this.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
|
||||
for _, addrId := range resultAddrIds {
|
||||
_, err = this.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(this.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -224,11 +262,6 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
return
|
||||
}
|
||||
if nodeResp.Node != nil {
|
||||
var addresses = []string{}
|
||||
for _, addrMap := range ipAddresses {
|
||||
addresses = append(addresses, addrMap.GetString("ip"))
|
||||
}
|
||||
|
||||
var grantMap maps.Map = nil
|
||||
grantId := params.GrantId
|
||||
if grantId > 0 {
|
||||
@@ -253,7 +286,7 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
"name": nodeResp.Node.Name,
|
||||
"uniqueId": nodeResp.Node.UniqueId,
|
||||
"secret": nodeResp.Node.Secret,
|
||||
"addresses": addresses,
|
||||
"addresses": resultIPAddresses,
|
||||
"login": maps.Map{
|
||||
"id": 0,
|
||||
"name": "SSH",
|
||||
|
||||
@@ -3,6 +3,7 @@ package ipAddresses
|
||||
import (
|
||||
"encoding/json"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/iwind/TeaGo/actions"
|
||||
@@ -39,9 +40,15 @@ func (this *CreatePopupAction) RunPost(params struct {
|
||||
Field("ip", params.IP).
|
||||
Require("请输入IP地址")
|
||||
|
||||
ip := net.ParseIP(params.IP)
|
||||
if len(ip) == 0 {
|
||||
this.FailField("ip", "请输入正确的IP")
|
||||
result, err := utils.ExtractIP(params.IP)
|
||||
if err != nil {
|
||||
this.Fail("IP格式错误'" + params.IP + "'")
|
||||
}
|
||||
|
||||
for _, ip := range result {
|
||||
if len(net.ParseIP(ip)) == 0 {
|
||||
this.FailField("ip", "请输入正确的IP")
|
||||
}
|
||||
}
|
||||
|
||||
// 阈值设置
|
||||
|
||||
@@ -2,6 +2,7 @@ package ipaddressutils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -16,8 +17,11 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
|
||||
return err
|
||||
}
|
||||
for _, addr := range addresses {
|
||||
var resultAddrIds = []int64{}
|
||||
addrId := addr.GetInt64("id")
|
||||
if addrId > 0 {
|
||||
resultAddrIds = append(resultAddrIds, addrId)
|
||||
|
||||
var isOn = false
|
||||
if !addr.Has("isOn") { // 兼容老版本
|
||||
isOn = true
|
||||
@@ -37,18 +41,40 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: role,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: addr.GetString("ip"),
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
var ipStrings = addr.GetString("ip")
|
||||
result, _ := utils.ExtractIP(ipStrings)
|
||||
|
||||
if len(result) == 1 {
|
||||
// 单个创建
|
||||
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddress(parentAction.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: role,
|
||||
Name: addr.GetString("name"),
|
||||
Ip: result[0],
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
addrId = createResp.NodeIPAddressId
|
||||
resultAddrIds = append(resultAddrIds, addrId)
|
||||
} else if len(result) > 1 {
|
||||
// 批量创建
|
||||
createResp, err := parentAction.RPC().NodeIPAddressRPC().CreateNodeIPAddresses(parentAction.AdminContext(), &pb.CreateNodeIPAddressesRequest{
|
||||
NodeId: nodeId,
|
||||
Role: role,
|
||||
Name: addr.GetString("name"),
|
||||
IpList: result,
|
||||
CanAccess: addr.GetBool("canAccess"),
|
||||
IsUp: addr.GetBool("isUp"),
|
||||
GroupValue: ipStrings,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resultAddrIds = append(resultAddrIds, createResp.NodeIPAddressIds...)
|
||||
}
|
||||
addrId = createResp.NodeIPAddressId
|
||||
}
|
||||
|
||||
// 保存阈值
|
||||
@@ -58,12 +84,15 @@ func UpdateNodeIPAddresses(parentAction *actionutils.ParentAction, nodeId int64,
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = parentAction.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(parentAction.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
for _, addrId := range resultAddrIds {
|
||||
_, err = parentAction.RPC().NodeIPAddressThresholdRPC().UpdateAllNodeIPAddressThresholds(parentAction.AdminContext(), &pb.UpdateAllNodeIPAddressThresholdsRequest{
|
||||
NodeIPAddressId: addrId,
|
||||
NodeIPAddressThresholdsJSON: thresholdsJSON,
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package ipAddresses
|
||||
import (
|
||||
"encoding/json"
|
||||
teaconst "github.com/TeaOSLab/EdgeAdmin/internal/const"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -57,9 +58,22 @@ func (this *UpdatePopupAction) RunPost(params struct {
|
||||
}
|
||||
}
|
||||
|
||||
ip := net.ParseIP(params.IP)
|
||||
if len(ip) == 0 {
|
||||
this.Fail("请输入正确的IP")
|
||||
if params.AddressId > 0 {
|
||||
ip := net.ParseIP(params.IP)
|
||||
if len(ip) == 0 {
|
||||
this.Fail("请输入正确的IP")
|
||||
}
|
||||
} else {
|
||||
result, err := utils.ExtractIP(params.IP)
|
||||
if err != nil {
|
||||
this.Fail("IP格式错误'" + params.IP + "'")
|
||||
}
|
||||
|
||||
for _, ip := range result {
|
||||
if len(net.ParseIP(ip)) == 0 {
|
||||
this.FailField("ip", "请输入正确的IP")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var thresholds = []*nodeconfigs.IPAddressThresholdConfig{}
|
||||
|
||||
@@ -3,6 +3,7 @@ package cluster
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/oplogs"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/utils"
|
||||
"github.com/TeaOSLab/EdgeAdmin/internal/web/actions/actionutils"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/nodeconfigs"
|
||||
"github.com/TeaOSLab/EdgeCommon/pkg/rpc/pb"
|
||||
@@ -87,14 +88,31 @@ func (this *CreateNodeAction) RunPost(params struct {
|
||||
NodeId: nodeId,
|
||||
})
|
||||
} else {
|
||||
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
Name: addrMap.GetString("name"),
|
||||
Ip: addrMap.GetString("ip"),
|
||||
CanAccess: addrMap.GetBool("canAccess"),
|
||||
IsUp: addrMap.GetBool("isUp"),
|
||||
})
|
||||
var ipStrings = addrMap.GetString("ip")
|
||||
result, _ := utils.ExtractIP(ipStrings)
|
||||
|
||||
if len(result) == 1 {
|
||||
// 单个创建
|
||||
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddress(this.AdminContext(), &pb.CreateNodeIPAddressRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
Name: addrMap.GetString("name"),
|
||||
Ip: result[0],
|
||||
CanAccess: addrMap.GetBool("canAccess"),
|
||||
IsUp: addrMap.GetBool("isUp"),
|
||||
})
|
||||
} else if len(result) > 1 {
|
||||
// 批量创建
|
||||
_, err = this.RPC().NodeIPAddressRPC().CreateNodeIPAddresses(this.AdminContext(), &pb.CreateNodeIPAddressesRequest{
|
||||
NodeId: nodeId,
|
||||
Role: nodeconfigs.NodeRoleDNS,
|
||||
Name: addrMap.GetString("name"),
|
||||
IpList: result,
|
||||
CanAccess: addrMap.GetBool("canAccess"),
|
||||
IsUp: addrMap.GetBool("isUp"),
|
||||
GroupValue: ipStrings,
|
||||
})
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
this.ErrorPage(err)
|
||||
|
||||
Reference in New Issue
Block a user