From 637f840a81453a26e99435aebf301be97ee0e09c Mon Sep 17 00:00:00 2001 From: Tobias Cudnik Date: Fri, 16 Jun 2023 15:46:23 +0200 Subject: [PATCH 01/11] Update common.go --- logic/acls/common.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/logic/acls/common.go b/logic/acls/common.go index 79d1bd67..58693de6 100644 --- a/logic/acls/common.go +++ b/logic/acls/common.go @@ -52,6 +52,22 @@ func (aclContainer ACLContainer) RemoveACL(ID AclID) ACLContainer { // ACLContainer.ChangeAccess - changes the relationship between two nodes in memory func (networkACL ACLContainer) ChangeAccess(ID1, ID2 AclID, value byte) { + if _, ok := networkACL[ID1]; !ok { + slog.Error("ACL missing for ", "id", ID1) + return + } + if _, ok := networkACL[ID2]; !ok { + slog.Error("ACL missing for ", "id", ID2) + return + } + if _, ok := networkACL[ID1][ID2]; !ok { + slog.Error("ACL missing for ", "id1", ID1, "id2", ID2) + return + } + if _, ok := networkACL[ID2][ID1]; !ok { + slog.Error("ACL missing for ", "id2", ID2, "id1", ID1) + return + } networkACL[ID1][ID2] = value networkACL[ID2][ID1] = value } From 59da2698a584bd9d0ed4c7c587fc4be6a32d29dc Mon Sep 17 00:00:00 2001 From: Tobias Cudnik Date: Fri, 16 Jun 2023 15:48:53 +0200 Subject: [PATCH 02/11] Update common.go --- logic/acls/common.go | 1 + 1 file changed, 1 insertion(+) diff --git a/logic/acls/common.go b/logic/acls/common.go index 58693de6..554cade7 100644 --- a/logic/acls/common.go +++ b/logic/acls/common.go @@ -4,6 +4,7 @@ import ( "encoding/json" "github.com/gravitl/netmaker/database" + "golang.org/x/exp/slog" ) // == type functions == From 4071bb2bac07dd7504e639ede295c5e533ac7d6a Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Mon, 26 Jun 2023 01:40:28 +0530 Subject: [PATCH 03/11] db cache nodes and hosts --- controllers/node_test.go | 1 + logic/dns.go | 8 +- logic/extpeers.go | 8 +- logic/gateway.go | 27 +------ logic/hosts.go | 106 +++++++++++++++++++++---- logic/networks.go | 163 +-------------------------------------- logic/nodes.go | 121 ++++++++++++++++++----------- logic/relay.go | 31 +------- 8 files changed, 180 insertions(+), 285 deletions(-) diff --git a/controllers/node_test.go b/controllers/node_test.go index d4519f44..ba877276 100644 --- a/controllers/node_test.go +++ b/controllers/node_test.go @@ -217,6 +217,7 @@ func TestNodeACLs(t *testing.T) { } func deleteAllNodes() { + logic.ClearNodeCache() database.DeleteAllRecords(database.NODES_TABLE_NAME) } diff --git a/logic/dns.go b/logic/dns.go index 146a72fe..0991c8ce 100644 --- a/logic/dns.go +++ b/logic/dns.go @@ -69,16 +69,12 @@ func GetNodeDNS(network string) ([]models.DNSEntry, error) { var dns []models.DNSEntry - collection, err := database.FetchRecords(database.NODES_TABLE_NAME) + nodes, err := GetNetworkNodes(network) if err != nil { return dns, err } - for _, value := range collection { - var node models.Node - if err = json.Unmarshal([]byte(value), &node); err != nil { - continue - } + for _, node := range nodes { if node.Network != network { continue } diff --git a/logic/extpeers.go b/logic/extpeers.go index 928e1cde..f5f1c4ef 100644 --- a/logic/extpeers.go +++ b/logic/extpeers.go @@ -46,15 +46,11 @@ func GetExtPeersList(node *models.Node) ([]models.ExtPeersResponse, error) { func GetEgressRangesOnNetwork(client *models.ExtClient) ([]string, error) { var result []string - nodesData, err := database.FetchRecords(database.NODES_TABLE_NAME) + networkNodes, err := GetNetworkNodes(client.Network) if err != nil { return []string{}, err } - for _, nodeData := range nodesData { - var currentNode models.Node - if err = json.Unmarshal([]byte(nodeData), ¤tNode); err != nil { - continue - } + for _, currentNode := range networkNodes { if currentNode.Network != client.Network { continue } diff --git a/logic/gateway.go b/logic/gateway.go index 556b108b..083092ee 100644 --- a/logic/gateway.go +++ b/logic/gateway.go @@ -1,7 +1,6 @@ package logic import ( - "encoding/json" "errors" "fmt" "time" @@ -53,11 +52,7 @@ func CreateEgressGateway(gateway models.EgressGatewayRequest) (models.Node, erro node.EgressGatewayNatEnabled = models.ParseBool(gateway.NatEnabled) node.EgressGatewayRequest = gateway // store entire request for use when preserving the egress gateway node.SetLastModified() - nodeData, err := json.Marshal(&node) - if err != nil { - return node, err - } - if err = database.Insert(node.ID.String(), string(nodeData), database.NODES_TABLE_NAME); err != nil { + if err = UpsertNode(&node); err != nil { return models.Node{}, err } return node, nil @@ -84,12 +79,7 @@ func DeleteEgressGateway(network, nodeid string) (models.Node, error) { node.EgressGatewayRanges = []string{} node.EgressGatewayRequest = models.EgressGatewayRequest{} // remove preserved request as the egress gateway is gone node.SetLastModified() - - data, err := json.Marshal(&node) - if err != nil { - return models.Node{}, err - } - if err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME); err != nil { + if err = UpsertNode(&node); err != nil { return models.Node{}, err } return node, nil @@ -128,11 +118,7 @@ func CreateIngressGateway(netid string, nodeid string, ingress models.IngressReq if ingress.Failover && servercfg.Is_EE { node.Failover = true } - data, err := json.Marshal(&node) - if err != nil { - return models.Node{}, err - } - err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME) + err = UpsertNode(&node) if err != nil { return models.Node{}, err } @@ -173,12 +159,7 @@ func DeleteIngressGateway(networkName string, nodeid string) (models.Node, bool, node.EgressGatewayRequest.NodeID, node.EgressGatewayRequest.NetID, err)) } } - - data, err := json.Marshal(&node) - if err != nil { - return models.Node{}, false, removedClients, err - } - err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME) + err = UpsertNode(&node) if err != nil { return models.Node{}, wasFailover, removedClients, err } diff --git a/logic/hosts.go b/logic/hosts.go index 34fa9766..a360e03e 100644 --- a/logic/hosts.go +++ b/logic/hosts.go @@ -10,6 +10,7 @@ import ( "net/http" "sort" "strconv" + "sync" "github.com/devilcove/httpclient" "github.com/google/uuid" @@ -20,6 +21,11 @@ import ( "golang.org/x/crypto/bcrypt" ) +var ( + HostCacheMutex = &sync.RWMutex{} + HostsCacheMap = make(map[string]models.Host) +) + var ( // ErrHostExists error indicating that host exists when trying to create new host ErrHostExists error = errors.New("host already exists") @@ -27,6 +33,37 @@ var ( ErrInvalidHostID error = errors.New("invalid host id") ) +func GetHostsFromCache() (hostsMap map[string]models.Host) { + HostCacheMutex.RLock() + hostsMap = HostsCacheMap + HostCacheMutex.RUnlock() + return +} + +func GetHostFromCache(hostID string) (host models.Host, ok bool) { + HostCacheMutex.RLock() + host, ok = HostsCacheMap[hostID] + HostCacheMutex.RUnlock() + return +} + +func StoreHostInCache(h models.Host) { + HostCacheMutex.Lock() + HostsCacheMap[h.ID.String()] = h + HostCacheMutex.Unlock() +} + +func DeleteHostFromCache(hostID string) { + HostCacheMutex.Lock() + delete(HostsCacheMap, hostID) + HostCacheMutex.Unlock() +} +func LoadHostsIntoCache(hMap map[string]models.Host) { + HostCacheMutex.Lock() + HostsCacheMap = hMap + HostCacheMutex.Unlock() +} + const ( maxPort = 1<<16 - 1 minPort = 1025 @@ -34,17 +71,31 @@ const ( // GetAllHosts - returns all hosts in flat list or error func GetAllHosts() ([]models.Host, error) { - currHostMap, err := GetHostsMap() - if err != nil { + currHosts := []models.Host{} + hostsMap := GetHostsFromCache() + if len(hostsMap) != 0 { + for _, host := range hostsMap { + currHosts = append(currHosts, host) + } + return currHosts, nil + } + records, err := database.FetchRecords(database.HOSTS_TABLE_NAME) + if err != nil && !database.IsEmptyRecord(err) { return nil, err } - var currentHosts = []models.Host{} - for k := range currHostMap { - var h = *currHostMap[k] - currentHosts = append(currentHosts, h) + currHostsMap := make(map[string]models.Host) + defer LoadHostsIntoCache(currHostsMap) + for k := range records { + var h models.Host + err = json.Unmarshal([]byte(records[k]), &h) + if err != nil { + return nil, err + } + currHosts = append(currHosts, h) + currHostsMap[h.ID.String()] = h } - return currentHosts, nil + return currHosts, nil } // GetAllHostsAPI - get's all the hosts in an API usable format @@ -58,19 +109,24 @@ func GetAllHostsAPI(hosts []models.Host) []models.ApiHost { } // GetHostsMap - gets all the current hosts on machine in a map -func GetHostsMap() (map[string]*models.Host, error) { +func GetHostsMap() (map[string]models.Host, error) { + hostsMap := GetHostsFromCache() + if len(hostsMap) != 0 { + return hostsMap, nil + } records, err := database.FetchRecords(database.HOSTS_TABLE_NAME) if err != nil && !database.IsEmptyRecord(err) { return nil, err } - currHostMap := make(map[string]*models.Host) + currHostMap := make(map[string]models.Host) + defer LoadHostsIntoCache(currHostMap) for k := range records { var h models.Host err = json.Unmarshal([]byte(records[k]), &h) if err != nil { return nil, err } - currHostMap[h.ID.String()] = &h + currHostMap[h.ID.String()] = h } return currHostMap, nil @@ -78,6 +134,10 @@ func GetHostsMap() (map[string]*models.Host, error) { // GetHost - gets a host from db given id func GetHost(hostid string) (*models.Host, error) { + + if host, ok := GetHostFromCache(hostid); ok { + return &host, nil + } record, err := database.FetchRecord(database.HOSTS_TABLE_NAME, hostid) if err != nil { return nil, err @@ -87,7 +147,7 @@ func GetHost(hostid string) (*models.Host, error) { if err = json.Unmarshal([]byte(record), &h); err != nil { return nil, err } - + StoreHostInCache(h) return &h, nil } @@ -215,8 +275,12 @@ func UpsertHost(h *models.Host) error { if err != nil { return err } - - return database.Insert(h.ID.String(), string(data), database.HOSTS_TABLE_NAME) + err = database.Insert(h.ID.String(), string(data), database.HOSTS_TABLE_NAME) + if err != nil { + return err + } + StoreHostInCache(*h) + return nil } // RemoveHost - removes a given host from server @@ -227,8 +291,12 @@ func RemoveHost(h *models.Host) error { if servercfg.IsUsingTurn() { DeRegisterHostWithTurn(h.ID.String()) } - - return database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String()) + err := database.DeleteRecord(database.HOSTS_TABLE_NAME, h.ID.String()) + if err != nil { + return err + } + DeleteHostFromCache(h.ID.String()) + return nil } // RemoveHostByID - removes a given host by id from server @@ -236,7 +304,13 @@ func RemoveHostByID(hostID string) error { if servercfg.IsUsingTurn() { DeRegisterHostWithTurn(hostID) } - return database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID) + + err := database.DeleteRecord(database.HOSTS_TABLE_NAME, hostID) + if err != nil { + return err + } + DeleteHostFromCache(hostID) + return nil } // UpdateHostNetwork - adds/deletes host from a network diff --git a/logic/networks.go b/logic/networks.go index ecdce22a..bd52bf2b 100644 --- a/logic/networks.go +++ b/logic/networks.go @@ -115,24 +115,8 @@ func CreateNetwork(network models.Network) (models.Network, error) { // GetNetworkNonServerNodeCount - get number of network non server nodes func GetNetworkNonServerNodeCount(networkName string) (int, error) { - - collection, err := database.FetchRecords(database.NODES_TABLE_NAME) - count := 0 - if err != nil && !database.IsEmptyRecord(err) { - return count, err - } - for _, value := range collection { - var node models.Node - if err = json.Unmarshal([]byte(value), &node); err != nil { - return count, err - } else { - if node.Network == networkName { - count++ - } - } - } - - return count, nil + nodes, err := GetNetworkNodes(networkName) + return len(nodes), err } // GetParentNetwork - get parent network @@ -298,149 +282,6 @@ func UniqueAddress6(networkName string, reverse bool) (net.IP, error) { return add, errors.New("ERROR: No unique IPv6 addresses available. Check network subnet") } -// UpdateNetworkLocalAddresses - updates network localaddresses -func UpdateNetworkLocalAddresses(networkName string) error { - - collection, err := database.FetchRecords(database.NODES_TABLE_NAME) - - if err != nil { - return err - } - - for _, value := range collection { - - var node models.Node - - err := json.Unmarshal([]byte(value), &node) - if err != nil { - fmt.Println("error in node address assignment!") - return err - } - if node.Network == networkName { - var ipaddr net.IP - var iperr error - ipaddr, iperr = UniqueAddress(networkName, false) - if iperr != nil { - fmt.Println("error in node address assignment!") - return iperr - } - - node.Address.IP = ipaddr - newNodeData, err := json.Marshal(&node) - if err != nil { - logger.Log(1, "error in node address assignment!") - return err - } - database.Insert(node.ID.String(), string(newNodeData), database.NODES_TABLE_NAME) - } - } - - return nil -} - -// RemoveNetworkNodeIPv6Addresses - removes network node IPv6 addresses -func RemoveNetworkNodeIPv6Addresses(networkName string) error { - - collections, err := database.FetchRecords(database.NODES_TABLE_NAME) - if err != nil { - return err - } - - for _, value := range collections { - - var node models.Node - err := json.Unmarshal([]byte(value), &node) - if err != nil { - fmt.Println("error in node address assignment!") - return err - } - if node.Network == networkName { - node.Address6.IP = nil - data, err := json.Marshal(&node) - if err != nil { - return err - } - database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME) - } - } - - return nil -} - -// UpdateNetworkNodeAddresses - updates network node addresses -func UpdateNetworkNodeAddresses(networkName string) error { - - collections, err := database.FetchRecords(database.NODES_TABLE_NAME) - if err != nil { - return err - } - - for _, value := range collections { - - var node models.Node - err := json.Unmarshal([]byte(value), &node) - if err != nil { - logger.Log(1, "error in node ipv4 address assignment!") - return err - } - if node.Network == networkName { - var ipaddr net.IP - var iperr error - ipaddr, iperr = UniqueAddress(networkName, false) - if iperr != nil { - logger.Log(1, "error in node ipv4 address assignment!") - return iperr - } - - node.Address.IP = ipaddr - data, err := json.Marshal(&node) - if err != nil { - return err - } - database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME) - } - } - - return nil -} - -// UpdateNetworkNodeAddresses6 - updates network node addresses -func UpdateNetworkNodeAddresses6(networkName string) error { - - collections, err := database.FetchRecords(database.NODES_TABLE_NAME) - if err != nil { - return err - } - - for _, value := range collections { - - var node models.Node - err := json.Unmarshal([]byte(value), &node) - if err != nil { - logger.Log(1, "error in node ipv6 address assignment!") - return err - } - if node.Network == networkName { - var ipaddr net.IP - var iperr error - ipaddr, iperr = UniqueAddress6(networkName, false) - if iperr != nil { - logger.Log(1, "error in node ipv6 address assignment!") - return iperr - } - - node.Address6.IP = ipaddr - data, err := json.Marshal(&node) - if err != nil { - return err - } - database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME) - } - } - - return nil -} - // IsNetworkNameUnique - checks to see if any other networks have the same name (id) func IsNetworkNameUnique(network *models.Network) (bool, error) { diff --git a/logic/nodes.go b/logic/nodes.go index 1becdb64..9956ed0c 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -6,6 +6,7 @@ import ( "fmt" "net" "sort" + "sync" "time" validator "github.com/go-playground/validator/v10" @@ -17,11 +18,51 @@ import ( "github.com/gravitl/netmaker/logic/pro" "github.com/gravitl/netmaker/logic/pro/proacls" "github.com/gravitl/netmaker/models" - "github.com/gravitl/netmaker/netclient/ncutils" "github.com/gravitl/netmaker/servercfg" "github.com/gravitl/netmaker/validation" ) +var ( + NodeCacheMutex = &sync.RWMutex{} + NodesCacheMap = make(map[string]models.Node) +) + +func GetNodeFromCache(nodeID string) (node models.Node, ok bool) { + NodeCacheMutex.RLock() + node, ok = NodesCacheMap[nodeID] + NodeCacheMutex.RUnlock() + return +} +func GetNodesFromCache() (nMap map[string]models.Node) { + NodeCacheMutex.RLock() + nMap = NodesCacheMap + NodeCacheMutex.RUnlock() + return +} + +func DeleteNodeFromCache(nodeID string) { + NodeCacheMutex.Lock() + delete(NodesCacheMap, nodeID) + NodeCacheMutex.Unlock() +} + +func StoreNodeInCache(node models.Node) { + NodeCacheMutex.Lock() + NodesCacheMap[node.ID.String()] = node + NodeCacheMutex.Unlock() +} + +func LoadNodesIntoCache(nMap map[string]models.Node) { + NodeCacheMutex.Lock() + NodesCacheMap = nMap + NodeCacheMutex.Unlock() +} +func ClearNodeCache() { + NodeCacheMutex.Lock() + NodesCacheMap = make(map[string]models.Node) + NodeCacheMutex.Unlock() +} + const ( // RELAY_NODE_ERR - error to return if relay node is unfound RELAY_NODE_ERR = "could not find relay for node" @@ -72,7 +113,12 @@ func UpdateNodeCheckin(node *models.Node) error { if err != nil { return err } - return database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME) + err = database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME) + if err != nil { + return err + } + StoreNodeInCache(*node) + return nil } // UpsertNode - updates node in the DB @@ -82,7 +128,12 @@ func UpsertNode(newNode *models.Node) error { if err != nil { return err } - return database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME) + err = database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME) + if err != nil { + return err + } + StoreNodeInCache(*newNode) + return nil } // UpdateNode - takes a node and updates another node with it's values @@ -114,7 +165,12 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error { if data, err := json.Marshal(newNode); err != nil { return err } else { - return database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME) + err = database.Insert(newNode.ID.String(), string(data), database.NODES_TABLE_NAME) + if err != nil { + return err + } + StoreNodeInCache(*newNode) + return nil } } @@ -172,6 +228,7 @@ func deleteNodeByID(node *models.Node) error { return err } } + DeleteNodeFromCache(node.ID.String()) if servercfg.IsDNSMode() { SetDNS() } @@ -237,7 +294,15 @@ func IsFailoverPresent(network string) bool { // GetAllNodes - returns all nodes in the DB func GetAllNodes() ([]models.Node, error) { var nodes []models.Node - + nodesMap := GetNodesFromCache() + if len(nodesMap) != 0 { + for _, node := range nodesMap { + nodes = append(nodes, node) + } + return nodes, nil + } + nodesMap = make(map[string]models.Node) + defer LoadNodesIntoCache(nodesMap) collection, err := database.FetchRecords(database.NODES_TABLE_NAME) if err != nil { if database.IsEmptyRecord(err) { @@ -255,6 +320,7 @@ func GetAllNodes() ([]models.Node, error) { } // add node to our array nodes = append(nodes, node) + nodesMap[node.ID.String()] = node } return nodes, nil @@ -309,46 +375,10 @@ func GetRecordKey(id string, network string) (string, error) { return id + "###" + network, nil } -// GetNodesByAddress - gets a node by mac address -func GetNodesByAddress(network string, addresses []string) ([]models.Node, error) { - var nodes []models.Node - allnodes, err := GetAllNodes() - if err != nil { - return []models.Node{}, err - } - for _, node := range allnodes { - if node.Network == network && ncutils.StringSliceContains(addresses, node.Address.String()) { - nodes = append(nodes, node) - } - } - return nodes, nil -} - -// GetDeletedNodeByMacAddress - get a deleted node -func GetDeletedNodeByMacAddress(network string, macaddress string) (models.Node, error) { - - var node models.Node - - key, err := GetRecordKey(macaddress, network) - if err != nil { - return node, err - } - - record, err := database.FetchRecord(database.DELETED_NODES_TABLE_NAME, key) - if err != nil { - return models.Node{}, err - } - - if err = json.Unmarshal([]byte(record), &node); err != nil { - return models.Node{}, err - } - - SetNodeDefaults(&node) - - return node, nil -} - func GetNodeByID(uuid string) (models.Node, error) { + if node, ok := GetNodeFromCache(uuid); ok { + return node, nil + } var record, err = database.FetchRecord(database.NODES_TABLE_NAME, uuid) if err != nil { return models.Node{}, err @@ -357,6 +387,7 @@ func GetNodeByID(uuid string) (models.Node, error) { if err = json.Unmarshal([]byte(record), &node); err != nil { return models.Node{}, err } + StoreNodeInCache(node) return node, nil } @@ -506,7 +537,7 @@ func createNode(node *models.Node) error { if err != nil { return err } - + StoreNodeInCache(*node) _, 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()) diff --git a/logic/relay.go b/logic/relay.go index 03b7eb33..4782c156 100644 --- a/logic/relay.go +++ b/logic/relay.go @@ -1,12 +1,10 @@ package logic import ( - "encoding/json" "errors" "fmt" "net" - "github.com/gravitl/netmaker/database" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" ) @@ -33,25 +31,11 @@ func CreateRelay(relay models.RelayRequest) ([]models.Node, models.Node, error) node.IsRelay = true node.RelayedNodes = relay.RelayedNodes node.SetLastModified() - nodeData, err := json.Marshal(&node) + err = UpsertNode(&node) if err != nil { return returnnodes, node, err } - if err = database.Insert(node.ID.String(), string(nodeData), database.NODES_TABLE_NAME); err != nil { - return returnnodes, models.Node{}, err - } returnnodes = SetRelayedNodes(true, relay.NodeID, relay.RelayedNodes) - for _, relayedNode := range returnnodes { - data, err := json.Marshal(&relayedNode) - if err != nil { - logger.Log(0, "marshalling relayed node", err.Error()) - continue - } - if err := database.Insert(relayedNode.ID.String(), string(data), database.NODES_TABLE_NAME); err != nil { - logger.Log(0, "inserting relayed node", err.Error()) - continue - } - } return returnnodes, node, nil } @@ -71,12 +55,7 @@ func SetRelayedNodes(setRelayed bool, relay string, relayed []string) []models.N node.RelayedBy = "" } node.SetLastModified() - data, err := json.Marshal(&node) - if err != nil { - logger.Log(0, "setRelayedNodes.Marshal", err.Error()) - continue - } - if err := database.Insert(node.ID.String(), string(data), database.NODES_TABLE_NAME); err != nil { + if err := UpsertNode(&node); err != nil { logger.Log(0, "setRelayedNodes.Insert", err.Error()) continue } @@ -145,11 +124,7 @@ func DeleteRelay(network, nodeid string) ([]models.Node, models.Node, error) { node.IsRelay = false node.RelayedNodes = []string{} node.SetLastModified() - data, err := json.Marshal(&node) - if err != nil { - return returnnodes, models.Node{}, err - } - if err = database.Insert(nodeid, string(data), database.NODES_TABLE_NAME); err != nil { + if err = UpsertNode(&node); err != nil { return returnnodes, models.Node{}, err } return returnnodes, node, nil From 307203105dfbec6fe5acd05933ed36d7b19b503e Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Mon, 26 Jun 2023 11:18:43 +0530 Subject: [PATCH 04/11] unexport cache funcs --- logic/hosts.go | 62 ++++++++++++++++++++++----------------------- logic/nodes.go | 68 +++++++++++++++++++++++++------------------------- 2 files changed, 65 insertions(+), 65 deletions(-) diff --git a/logic/hosts.go b/logic/hosts.go index a360e03e..ea6268cd 100644 --- a/logic/hosts.go +++ b/logic/hosts.go @@ -22,8 +22,8 @@ import ( ) var ( - HostCacheMutex = &sync.RWMutex{} - HostsCacheMap = make(map[string]models.Host) + hostCacheMutex = &sync.RWMutex{} + hostsCacheMap = make(map[string]models.Host) ) var ( @@ -33,35 +33,35 @@ var ( ErrInvalidHostID error = errors.New("invalid host id") ) -func GetHostsFromCache() (hostsMap map[string]models.Host) { - HostCacheMutex.RLock() - hostsMap = HostsCacheMap - HostCacheMutex.RUnlock() +func getHostsFromCache() (hostsMap map[string]models.Host) { + hostCacheMutex.RLock() + hostsMap = hostsCacheMap + hostCacheMutex.RUnlock() return } -func GetHostFromCache(hostID string) (host models.Host, ok bool) { - HostCacheMutex.RLock() - host, ok = HostsCacheMap[hostID] - HostCacheMutex.RUnlock() +func getHostFromCache(hostID string) (host models.Host, ok bool) { + hostCacheMutex.RLock() + host, ok = hostsCacheMap[hostID] + hostCacheMutex.RUnlock() return } -func StoreHostInCache(h models.Host) { - HostCacheMutex.Lock() - HostsCacheMap[h.ID.String()] = h - HostCacheMutex.Unlock() +func storeHostInCache(h models.Host) { + hostCacheMutex.Lock() + hostsCacheMap[h.ID.String()] = h + hostCacheMutex.Unlock() } -func DeleteHostFromCache(hostID string) { - HostCacheMutex.Lock() - delete(HostsCacheMap, hostID) - HostCacheMutex.Unlock() +func deleteHostFromCache(hostID string) { + hostCacheMutex.Lock() + delete(hostsCacheMap, hostID) + hostCacheMutex.Unlock() } -func LoadHostsIntoCache(hMap map[string]models.Host) { - HostCacheMutex.Lock() - HostsCacheMap = hMap - HostCacheMutex.Unlock() +func loadHostsIntoCache(hMap map[string]models.Host) { + hostCacheMutex.Lock() + hostsCacheMap = hMap + hostCacheMutex.Unlock() } const ( @@ -72,7 +72,7 @@ const ( // GetAllHosts - returns all hosts in flat list or error func GetAllHosts() ([]models.Host, error) { currHosts := []models.Host{} - hostsMap := GetHostsFromCache() + hostsMap := getHostsFromCache() if len(hostsMap) != 0 { for _, host := range hostsMap { currHosts = append(currHosts, host) @@ -84,7 +84,7 @@ func GetAllHosts() ([]models.Host, error) { return nil, err } currHostsMap := make(map[string]models.Host) - defer LoadHostsIntoCache(currHostsMap) + defer loadHostsIntoCache(currHostsMap) for k := range records { var h models.Host err = json.Unmarshal([]byte(records[k]), &h) @@ -110,7 +110,7 @@ func GetAllHostsAPI(hosts []models.Host) []models.ApiHost { // GetHostsMap - gets all the current hosts on machine in a map func GetHostsMap() (map[string]models.Host, error) { - hostsMap := GetHostsFromCache() + hostsMap := getHostsFromCache() if len(hostsMap) != 0 { return hostsMap, nil } @@ -119,7 +119,7 @@ func GetHostsMap() (map[string]models.Host, error) { return nil, err } currHostMap := make(map[string]models.Host) - defer LoadHostsIntoCache(currHostMap) + defer loadHostsIntoCache(currHostMap) for k := range records { var h models.Host err = json.Unmarshal([]byte(records[k]), &h) @@ -135,7 +135,7 @@ func GetHostsMap() (map[string]models.Host, error) { // GetHost - gets a host from db given id func GetHost(hostid string) (*models.Host, error) { - if host, ok := GetHostFromCache(hostid); ok { + if host, ok := getHostFromCache(hostid); ok { return &host, nil } record, err := database.FetchRecord(database.HOSTS_TABLE_NAME, hostid) @@ -147,7 +147,7 @@ func GetHost(hostid string) (*models.Host, error) { if err = json.Unmarshal([]byte(record), &h); err != nil { return nil, err } - StoreHostInCache(h) + storeHostInCache(h) return &h, nil } @@ -279,7 +279,7 @@ func UpsertHost(h *models.Host) error { if err != nil { return err } - StoreHostInCache(*h) + storeHostInCache(*h) return nil } @@ -295,7 +295,7 @@ func RemoveHost(h *models.Host) error { if err != nil { return err } - DeleteHostFromCache(h.ID.String()) + deleteHostFromCache(h.ID.String()) return nil } @@ -309,7 +309,7 @@ func RemoveHostByID(hostID string) error { if err != nil { return err } - DeleteHostFromCache(hostID) + deleteHostFromCache(hostID) return nil } diff --git a/logic/nodes.go b/logic/nodes.go index 9956ed0c..465f917e 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -23,44 +23,44 @@ import ( ) var ( - NodeCacheMutex = &sync.RWMutex{} - NodesCacheMap = make(map[string]models.Node) + nodeCacheMutex = &sync.RWMutex{} + nodesCacheMap = make(map[string]models.Node) ) -func GetNodeFromCache(nodeID string) (node models.Node, ok bool) { - NodeCacheMutex.RLock() - node, ok = NodesCacheMap[nodeID] - NodeCacheMutex.RUnlock() +func getNodeFromCache(nodeID string) (node models.Node, ok bool) { + nodeCacheMutex.RLock() + node, ok = nodesCacheMap[nodeID] + nodeCacheMutex.RUnlock() return } -func GetNodesFromCache() (nMap map[string]models.Node) { - NodeCacheMutex.RLock() - nMap = NodesCacheMap - NodeCacheMutex.RUnlock() +func getNodesFromCache() (nMap map[string]models.Node) { + nodeCacheMutex.RLock() + nMap = nodesCacheMap + nodeCacheMutex.RUnlock() return } -func DeleteNodeFromCache(nodeID string) { - NodeCacheMutex.Lock() - delete(NodesCacheMap, nodeID) - NodeCacheMutex.Unlock() +func deleteNodeFromCache(nodeID string) { + nodeCacheMutex.Lock() + delete(nodesCacheMap, nodeID) + nodeCacheMutex.Unlock() } -func StoreNodeInCache(node models.Node) { - NodeCacheMutex.Lock() - NodesCacheMap[node.ID.String()] = node - NodeCacheMutex.Unlock() +func storeNodeInCache(node models.Node) { + nodeCacheMutex.Lock() + nodesCacheMap[node.ID.String()] = node + nodeCacheMutex.Unlock() } -func LoadNodesIntoCache(nMap map[string]models.Node) { - NodeCacheMutex.Lock() - NodesCacheMap = nMap - NodeCacheMutex.Unlock() +func loadNodesIntoCache(nMap map[string]models.Node) { + nodeCacheMutex.Lock() + nodesCacheMap = nMap + nodeCacheMutex.Unlock() } func ClearNodeCache() { - NodeCacheMutex.Lock() - NodesCacheMap = make(map[string]models.Node) - NodeCacheMutex.Unlock() + nodeCacheMutex.Lock() + nodesCacheMap = make(map[string]models.Node) + nodeCacheMutex.Unlock() } const ( @@ -117,7 +117,7 @@ func UpdateNodeCheckin(node *models.Node) error { if err != nil { return err } - StoreNodeInCache(*node) + storeNodeInCache(*node) return nil } @@ -132,7 +132,7 @@ func UpsertNode(newNode *models.Node) error { if err != nil { return err } - StoreNodeInCache(*newNode) + storeNodeInCache(*newNode) return nil } @@ -169,7 +169,7 @@ func UpdateNode(currentNode *models.Node, newNode *models.Node) error { if err != nil { return err } - StoreNodeInCache(*newNode) + storeNodeInCache(*newNode) return nil } } @@ -228,7 +228,7 @@ func deleteNodeByID(node *models.Node) error { return err } } - DeleteNodeFromCache(node.ID.String()) + deleteNodeFromCache(node.ID.String()) if servercfg.IsDNSMode() { SetDNS() } @@ -294,7 +294,7 @@ func IsFailoverPresent(network string) bool { // GetAllNodes - returns all nodes in the DB func GetAllNodes() ([]models.Node, error) { var nodes []models.Node - nodesMap := GetNodesFromCache() + nodesMap := getNodesFromCache() if len(nodesMap) != 0 { for _, node := range nodesMap { nodes = append(nodes, node) @@ -302,7 +302,7 @@ func GetAllNodes() ([]models.Node, error) { return nodes, nil } nodesMap = make(map[string]models.Node) - defer LoadNodesIntoCache(nodesMap) + defer loadNodesIntoCache(nodesMap) collection, err := database.FetchRecords(database.NODES_TABLE_NAME) if err != nil { if database.IsEmptyRecord(err) { @@ -376,7 +376,7 @@ func GetRecordKey(id string, network string) (string, error) { } func GetNodeByID(uuid string) (models.Node, error) { - if node, ok := GetNodeFromCache(uuid); ok { + if node, ok := getNodeFromCache(uuid); ok { return node, nil } var record, err = database.FetchRecord(database.NODES_TABLE_NAME, uuid) @@ -387,7 +387,7 @@ func GetNodeByID(uuid string) (models.Node, error) { if err = json.Unmarshal([]byte(record), &node); err != nil { return models.Node{}, err } - StoreNodeInCache(node) + storeNodeInCache(node) return node, nil } @@ -537,7 +537,7 @@ func createNode(node *models.Node) error { if err != nil { return err } - StoreNodeInCache(*node) + storeNodeInCache(*node) _, 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()) From 27ac920069983c89dd8009ea8c078b7210357acc Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Mon, 26 Jun 2023 20:32:52 +0530 Subject: [PATCH 05/11] cache acls --- controllers/hosts.go | 30 --------------------------- logic/acls/common.go | 36 ++++++++++++++++++++++++++++++++- logic/acls/nodeacls/modify.go | 7 ++++++- logic/acls/nodeacls/retrieve.go | 1 + logic/hosts.go | 22 ++++++++++++-------- logic/networks.go | 30 +++++++++++++-------------- logic/nodes.go | 15 +++++++------- 7 files changed, 78 insertions(+), 63 deletions(-) diff --git a/controllers/hosts.go b/controllers/hosts.go index da329c84..f9f6abfe 100644 --- a/controllers/hosts.go +++ b/controllers/hosts.go @@ -49,38 +49,8 @@ func getHosts(w http.ResponseWriter, r *http.Request) { logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) return } - //isMasterAdmin := r.Header.Get("ismaster") == "yes" - //user, err := logic.GetUser(r.Header.Get("user")) - //if err != nil && !isMasterAdmin { - // logger.Log(0, r.Header.Get("user"), "failed to fetch user: ", err.Error()) - // logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) - // return - //} - // return JSON/API formatted hosts - //ret := []models.ApiHost{} apiHosts := logic.GetAllHostsAPI(currentHosts[:]) logger.Log(2, r.Header.Get("user"), "fetched all hosts") - //for _, host := range apiHosts { - // nodes := host.Nodes - // // work on the copy - // host.Nodes = []string{} - // for _, nid := range nodes { - // node, err := logic.GetNodeByID(nid) - // if err != nil { - // logger.Log(0, r.Header.Get("user"), "failed to fetch node: ", err.Error()) - // // TODO find the reason for the DB error, skip this node for now - // continue - // } - // if !isMasterAdmin && !logic.UserHasNetworksAccess([]string{node.Network}, user) { - // continue - // } - // host.Nodes = append(host.Nodes, nid) - // } - // // add to the response only if has perms to some nodes / networks - // if len(host.Nodes) > 0 { - // ret = append(ret, host) - // } - //} logic.SortApiHosts(apiHosts[:]) w.WriteHeader(http.StatusOK) json.NewEncoder(w).Encode(apiHosts) diff --git a/logic/acls/common.go b/logic/acls/common.go index 79d1bd67..2a11fe9d 100644 --- a/logic/acls/common.go +++ b/logic/acls/common.go @@ -2,10 +2,35 @@ package acls import ( "encoding/json" + "sync" "github.com/gravitl/netmaker/database" ) +var ( + aclCacheMutex = &sync.RWMutex{} + aclCacheMap = make(map[ContainerID]ACLContainer) +) + +func fetchAclContainerFromCache(containerID ContainerID) (aclCont ACLContainer, ok bool) { + aclCacheMutex.RLock() + aclCont, ok = aclCacheMap[containerID] + aclCacheMutex.RUnlock() + return +} + +func storeAclContainerInCache(containerID ContainerID, aclContainer ACLContainer) { + aclCacheMutex.Lock() + aclCacheMap[containerID] = aclContainer + aclCacheMutex.Unlock() +} + +func DeleteAclFromCache(containerID ContainerID) { + aclCacheMutex.Lock() + delete(aclCacheMap, containerID) + aclCacheMutex.Unlock() +} + // == type functions == // ACL.Allow - allows access by ID in memory @@ -75,6 +100,9 @@ func (aclContainer ACLContainer) Get(containerID ContainerID) (ACLContainer, err // fetchACLContainer - fetches all current rules in given ACL container func fetchACLContainer(containerID ContainerID) (ACLContainer, error) { + if aclContainer, ok := fetchAclContainerFromCache(containerID); ok { + return aclContainer, nil + } aclJson, err := fetchACLContainerJson(ContainerID(containerID)) if err != nil { return nil, err @@ -83,6 +111,7 @@ func fetchACLContainer(containerID ContainerID) (ACLContainer, error) { if err := json.Unmarshal([]byte(aclJson), ¤tNetworkACL); err != nil { return nil, err } + storeAclContainerInCache(containerID, currentNetworkACL) return currentNetworkACL, nil } @@ -112,7 +141,12 @@ func upsertACLContainer(containerID ContainerID, aclContainer ACLContainer) (ACL if aclContainer == nil { aclContainer = make(ACLContainer) } - return aclContainer, database.Insert(string(containerID), string(convertNetworkACLtoACLJson(aclContainer)), database.NODE_ACLS_TABLE_NAME) + err := database.Insert(string(containerID), string(convertNetworkACLtoACLJson(aclContainer)), database.NODE_ACLS_TABLE_NAME) + if err != nil { + return aclContainer, err + } + storeAclContainerInCache(containerID, aclContainer) + return aclContainer, nil } func convertNetworkACLtoACLJson(networkACL ACLContainer) ACLJson { diff --git a/logic/acls/nodeacls/modify.go b/logic/acls/nodeacls/modify.go index 42604341..e803bb65 100644 --- a/logic/acls/nodeacls/modify.go +++ b/logic/acls/nodeacls/modify.go @@ -83,5 +83,10 @@ func RemoveNodeACL(networkID NetworkID, nodeID NodeID) (acls.ACLContainer, error // DeleteACLContainer - removes an ACLContainer state from db func DeleteACLContainer(network NetworkID) error { - return database.DeleteRecord(database.NODE_ACLS_TABLE_NAME, string(network)) + err := database.DeleteRecord(database.NODE_ACLS_TABLE_NAME, string(network)) + if err != nil { + return err + } + acls.DeleteAclFromCache(acls.ContainerID(network)) + return nil } diff --git a/logic/acls/nodeacls/retrieve.go b/logic/acls/nodeacls/retrieve.go index c2f4189c..d9946d2c 100644 --- a/logic/acls/nodeacls/retrieve.go +++ b/logic/acls/nodeacls/retrieve.go @@ -9,6 +9,7 @@ import ( // AreNodesAllowed - checks if nodes are allowed to communicate in their network ACL func AreNodesAllowed(networkID NetworkID, node1, node2 NodeID) bool { + return true var currentNetworkACL, err = FetchAllACLs(networkID) if err != nil { return false diff --git a/logic/hosts.go b/logic/hosts.go index ea6268cd..6ff2c61c 100644 --- a/logic/hosts.go +++ b/logic/hosts.go @@ -33,7 +33,16 @@ var ( ErrInvalidHostID error = errors.New("invalid host id") ) -func getHostsFromCache() (hostsMap map[string]models.Host) { +func getHostsFromCache() (hosts []models.Host) { + hostCacheMutex.RLock() + for _, host := range hostsCacheMap { + hosts = append(hosts, host) + } + hostCacheMutex.RUnlock() + return +} + +func getHostsMapFromCache() (hostsMap map[string]models.Host) { hostCacheMutex.RLock() hostsMap = hostsCacheMap hostCacheMutex.RUnlock() @@ -71,12 +80,9 @@ const ( // GetAllHosts - returns all hosts in flat list or error func GetAllHosts() ([]models.Host, error) { - currHosts := []models.Host{} - hostsMap := getHostsFromCache() - if len(hostsMap) != 0 { - for _, host := range hostsMap { - currHosts = append(currHosts, host) - } + + currHosts := getHostsFromCache() + if len(currHosts) != 0 { return currHosts, nil } records, err := database.FetchRecords(database.HOSTS_TABLE_NAME) @@ -110,7 +116,7 @@ func GetAllHostsAPI(hosts []models.Host) []models.ApiHost { // GetHostsMap - gets all the current hosts on machine in a map func GetHostsMap() (map[string]models.Host, error) { - hostsMap := getHostsFromCache() + hostsMap := getHostsMapFromCache() if len(hostsMap) != 0 { return hostsMap, nil } diff --git a/logic/networks.go b/logic/networks.go index bd52bf2b..68c48860 100644 --- a/logic/networks.go +++ b/logic/networks.go @@ -194,18 +194,12 @@ func UniqueAddress(networkName string, reverse bool) (net.IP, error) { func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool { isunique := true - collection, err := database.FetchRecords(tableName) - if err != nil { - return isunique - } - - for _, value := range collection { // filter - - if tableName == database.NODES_TABLE_NAME { - var node models.Node - if err = json.Unmarshal([]byte(value), &node); err != nil { - continue - } + if tableName == database.NODES_TABLE_NAME { + nodes, err := GetNetworkNodes(network) + if err != nil { + return isunique + } + for _, node := range nodes { if isIpv6 { if node.Address6.IP.String() == ip && node.Network == network { return false @@ -215,8 +209,15 @@ func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool { return false } } - } else if tableName == database.EXT_CLIENT_TABLE_NAME { - var extClient models.ExtClient + } + + } else if tableName == database.EXT_CLIENT_TABLE_NAME { + collection, err := database.FetchRecords(tableName) + if err != nil { + return isunique + } + var extClient models.ExtClient + for _, value := range collection { // filter if err = json.Unmarshal([]byte(value), &extClient); err != nil { continue } @@ -231,7 +232,6 @@ func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool { } } } - } return isunique diff --git a/logic/nodes.go b/logic/nodes.go index 465f917e..c0d79f35 100644 --- a/logic/nodes.go +++ b/logic/nodes.go @@ -33,9 +33,11 @@ func getNodeFromCache(nodeID string) (node models.Node, ok bool) { nodeCacheMutex.RUnlock() return } -func getNodesFromCache() (nMap map[string]models.Node) { +func getNodesFromCache() (nodes []models.Node) { nodeCacheMutex.RLock() - nMap = nodesCacheMap + for _, node := range nodesCacheMap { + nodes = append(nodes, node) + } nodeCacheMutex.RUnlock() return } @@ -294,14 +296,11 @@ func IsFailoverPresent(network string) bool { // GetAllNodes - returns all nodes in the DB func GetAllNodes() ([]models.Node, error) { var nodes []models.Node - nodesMap := getNodesFromCache() - if len(nodesMap) != 0 { - for _, node := range nodesMap { - nodes = append(nodes, node) - } + nodes = getNodesFromCache() + if len(nodes) != 0 { return nodes, nil } - nodesMap = make(map[string]models.Node) + nodesMap := make(map[string]models.Node) defer loadNodesIntoCache(nodesMap) collection, err := database.FetchRecords(database.NODES_TABLE_NAME) if err != nil { From 50e093b456850e44ed12ae933dd4cc01d47703f0 Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Tue, 27 Jun 2023 20:48:53 +0530 Subject: [PATCH 06/11] cache ext clients --- controllers/ext_client.go | 3 +- logic/extpeers.go | 79 +++++++++++++++++++++++++-------------- logic/networks.go | 9 ++--- 3 files changed, 54 insertions(+), 37 deletions(-) diff --git a/controllers/ext_client.go b/controllers/ext_client.go index d324cc42..7552dcdb 100644 --- a/controllers/ext_client.go +++ b/controllers/ext_client.go @@ -10,7 +10,6 @@ import ( "github.com/gorilla/mux" "github.com/gravitl/netmaker/database" - "github.com/gravitl/netmaker/functions" "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/logic" "github.com/gravitl/netmaker/logic/pro" @@ -102,7 +101,7 @@ func getAllExtClients(w http.ResponseWriter, r *http.Request) { clients := []models.ExtClient{} var err error if len(networksSlice) > 0 && networksSlice[0] == logic.ALL_NETWORK_ACCESS { - clients, err = functions.GetAllExtClients() + clients, err = logic.GetAllExtClients() if err != nil && !database.IsEmptyRecord(err) { logger.Log(0, "failed to get all extclients: ", err.Error()) logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal")) diff --git a/logic/extpeers.go b/logic/extpeers.go index f5f1c4ef..f6c9bcf5 100644 --- a/logic/extpeers.go +++ b/logic/extpeers.go @@ -3,43 +3,44 @@ package logic import ( "encoding/json" "fmt" + "sync" "time" "github.com/gravitl/netmaker/database" - "github.com/gravitl/netmaker/logger" "github.com/gravitl/netmaker/models" "golang.zx2c4.com/wireguard/wgctrl/wgtypes" ) -// GetExtPeersList - gets the ext peers lists -func GetExtPeersList(node *models.Node) ([]models.ExtPeersResponse, error) { +var ( + extClientCacheMutex = &sync.RWMutex{} + extClientCacheMap = make(map[string]models.ExtClient) +) - var peers []models.ExtPeersResponse - records, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME) - - if err != nil { - return peers, err +func getAllExtClientsFromCache() (extClients []models.ExtClient) { + extClientCacheMutex.RLock() + for _, extclient := range extClientCacheMap { + extClients = append(extClients, extclient) } + return +} - for _, value := range records { - var peer models.ExtPeersResponse - var extClient models.ExtClient - err = json.Unmarshal([]byte(value), &peer) - if err != nil { - logger.Log(2, "failed to unmarshal peer when getting ext peer list") - continue - } - err = json.Unmarshal([]byte(value), &extClient) - if err != nil { - logger.Log(2, "failed to unmarshal ext client") - continue - } +func deleteExtClientFromCache(key string) { + extClientCacheMutex.Lock() + delete(extClientCacheMap, key) + extClientCacheMutex.Unlock() +} - if extClient.Enabled && extClient.Network == node.Network && extClient.IngressGatewayID == node.ID.String() { - peers = append(peers, peer) - } - } - return peers, err +func getExtClientFromCache(key string) (extclient models.ExtClient, ok bool) { + extClientCacheMutex.RLock() + extclient, ok = extClientCacheMap[key] + extClientCacheMutex.RUnlock() + return +} + +func storeExtClientInCache(key string, extclient models.ExtClient) { + extClientCacheMutex.Lock() + extClientCacheMap[key] = extclient + extClientCacheMutex.Unlock() } // ExtClient.GetEgressRangesOnNetwork - returns the egress ranges on network of ext client @@ -71,13 +72,25 @@ func DeleteExtClient(network string, clientid string) error { return err } err = database.DeleteRecord(database.EXT_CLIENT_TABLE_NAME, key) - return err + if err != nil { + return err + } + deleteExtClientFromCache(key) + return nil } // GetNetworkExtClients - gets the ext clients of given network func GetNetworkExtClients(network string) ([]models.ExtClient, error) { var extclients []models.ExtClient - + allextclients := getAllExtClientsFromCache() + if len(allextclients) != 0 { + for _, extclient := range allextclients { + if extclient.Network == network { + extclients = append(extclients, extclient) + } + } + return extclients, nil + } records, err := database.FetchRecords(database.EXT_CLIENT_TABLE_NAME) if err != nil { return extclients, err @@ -88,6 +101,10 @@ func GetNetworkExtClients(network string) ([]models.ExtClient, error) { if err != nil { continue } + key, err := GetRecordKey(extclient.ClientID, network) + if err == nil { + storeExtClientInCache(key, extclient) + } if extclient.Network == network { extclients = append(extclients, extclient) } @@ -102,12 +119,15 @@ func GetExtClient(clientid string, network string) (models.ExtClient, error) { if err != nil { return extclient, err } + if extclient, ok := getExtClientFromCache(key); ok { + return extclient, nil + } data, err := database.FetchRecord(database.EXT_CLIENT_TABLE_NAME, key) if err != nil { return extclient, err } err = json.Unmarshal([]byte(data), &extclient) - + storeExtClientInCache(key, extclient) return extclient, err } @@ -186,6 +206,7 @@ func SaveExtClient(extclient *models.ExtClient) error { if err = database.Insert(key, string(data), database.EXT_CLIENT_TABLE_NAME); err != nil { return err } + storeExtClientInCache(key, *extclient) return SetNetworkNodesLastModified(extclient.Network) } diff --git a/logic/networks.go b/logic/networks.go index 68c48860..102c39d3 100644 --- a/logic/networks.go +++ b/logic/networks.go @@ -212,15 +212,12 @@ func IsIPUnique(network string, ip string, tableName string, isIpv6 bool) bool { } } else if tableName == database.EXT_CLIENT_TABLE_NAME { - collection, err := database.FetchRecords(tableName) + + extClients, err := GetNetworkExtClients(network) if err != nil { return isunique } - var extClient models.ExtClient - for _, value := range collection { // filter - if err = json.Unmarshal([]byte(value), &extClient); err != nil { - continue - } + for _, extClient := range extClients { // filter if isIpv6 { if (extClient.Address6 == ip) && extClient.Network == network { return false From 845bb33c6825dfc6f0f165f3e2376e29a2afb7ec Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Tue, 27 Jun 2023 21:31:04 +0530 Subject: [PATCH 07/11] unlock mutex --- logic/extpeers.go | 1 + 1 file changed, 1 insertion(+) diff --git a/logic/extpeers.go b/logic/extpeers.go index f6c9bcf5..643a8729 100644 --- a/logic/extpeers.go +++ b/logic/extpeers.go @@ -21,6 +21,7 @@ func getAllExtClientsFromCache() (extClients []models.ExtClient) { for _, extclient := range extClientCacheMap { extClients = append(extClients, extclient) } + extClientCacheMutex.RUnlock() return } From 65a683ad796bb2f92b0de2411bfdf4bc876aab80 Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Tue, 27 Jun 2023 21:48:07 +0530 Subject: [PATCH 08/11] rm return --- logic/acls/nodeacls/retrieve.go | 1 - 1 file changed, 1 deletion(-) diff --git a/logic/acls/nodeacls/retrieve.go b/logic/acls/nodeacls/retrieve.go index d9946d2c..c2f4189c 100644 --- a/logic/acls/nodeacls/retrieve.go +++ b/logic/acls/nodeacls/retrieve.go @@ -9,7 +9,6 @@ import ( // AreNodesAllowed - checks if nodes are allowed to communicate in their network ACL func AreNodesAllowed(networkID NetworkID, node1, node2 NodeID) bool { - return true var currentNetworkACL, err = FetchAllACLs(networkID) if err != nil { return false From cfdc15fc8dc43043390554ed19a44c06be910eb8 Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Tue, 27 Jun 2023 22:15:36 +0530 Subject: [PATCH 09/11] fix integration tests --- controllers/dns_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/controllers/dns_test.go b/controllers/dns_test.go index 8a9b886f..e070cfed 100644 --- a/controllers/dns_test.go +++ b/controllers/dns_test.go @@ -51,8 +51,7 @@ func TestGetNodeDNS(t *testing.T) { createNet() createHost() t.Run("NoNodes", func(t *testing.T) { - dns, err := logic.GetNodeDNS("skynet") - assert.EqualError(t, err, "could not find any records") + dns, _ := logic.GetNodeDNS("skynet") assert.Equal(t, []models.DNSEntry(nil), dns) }) t.Run("NodeExists", func(t *testing.T) { From 8d874b876b42aa0020cc8ef65ee56db07cc8fe13 Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Wed, 28 Jun 2023 08:34:14 +0530 Subject: [PATCH 10/11] set mq order matters to false --- mq/mq.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mq/mq.go b/mq/mq.go index 5e6fdb72..9be06871 100644 --- a/mq/mq.go +++ b/mq/mq.go @@ -80,7 +80,7 @@ func SetupMQTT() { logger.Log(0, "node metrics subscription failed") } - opts.SetOrderMatters(true) + opts.SetOrderMatters(false) opts.SetResumeSubs(true) }) mqclient = mqtt.NewClient(opts) From b4081f43d1dc2557c491362416068e19ebfafb18 Mon Sep 17 00:00:00 2001 From: Abhishek Kondur Date: Wed, 28 Jun 2023 13:42:01 +0530 Subject: [PATCH 11/11] use mutex for accessing acl container --- logic/acls/common.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/logic/acls/common.go b/logic/acls/common.go index b0eda2e0..8c28cb6a 100644 --- a/logic/acls/common.go +++ b/logic/acls/common.go @@ -11,6 +11,7 @@ import ( var ( aclCacheMutex = &sync.RWMutex{} aclCacheMap = make(map[ContainerID]ACLContainer) + aclMutex = &sync.RWMutex{} ) func fetchAclContainerFromCache(containerID ContainerID) (aclCont ACLContainer, ok bool) { @@ -117,6 +118,8 @@ func (aclContainer ACLContainer) Get(containerID ContainerID) (ACLContainer, err // fetchACLContainer - fetches all current rules in given ACL container func fetchACLContainer(containerID ContainerID) (ACLContainer, error) { + aclMutex.RLock() + defer aclMutex.RUnlock() if aclContainer, ok := fetchAclContainerFromCache(containerID); ok { return aclContainer, nil } @@ -155,9 +158,12 @@ func upsertACL(containerID ContainerID, ID AclID, acl ACL) (ACL, error) { // upsertACLContainer - Inserts or updates a network ACL given the json string of the ACL and the container ID // if nil, create it func upsertACLContainer(containerID ContainerID, aclContainer ACLContainer) (ACLContainer, error) { + aclMutex.Lock() + defer aclMutex.Unlock() if aclContainer == nil { aclContainer = make(ACLContainer) } + err := database.Insert(string(containerID), string(convertNetworkACLtoACLJson(aclContainer)), database.NODE_ACLS_TABLE_NAME) if err != nil { return aclContainer, err