mirror of
https://github.com/gravitl/netmaker.git
synced 2025-10-06 17:29:15 +08:00
fix network ip allocation in HA
This commit is contained in:
@@ -458,7 +458,9 @@ func deleteNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
go logic.DeleteNetworkRoles(network)
|
||||
go logic.DeleteDefaultNetworkPolicies(models.NetworkID(network))
|
||||
//delete network from allocated ip map
|
||||
if servercfg.CacheEnabled() {
|
||||
go logic.RemoveNetworkFromAllocatedIpMap(network)
|
||||
}
|
||||
|
||||
logger.Log(1, r.Header.Get("user"), "deleted network", network)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
@@ -534,7 +536,7 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
|
||||
logic.CreateDefaultNetworkRolesAndGroups(models.NetworkID(network.NetID))
|
||||
logic.CreateDefaultAclNetworkPolicies(models.NetworkID(network.NetID))
|
||||
logic.CreateDefaultTags(models.NetworkID(network.NetID))
|
||||
//add new network to allocated ip map
|
||||
|
||||
go logic.AddNetworkToAllocatedIpMap(network.NetID)
|
||||
|
||||
go func() {
|
||||
|
@@ -105,14 +105,14 @@ func DeleteExtClient(network string, clientid string) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
//recycle ip address
|
||||
if servercfg.CacheEnabled() {
|
||||
// recycle ip address
|
||||
if extClient.Address != "" {
|
||||
RemoveIpFromAllocatedIpMap(network, extClient.Address)
|
||||
}
|
||||
if extClient.Address6 != "" {
|
||||
RemoveIpFromAllocatedIpMap(network, extClient.Address6)
|
||||
}
|
||||
if servercfg.CacheEnabled() {
|
||||
deleteExtClientFromCache(key)
|
||||
}
|
||||
return nil
|
||||
@@ -342,7 +342,6 @@ func SaveExtClient(extclient *models.ExtClient) error {
|
||||
}
|
||||
if servercfg.CacheEnabled() {
|
||||
storeExtClientInCache(key, *extclient)
|
||||
}
|
||||
if _, ok := allocatedIpMap[extclient.Network]; ok {
|
||||
if extclient.Address != "" {
|
||||
AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(extclient.Address))
|
||||
@@ -351,6 +350,8 @@ func SaveExtClient(extclient *models.ExtClient) error {
|
||||
AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(extclient.Address6))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return SetNetworkNodesLastModified(extclient.Network)
|
||||
}
|
||||
|
||||
|
@@ -30,6 +30,9 @@ var (
|
||||
|
||||
// SetAllocatedIpMap - set allocated ip map for networks
|
||||
func SetAllocatedIpMap() error {
|
||||
if !servercfg.CacheEnabled() {
|
||||
return nil
|
||||
}
|
||||
logger.Log(0, "start setting up allocated ip map")
|
||||
if allocatedIpMap == nil {
|
||||
allocatedIpMap = map[string]map[string]net.IP{}
|
||||
@@ -84,16 +87,25 @@ func SetAllocatedIpMap() error {
|
||||
|
||||
// ClearAllocatedIpMap - set allocatedIpMap to nil
|
||||
func ClearAllocatedIpMap() {
|
||||
if !servercfg.CacheEnabled() {
|
||||
return
|
||||
}
|
||||
allocatedIpMap = nil
|
||||
}
|
||||
|
||||
func AddIpToAllocatedIpMap(networkName string, ip net.IP) {
|
||||
if !servercfg.CacheEnabled() {
|
||||
return
|
||||
}
|
||||
networkCacheMutex.Lock()
|
||||
allocatedIpMap[networkName][ip.String()] = ip
|
||||
networkCacheMutex.Unlock()
|
||||
}
|
||||
|
||||
func RemoveIpFromAllocatedIpMap(networkName string, ip string) {
|
||||
if !servercfg.CacheEnabled() {
|
||||
return
|
||||
}
|
||||
networkCacheMutex.Lock()
|
||||
delete(allocatedIpMap[networkName], ip)
|
||||
networkCacheMutex.Unlock()
|
||||
@@ -101,6 +113,10 @@ func RemoveIpFromAllocatedIpMap(networkName string, ip string) {
|
||||
|
||||
// AddNetworkToAllocatedIpMap - add network to allocated ip map when network is added
|
||||
func AddNetworkToAllocatedIpMap(networkName string) {
|
||||
//add new network to allocated ip map
|
||||
if !servercfg.CacheEnabled() {
|
||||
return
|
||||
}
|
||||
networkCacheMutex.Lock()
|
||||
allocatedIpMap[networkName] = map[string]net.IP{}
|
||||
networkCacheMutex.Unlock()
|
||||
@@ -108,6 +124,9 @@ func AddNetworkToAllocatedIpMap(networkName string) {
|
||||
|
||||
// RemoveNetworkFromAllocatedIpMap - remove network from allocated ip map when network is deleted
|
||||
func RemoveNetworkFromAllocatedIpMap(networkName string) {
|
||||
if !servercfg.CacheEnabled() {
|
||||
return
|
||||
}
|
||||
networkCacheMutex.Lock()
|
||||
delete(allocatedIpMap, networkName)
|
||||
networkCacheMutex.Unlock()
|
||||
@@ -326,7 +345,7 @@ func GetNetworkSettings(networkname string) (models.Network, error) {
|
||||
}
|
||||
|
||||
// UniqueAddress - get a unique ipv4 address
|
||||
func UniqueAddress(networkName string, reverse bool) (net.IP, error) {
|
||||
func UniqueAddressCache(networkName string, reverse bool) (net.IP, error) {
|
||||
add := net.IP{}
|
||||
var network models.Network
|
||||
network, err := GetParentNetwork(networkName)
|
||||
@@ -368,6 +387,49 @@ func UniqueAddress(networkName string, reverse bool) (net.IP, error) {
|
||||
return add, errors.New("ERROR: No unique addresses available. Check network subnet")
|
||||
}
|
||||
|
||||
// UniqueAddress - get a unique ipv4 address
|
||||
func UniqueAddressDB(networkName string, reverse bool) (net.IP, error) {
|
||||
add := net.IP{}
|
||||
var network models.Network
|
||||
network, err := GetParentNetwork(networkName)
|
||||
if err != nil {
|
||||
logger.Log(0, "UniqueAddressServer encountered an error")
|
||||
return add, err
|
||||
}
|
||||
|
||||
if network.IsIPv4 == "no" {
|
||||
return add, fmt.Errorf("IPv4 not active on network " + networkName)
|
||||
}
|
||||
//ensure AddressRange is valid
|
||||
if _, _, err := net.ParseCIDR(network.AddressRange); err != nil {
|
||||
logger.Log(0, "UniqueAddress encountered an error")
|
||||
return add, err
|
||||
}
|
||||
net4 := iplib.Net4FromStr(network.AddressRange)
|
||||
newAddrs := net4.FirstAddress()
|
||||
|
||||
if reverse {
|
||||
newAddrs = net4.LastAddress()
|
||||
}
|
||||
|
||||
for {
|
||||
if IsIPUnique(networkName, newAddrs.String(), database.NODES_TABLE_NAME, false) &&
|
||||
IsIPUnique(networkName, newAddrs.String(), database.EXT_CLIENT_TABLE_NAME, false) {
|
||||
return newAddrs, nil
|
||||
}
|
||||
if reverse {
|
||||
newAddrs, err = net4.PreviousIP(newAddrs)
|
||||
} else {
|
||||
newAddrs, err = net4.NextIP(newAddrs)
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return add, errors.New("ERROR: No unique addresses available. Check network subnet")
|
||||
}
|
||||
|
||||
// IsIPUnique - checks if an IP is unique
|
||||
func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
|
||||
|
||||
@@ -411,9 +473,67 @@ func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
|
||||
|
||||
return isunique
|
||||
}
|
||||
func UniqueAddress(networkName string, reverse bool) (net.IP, error) {
|
||||
if servercfg.CacheEnabled() {
|
||||
return UniqueAddressCache(networkName, reverse)
|
||||
}
|
||||
return UniqueAddressDB(networkName, reverse)
|
||||
}
|
||||
|
||||
// UniqueAddress6 - see if ipv6 address is unique
|
||||
func UniqueAddress6(networkName string, reverse bool) (net.IP, error) {
|
||||
if servercfg.CacheEnabled() {
|
||||
return UniqueAddress6Cache(networkName, reverse)
|
||||
}
|
||||
return UniqueAddress6DB(networkName, reverse)
|
||||
}
|
||||
|
||||
// UniqueAddress6DB - see if ipv6 address is unique
|
||||
func UniqueAddress6DB(networkName string, reverse bool) (net.IP, error) {
|
||||
add := net.IP{}
|
||||
var network models.Network
|
||||
network, err := GetParentNetwork(networkName)
|
||||
if err != nil {
|
||||
fmt.Println("Network Not Found")
|
||||
return add, err
|
||||
}
|
||||
if network.IsIPv6 == "no" {
|
||||
return add, fmt.Errorf("IPv6 not active on network " + networkName)
|
||||
}
|
||||
|
||||
//ensure AddressRange is valid
|
||||
if _, _, err := net.ParseCIDR(network.AddressRange6); err != nil {
|
||||
return add, err
|
||||
}
|
||||
net6 := iplib.Net6FromStr(network.AddressRange6)
|
||||
|
||||
newAddrs, err := net6.NextIP(net6.FirstAddress())
|
||||
if reverse {
|
||||
newAddrs, err = net6.PreviousIP(net6.LastAddress())
|
||||
}
|
||||
if err != nil {
|
||||
return add, err
|
||||
}
|
||||
|
||||
for {
|
||||
if IsIPUnique(networkName, newAddrs.String(), database.NODES_TABLE_NAME, true) &&
|
||||
IsIPUnique(networkName, newAddrs.String(), database.EXT_CLIENT_TABLE_NAME, true) {
|
||||
return newAddrs, nil
|
||||
}
|
||||
if reverse {
|
||||
newAddrs, err = net6.PreviousIP(newAddrs)
|
||||
} else {
|
||||
newAddrs, err = net6.NextIP(newAddrs)
|
||||
}
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return add, errors.New("ERROR: No unique IPv6 addresses available. Check network subnet")
|
||||
}
|
||||
|
||||
// UniqueAddress6Cache - see if ipv6 address is unique using cache
|
||||
func UniqueAddress6Cache(networkName string, reverse bool) (net.IP, error) {
|
||||
add := net.IP{}
|
||||
var network models.Network
|
||||
network, err := GetParentNetwork(networkName)
|
||||
|
@@ -364,12 +364,15 @@ func DeleteNodeByID(node *models.Node) error {
|
||||
logger.Log(1, "unable to remove metrics from DB for node", node.ID.String(), err.Error())
|
||||
}
|
||||
//recycle ip address
|
||||
if servercfg.CacheEnabled() {
|
||||
if node.Address.IP != nil {
|
||||
RemoveIpFromAllocatedIpMap(node.Network, node.Address.IP.String())
|
||||
}
|
||||
if node.Address6.IP != nil {
|
||||
RemoveIpFromAllocatedIpMap(node.Network, node.Address6.IP.String())
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -694,7 +697,6 @@ func createNode(node *models.Node) error {
|
||||
if servercfg.CacheEnabled() {
|
||||
storeNodeInCache(*node)
|
||||
storeNodeInNetworkCache(*node, node.Network)
|
||||
}
|
||||
if _, ok := allocatedIpMap[node.Network]; ok {
|
||||
if node.Address.IP != nil {
|
||||
AddIpToAllocatedIpMap(node.Network, node.Address.IP)
|
||||
@@ -703,6 +705,8 @@ func createNode(node *models.Node) error {
|
||||
AddIpToAllocatedIpMap(node.Network, node.Address6.IP)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), defaultACLVal)
|
||||
if err != nil {
|
||||
logger.Log(1, "failed to create node ACL for node,", node.ID.String(), "err:", err.Error())
|
||||
@@ -748,16 +752,14 @@ func ValidateParams(nodeid, netid string) (models.Node, error) {
|
||||
func ValidateNodeIp(currentNode *models.Node, newNode *models.ApiNode) error {
|
||||
|
||||
if currentNode.Address.IP != nil && currentNode.Address.String() != newNode.Address {
|
||||
newIp, _, _ := net.ParseCIDR(newNode.Address)
|
||||
ipAllocated := allocatedIpMap[currentNode.Network]
|
||||
if _, ok := ipAllocated[newIp.String()]; ok {
|
||||
if !IsIPUnique(newNode.Network, newNode.Address, database.NODES_TABLE_NAME, false) ||
|
||||
!IsIPUnique(newNode.Network, newNode.Address, database.EXT_CLIENT_TABLE_NAME, false) {
|
||||
return errors.New("ip specified is already allocated: " + newNode.Address)
|
||||
}
|
||||
}
|
||||
if currentNode.Address6.IP != nil && currentNode.Address6.String() != newNode.Address6 {
|
||||
newIp, _, _ := net.ParseCIDR(newNode.Address6)
|
||||
ipAllocated := allocatedIpMap[currentNode.Network]
|
||||
if _, ok := ipAllocated[newIp.String()]; ok {
|
||||
if !IsIPUnique(newNode.Network, newNode.Address6, database.NODES_TABLE_NAME, false) ||
|
||||
!IsIPUnique(newNode.Network, newNode.Address6, database.EXT_CLIENT_TABLE_NAME, false) {
|
||||
return errors.New("ip specified is already allocated: " + newNode.Address6)
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user