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.DeleteNetworkRoles(network)
|
||||||
go logic.DeleteDefaultNetworkPolicies(models.NetworkID(network))
|
go logic.DeleteDefaultNetworkPolicies(models.NetworkID(network))
|
||||||
//delete network from allocated ip map
|
//delete network from allocated ip map
|
||||||
|
if servercfg.CacheEnabled() {
|
||||||
go logic.RemoveNetworkFromAllocatedIpMap(network)
|
go logic.RemoveNetworkFromAllocatedIpMap(network)
|
||||||
|
}
|
||||||
|
|
||||||
logger.Log(1, r.Header.Get("user"), "deleted network", network)
|
logger.Log(1, r.Header.Get("user"), "deleted network", network)
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
@@ -534,7 +536,7 @@ func createNetwork(w http.ResponseWriter, r *http.Request) {
|
|||||||
logic.CreateDefaultNetworkRolesAndGroups(models.NetworkID(network.NetID))
|
logic.CreateDefaultNetworkRolesAndGroups(models.NetworkID(network.NetID))
|
||||||
logic.CreateDefaultAclNetworkPolicies(models.NetworkID(network.NetID))
|
logic.CreateDefaultAclNetworkPolicies(models.NetworkID(network.NetID))
|
||||||
logic.CreateDefaultTags(models.NetworkID(network.NetID))
|
logic.CreateDefaultTags(models.NetworkID(network.NetID))
|
||||||
//add new network to allocated ip map
|
|
||||||
go logic.AddNetworkToAllocatedIpMap(network.NetID)
|
go logic.AddNetworkToAllocatedIpMap(network.NetID)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
@@ -105,6 +105,7 @@ func DeleteExtClient(network string, clientid string) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
if servercfg.CacheEnabled() {
|
||||||
// recycle ip address
|
// recycle ip address
|
||||||
if extClient.Address != "" {
|
if extClient.Address != "" {
|
||||||
RemoveIpFromAllocatedIpMap(network, extClient.Address)
|
RemoveIpFromAllocatedIpMap(network, extClient.Address)
|
||||||
@@ -112,7 +113,6 @@ func DeleteExtClient(network string, clientid string) error {
|
|||||||
if extClient.Address6 != "" {
|
if extClient.Address6 != "" {
|
||||||
RemoveIpFromAllocatedIpMap(network, extClient.Address6)
|
RemoveIpFromAllocatedIpMap(network, extClient.Address6)
|
||||||
}
|
}
|
||||||
if servercfg.CacheEnabled() {
|
|
||||||
deleteExtClientFromCache(key)
|
deleteExtClientFromCache(key)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
@@ -342,7 +342,6 @@ func SaveExtClient(extclient *models.ExtClient) error {
|
|||||||
}
|
}
|
||||||
if servercfg.CacheEnabled() {
|
if servercfg.CacheEnabled() {
|
||||||
storeExtClientInCache(key, *extclient)
|
storeExtClientInCache(key, *extclient)
|
||||||
}
|
|
||||||
if _, ok := allocatedIpMap[extclient.Network]; ok {
|
if _, ok := allocatedIpMap[extclient.Network]; ok {
|
||||||
if extclient.Address != "" {
|
if extclient.Address != "" {
|
||||||
AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(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))
|
AddIpToAllocatedIpMap(extclient.Network, net.ParseIP(extclient.Address6))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return SetNetworkNodesLastModified(extclient.Network)
|
return SetNetworkNodesLastModified(extclient.Network)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -30,6 +30,9 @@ var (
|
|||||||
|
|
||||||
// SetAllocatedIpMap - set allocated ip map for networks
|
// SetAllocatedIpMap - set allocated ip map for networks
|
||||||
func SetAllocatedIpMap() error {
|
func SetAllocatedIpMap() error {
|
||||||
|
if !servercfg.CacheEnabled() {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
logger.Log(0, "start setting up allocated ip map")
|
logger.Log(0, "start setting up allocated ip map")
|
||||||
if allocatedIpMap == nil {
|
if allocatedIpMap == nil {
|
||||||
allocatedIpMap = map[string]map[string]net.IP{}
|
allocatedIpMap = map[string]map[string]net.IP{}
|
||||||
@@ -84,16 +87,25 @@ func SetAllocatedIpMap() error {
|
|||||||
|
|
||||||
// ClearAllocatedIpMap - set allocatedIpMap to nil
|
// ClearAllocatedIpMap - set allocatedIpMap to nil
|
||||||
func ClearAllocatedIpMap() {
|
func ClearAllocatedIpMap() {
|
||||||
|
if !servercfg.CacheEnabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
allocatedIpMap = nil
|
allocatedIpMap = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func AddIpToAllocatedIpMap(networkName string, ip net.IP) {
|
func AddIpToAllocatedIpMap(networkName string, ip net.IP) {
|
||||||
|
if !servercfg.CacheEnabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
networkCacheMutex.Lock()
|
networkCacheMutex.Lock()
|
||||||
allocatedIpMap[networkName][ip.String()] = ip
|
allocatedIpMap[networkName][ip.String()] = ip
|
||||||
networkCacheMutex.Unlock()
|
networkCacheMutex.Unlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
func RemoveIpFromAllocatedIpMap(networkName string, ip string) {
|
func RemoveIpFromAllocatedIpMap(networkName string, ip string) {
|
||||||
|
if !servercfg.CacheEnabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
networkCacheMutex.Lock()
|
networkCacheMutex.Lock()
|
||||||
delete(allocatedIpMap[networkName], ip)
|
delete(allocatedIpMap[networkName], ip)
|
||||||
networkCacheMutex.Unlock()
|
networkCacheMutex.Unlock()
|
||||||
@@ -101,6 +113,10 @@ func RemoveIpFromAllocatedIpMap(networkName string, ip string) {
|
|||||||
|
|
||||||
// AddNetworkToAllocatedIpMap - add network to allocated ip map when network is added
|
// AddNetworkToAllocatedIpMap - add network to allocated ip map when network is added
|
||||||
func AddNetworkToAllocatedIpMap(networkName string) {
|
func AddNetworkToAllocatedIpMap(networkName string) {
|
||||||
|
//add new network to allocated ip map
|
||||||
|
if !servercfg.CacheEnabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
networkCacheMutex.Lock()
|
networkCacheMutex.Lock()
|
||||||
allocatedIpMap[networkName] = map[string]net.IP{}
|
allocatedIpMap[networkName] = map[string]net.IP{}
|
||||||
networkCacheMutex.Unlock()
|
networkCacheMutex.Unlock()
|
||||||
@@ -108,6 +124,9 @@ func AddNetworkToAllocatedIpMap(networkName string) {
|
|||||||
|
|
||||||
// RemoveNetworkFromAllocatedIpMap - remove network from allocated ip map when network is deleted
|
// RemoveNetworkFromAllocatedIpMap - remove network from allocated ip map when network is deleted
|
||||||
func RemoveNetworkFromAllocatedIpMap(networkName string) {
|
func RemoveNetworkFromAllocatedIpMap(networkName string) {
|
||||||
|
if !servercfg.CacheEnabled() {
|
||||||
|
return
|
||||||
|
}
|
||||||
networkCacheMutex.Lock()
|
networkCacheMutex.Lock()
|
||||||
delete(allocatedIpMap, networkName)
|
delete(allocatedIpMap, networkName)
|
||||||
networkCacheMutex.Unlock()
|
networkCacheMutex.Unlock()
|
||||||
@@ -326,7 +345,7 @@ func GetNetworkSettings(networkname string) (models.Network, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// UniqueAddress - get a unique ipv4 address
|
// 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{}
|
add := net.IP{}
|
||||||
var network models.Network
|
var network models.Network
|
||||||
network, err := GetParentNetwork(networkName)
|
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")
|
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
|
// IsIPUnique - checks if an IP is unique
|
||||||
func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool {
|
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
|
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) {
|
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{}
|
add := net.IP{}
|
||||||
var network models.Network
|
var network models.Network
|
||||||
network, err := GetParentNetwork(networkName)
|
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())
|
logger.Log(1, "unable to remove metrics from DB for node", node.ID.String(), err.Error())
|
||||||
}
|
}
|
||||||
//recycle ip address
|
//recycle ip address
|
||||||
|
if servercfg.CacheEnabled() {
|
||||||
if node.Address.IP != nil {
|
if node.Address.IP != nil {
|
||||||
RemoveIpFromAllocatedIpMap(node.Network, node.Address.IP.String())
|
RemoveIpFromAllocatedIpMap(node.Network, node.Address.IP.String())
|
||||||
}
|
}
|
||||||
if node.Address6.IP != nil {
|
if node.Address6.IP != nil {
|
||||||
RemoveIpFromAllocatedIpMap(node.Network, node.Address6.IP.String())
|
RemoveIpFromAllocatedIpMap(node.Network, node.Address6.IP.String())
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -694,7 +697,6 @@ func createNode(node *models.Node) error {
|
|||||||
if servercfg.CacheEnabled() {
|
if servercfg.CacheEnabled() {
|
||||||
storeNodeInCache(*node)
|
storeNodeInCache(*node)
|
||||||
storeNodeInNetworkCache(*node, node.Network)
|
storeNodeInNetworkCache(*node, node.Network)
|
||||||
}
|
|
||||||
if _, ok := allocatedIpMap[node.Network]; ok {
|
if _, ok := allocatedIpMap[node.Network]; ok {
|
||||||
if node.Address.IP != nil {
|
if node.Address.IP != nil {
|
||||||
AddIpToAllocatedIpMap(node.Network, node.Address.IP)
|
AddIpToAllocatedIpMap(node.Network, node.Address.IP)
|
||||||
@@ -703,6 +705,8 @@ func createNode(node *models.Node) error {
|
|||||||
AddIpToAllocatedIpMap(node.Network, node.Address6.IP)
|
AddIpToAllocatedIpMap(node.Network, node.Address6.IP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), defaultACLVal)
|
_, err = nodeacls.CreateNodeACL(nodeacls.NetworkID(node.Network), nodeacls.NodeID(node.ID.String()), defaultACLVal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Log(1, "failed to create node ACL for node,", node.ID.String(), "err:", err.Error())
|
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 {
|
func ValidateNodeIp(currentNode *models.Node, newNode *models.ApiNode) error {
|
||||||
|
|
||||||
if currentNode.Address.IP != nil && currentNode.Address.String() != newNode.Address {
|
if currentNode.Address.IP != nil && currentNode.Address.String() != newNode.Address {
|
||||||
newIp, _, _ := net.ParseCIDR(newNode.Address)
|
if !IsIPUnique(newNode.Network, newNode.Address, database.NODES_TABLE_NAME, false) ||
|
||||||
ipAllocated := allocatedIpMap[currentNode.Network]
|
!IsIPUnique(newNode.Network, newNode.Address, database.EXT_CLIENT_TABLE_NAME, false) {
|
||||||
if _, ok := ipAllocated[newIp.String()]; ok {
|
|
||||||
return errors.New("ip specified is already allocated: " + newNode.Address)
|
return errors.New("ip specified is already allocated: " + newNode.Address)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if currentNode.Address6.IP != nil && currentNode.Address6.String() != newNode.Address6 {
|
if currentNode.Address6.IP != nil && currentNode.Address6.String() != newNode.Address6 {
|
||||||
newIp, _, _ := net.ParseCIDR(newNode.Address6)
|
if !IsIPUnique(newNode.Network, newNode.Address6, database.NODES_TABLE_NAME, false) ||
|
||||||
ipAllocated := allocatedIpMap[currentNode.Network]
|
!IsIPUnique(newNode.Network, newNode.Address6, database.EXT_CLIENT_TABLE_NAME, false) {
|
||||||
if _, ok := ipAllocated[newIp.String()]; ok {
|
|
||||||
return errors.New("ip specified is already allocated: " + newNode.Address6)
|
return errors.New("ip specified is already allocated: " + newNode.Address6)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user