2
0
Эх сурвалжийг харах

fix network ip allocation in HA

abhishek9686 6 сар өмнө
parent
commit
ce6ec25253
4 өөрчлөгдсөн 161 нэмэгдсэн , 36 устгасан
  1. 4 2
      controllers/network.go
  2. 15 14
      logic/extpeers.go
  3. 122 2
      logic/networks.go
  4. 20 18
      logic/nodes.go

+ 4 - 2
controllers/network.go

@@ -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
-	go logic.RemoveNetworkFromAllocatedIpMap(network)
+	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() {

+ 15 - 14
logic/extpeers.go

@@ -105,14 +105,14 @@ func DeleteExtClient(network string, clientid string) error {
 	if err != nil {
 		return err
 	}
-	//recycle ip address
-	if extClient.Address != "" {
-		RemoveIpFromAllocatedIpMap(network, extClient.Address)
-	}
-	if extClient.Address6 != "" {
-		RemoveIpFromAllocatedIpMap(network, extClient.Address6)
-	}
 	if servercfg.CacheEnabled() {
+		// recycle ip address
+		if extClient.Address != "" {
+			RemoveIpFromAllocatedIpMap(network, extClient.Address)
+		}
+		if extClient.Address6 != "" {
+			RemoveIpFromAllocatedIpMap(network, extClient.Address6)
+		}
 		deleteExtClientFromCache(key)
 	}
 	return nil
@@ -342,15 +342,16 @@ 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))
-		}
-		if extclient.Address6 != "" {
-			AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(extclient.Address6))
+		if _, ok := allocatedIpMap[extclient.Network]; ok {
+			if extclient.Address != "" {
+				AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(extclient.Address))
+			}
+			if extclient.Address6 != "" {
+				AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(extclient.Address6))
+			}
 		}
 	}
+
 	return SetNetworkNodesLastModified(extclient.Network)
 }
 

+ 122 - 2
logic/networks.go

@@ -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)

+ 20 - 18
logic/nodes.go

@@ -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 node.Address.IP != nil {
-		RemoveIpFromAllocatedIpMap(node.Network, node.Address.IP.String())
-	}
-	if node.Address6.IP != nil {
-		RemoveIpFromAllocatedIpMap(node.Network, node.Address6.IP.String())
+	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,15 +697,16 @@ 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)
-		}
-		if node.Address6.IP != nil {
-			AddIpToAllocatedIpMap(node.Network, node.Address6.IP)
+		if _, ok := allocatedIpMap[node.Network]; ok {
+			if node.Address.IP != nil {
+				AddIpToAllocatedIpMap(node.Network, node.Address.IP)
+			}
+			if node.Address6.IP != nil {
+				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)
 		}
 	}