فهرست منبع

Merge pull request #3164 from gravitl/NET-1615-ext

NET-1615: Apply Acl policy to static nodes
Abhishek K 10 ماه پیش
والد
کامیت
d297158da3
8فایلهای تغییر یافته به همراه191 افزوده شده و 29 حذف شده
  1. 13 2
      controllers/tags.go
  2. 7 2
      logic/acls.go
  3. 11 0
      logic/extpeers.go
  4. 61 2
      logic/nodes.go
  5. 1 0
      logic/peers.go
  6. 77 16
      logic/tags.go
  7. 14 0
      models/extclient.go
  8. 7 7
      models/tags.go

+ 13 - 2
controllers/tags.go

@@ -107,8 +107,19 @@ func createTag(w http.ResponseWriter, r *http.Request) {
 		return
 	}
 	go func() {
-		for _, nodeID := range req.TaggedNodes {
-			node, err := logic.GetNodeByID(nodeID)
+		for _, node := range req.TaggedNodes {
+			if node.IsStatic {
+				extclient, err := logic.GetExtClient(node.StaticNode.ClientID, node.StaticNode.Network)
+				if err == nil && extclient.RemoteAccessClientID == "" {
+					if extclient.Tags == nil {
+						extclient.Tags = make(map[models.TagID]struct{})
+					}
+					extclient.Tags[tag.ID] = struct{}{}
+					logic.SaveExtClient(&extclient)
+				}
+				continue
+			}
+			node, err := logic.GetNodeByID(node.ID)
 			if err != nil {
 				continue
 			}

+ 7 - 2
logic/acls.go

@@ -323,8 +323,8 @@ func ListUserPolicies(u models.User) []models.Acl {
 	return acls
 }
 
-// ListUserPoliciesByNetwork - lists all acl user policies in a network
-func ListUserPoliciesByNetwork(netID models.NetworkID) []models.Acl {
+// listUserPoliciesByNetwork - lists all acl user policies in a network
+func listUserPoliciesByNetwork(netID models.NetworkID) []models.Acl {
 	data, err := database.FetchRecords(database.ACLS_TABLE_NAME)
 	if err != nil && !database.IsEmptyRecord(err) {
 		return []models.Acl{}
@@ -391,6 +391,11 @@ func convAclTagToValueMap(acltags []models.AclPolicyTag) map[string]struct{} {
 	return aclValueMap
 }
 
+func IsUserAllowedToCommunicate(userName string, peer models.Node) bool {
+	listUserPoliciesByNetwork(models.NetworkID(peer.Network))
+	return true
+}
+
 // IsNodeAllowedToCommunicate - check node is allowed to communicate with the peer
 func IsNodeAllowedToCommunicate(node, peer models.Node) bool {
 	// check default policy if all allowed return true

+ 11 - 0
logic/extpeers.go

@@ -329,6 +329,7 @@ func UpdateExtClient(old *models.ExtClient, update *models.CustomExtClient) mode
 	// replace any \r\n with \n in postup and postdown from HTTP request
 	new.PostUp = strings.Replace(update.PostUp, "\r\n", "\n", -1)
 	new.PostDown = strings.Replace(update.PostDown, "\r\n", "\n", -1)
+	new.Tags = update.Tags
 	return new
 }
 
@@ -412,6 +413,16 @@ func GetExtPeers(node, peer *models.Node) ([]wgtypes.PeerConfig, []models.IDandA
 		if !IsClientNodeAllowed(&extPeer, peer.ID.String()) {
 			continue
 		}
+		if extPeer.RemoteAccessClientID == "" {
+			if !IsNodeAllowedToCommunicate(extPeer.ConvertToStaticNode(), *peer) {
+				continue
+			}
+		} else {
+			if !IsUserAllowedToCommunicate(extPeer.OwnerID, *peer) {
+				continue
+			}
+		}
+
 		pubkey, err := wgtypes.ParseKey(extPeer.PublicKey)
 		if err != nil {
 			logger.Log(1, "error parsing ext pub key:", err.Error())

+ 61 - 2
logic/nodes.go

@@ -741,11 +741,31 @@ func GetTagMapWithNodesByNetwork(netID models.NetworkID) (tagNodesMap map[models
 			tagNodesMap[nodeTagID] = append(tagNodesMap[nodeTagID], nodeI)
 		}
 	}
-	return
+	return AddTagMapWithStaticNodes(netID, tagNodesMap)
 }
 
-func GetNodesWithTag(tagID models.TagID) map[string]models.Node {
+func AddTagMapWithStaticNodes(netID models.NetworkID,
+	tagNodesMap map[models.TagID][]models.Node) map[models.TagID][]models.Node {
+	extclients, err := GetNetworkExtClients(netID.String())
+	if err != nil {
+		return tagNodesMap
+	}
+	for _, extclient := range extclients {
+		if extclient.Tags == nil || extclient.RemoteAccessClientID != "" {
+			continue
+		}
+		for tagID := range extclient.Tags {
+			tagNodesMap[tagID] = append(tagNodesMap[tagID], models.Node{
+				IsStatic:   true,
+				StaticNode: extclient,
+			})
+		}
+
+	}
+	return tagNodesMap
+}
 
+func GetNodesWithTag(tagID models.TagID) map[string]models.Node {
 	nMap := make(map[string]models.Node)
 	tag, err := GetTag(tagID)
 	if err != nil {
@@ -760,5 +780,44 @@ func GetNodesWithTag(tagID models.TagID) map[string]models.Node {
 			nMap[nodeI.ID.String()] = nodeI
 		}
 	}
+	return AddStaticNodesWithTag(tag, nMap)
+}
+
+func AddStaticNodesWithTag(tag models.Tag, nMap map[string]models.Node) map[string]models.Node {
+	extclients, err := GetNetworkExtClients(tag.Network.String())
+	if err != nil {
+		return nMap
+	}
+	for _, extclient := range extclients {
+		if extclient.RemoteAccessClientID != "" {
+			continue
+		}
+		if _, ok := extclient.Tags[tag.ID]; ok {
+			nMap[extclient.ClientID] = models.Node{
+				IsStatic:   true,
+				StaticNode: extclient,
+			}
+		}
+
+	}
+	return nMap
+}
+
+func GetStaticNodeWithTag(tagID models.TagID) map[string]models.Node {
+	nMap := make(map[string]models.Node)
+	tag, err := GetTag(tagID)
+	if err != nil {
+		return nMap
+	}
+	extclients, err := GetNetworkExtClients(tag.Network.String())
+	if err != nil {
+		return nMap
+	}
+	for _, extclient := range extclients {
+		nMap[extclient.ClientID] = models.Node{
+			IsStatic:   true,
+			StaticNode: extclient,
+		}
+	}
 	return nMap
 }

+ 1 - 0
logic/peers.go

@@ -426,6 +426,7 @@ func GetAllowedIPs(node, peer *models.Node, metrics *models.Metrics) []net.IPNet
 			logger.Log(2, "could not retrieve ext peers for ", peer.ID.String(), err.Error())
 		}
 		for _, extPeer := range extPeers {
+
 			allowedips = append(allowedips, extPeer.AllowedIPs...)
 		}
 	}

+ 77 - 16
logic/tags.go

@@ -69,6 +69,13 @@ func DeleteTag(tagID models.TagID, removeFromPolicy bool) error {
 		// remove tag used on acl policy
 		go RemoveDeviceTagFromAclPolicies(tagID, tag.Network)
 	}
+	extclients, _ := GetNetworkExtClients(tag.Network.String())
+	for _, extclient := range extclients {
+		if _, ok := extclient.Tags[tagID]; ok {
+			delete(extclient.Tags, tagID)
+			SaveExtClient(&extclient)
+		}
+	}
 	return database.DeleteRecord(database.TAG_TABLE_NAME, tagID.String())
 }
 
@@ -84,7 +91,7 @@ func ListTagsWithNodes(netID models.NetworkID) ([]models.TagListResp, error) {
 		tagRespI := models.TagListResp{
 			Tag:         tagI,
 			UsedByCnt:   len(tagsNodeMap[tagI.ID]),
-			TaggedNodes: tagsNodeMap[tagI.ID],
+			TaggedNodes: GetAllNodesAPI(tagsNodeMap[tagI.ID]),
 		}
 		resp = append(resp, tagRespI)
 	}
@@ -138,46 +145,100 @@ func ListNetworkTags(netID models.NetworkID) ([]models.Tag, error) {
 func UpdateTag(req models.UpdateTagReq, newID models.TagID) {
 	tagMutex.Lock()
 	defer tagMutex.Unlock()
+	var err error
 	tagNodesMap := GetNodesWithTag(req.ID)
-	for _, nodeID := range req.TaggedNodes {
-		node, err := GetNodeByID(nodeID)
-		if err != nil {
-			continue
+	for _, apiNode := range req.TaggedNodes {
+		node := models.Node{}
+		var nodeID string
+		if apiNode.IsStatic {
+			if apiNode.StaticNode.RemoteAccessClientID != "" {
+				continue
+			}
+			extclient, err := GetExtClient(apiNode.StaticNode.ClientID, apiNode.StaticNode.Network)
+			if err != nil {
+				continue
+			}
+			node.IsStatic = true
+			nodeID = extclient.ClientID
+			node.StaticNode = extclient
+		} else {
+			node, err = GetNodeByID(apiNode.ID)
+			if err != nil {
+				continue
+			}
+			nodeID = node.ID.String()
 		}
 
-		if _, ok := tagNodesMap[node.ID.String()]; !ok {
+		if _, ok := tagNodesMap[nodeID]; !ok {
+			if node.StaticNode.Tags == nil {
+				node.StaticNode.Tags = make(map[models.TagID]struct{})
+			}
 			if node.Tags == nil {
 				node.Tags = make(map[models.TagID]struct{})
 			}
 			if newID != "" {
-				node.Tags[newID] = struct{}{}
+				if node.IsStatic {
+					node.StaticNode.Tags[newID] = struct{}{}
+					SaveExtClient(&node.StaticNode)
+				} else {
+					node.Tags[newID] = struct{}{}
+					UpsertNode(&node)
+				}
+
 			} else {
-				node.Tags[req.ID] = struct{}{}
+				if node.IsStatic {
+					node.StaticNode.Tags[req.ID] = struct{}{}
+					SaveExtClient(&node.StaticNode)
+				} else {
+					node.Tags[req.ID] = struct{}{}
+					UpsertNode(&node)
+				}
 			}
-			UpsertNode(&node)
 		} else {
 			if newID != "" {
 				delete(node.Tags, req.ID)
-				node.Tags[newID] = struct{}{}
-				UpsertNode(&node)
+				delete(node.StaticNode.Tags, req.ID)
+				if node.IsStatic {
+					node.StaticNode.Tags[newID] = struct{}{}
+					SaveExtClient(&node.StaticNode)
+				} else {
+					node.Tags[newID] = struct{}{}
+					UpsertNode(&node)
+				}
 			}
-			delete(tagNodesMap, node.ID.String())
+			delete(tagNodesMap, nodeID)
 		}
 
 	}
 	for _, deletedTaggedNode := range tagNodesMap {
-		deletedTaggedHost := deletedTaggedNode
-		delete(deletedTaggedHost.Tags, req.ID)
-		UpsertNode(&deletedTaggedHost)
+		delete(deletedTaggedNode.Tags, req.ID)
+		delete(deletedTaggedNode.StaticNode.Tags, req.ID)
+		if deletedTaggedNode.IsStatic {
+			SaveExtClient(&deletedTaggedNode.StaticNode)
+		} else {
+			UpsertNode(&deletedTaggedNode)
+		}
 	}
 	go func(req models.UpdateTagReq) {
 		if newID != "" {
 			tagNodesMap = GetNodesWithTag(req.ID)
 			for _, nodeI := range tagNodesMap {
 				nodeI := nodeI
+				if nodeI.StaticNode.Tags == nil {
+					nodeI.StaticNode.Tags = make(map[models.TagID]struct{})
+				}
+				if nodeI.Tags == nil {
+					nodeI.Tags = make(map[models.TagID]struct{})
+				}
 				delete(nodeI.Tags, req.ID)
+				delete(nodeI.StaticNode.Tags, req.ID)
 				nodeI.Tags[newID] = struct{}{}
-				UpsertNode(&nodeI)
+				nodeI.StaticNode.Tags[newID] = struct{}{}
+				if nodeI.IsStatic {
+					SaveExtClient(&nodeI.StaticNode)
+				} else {
+					UpsertNode(&nodeI)
+				}
 			}
 		}
 	}(req)

+ 14 - 0
models/extclient.go

@@ -20,6 +20,7 @@ type ExtClient struct {
 	RemoteAccessClientID   string              `json:"remote_access_client_id"` // unique ID (MAC address) of RAC machine
 	PostUp                 string              `json:"postup" bson:"postup"`
 	PostDown               string              `json:"postdown" bson:"postdown"`
+	Tags                   map[TagID]struct{}  `json:"tags"`
 }
 
 // CustomExtClient - struct for CustomExtClient params
@@ -33,4 +34,17 @@ type CustomExtClient struct {
 	RemoteAccessClientID string              `json:"remote_access_client_id"` // unique ID (MAC address) of RAC machine
 	PostUp               string              `json:"postup" bson:"postup" validate:"max=1024"`
 	PostDown             string              `json:"postdown" bson:"postdown" validate:"max=1024"`
+	Tags                 map[TagID]struct{}  `json:"tags"`
+}
+
+func (ext *ExtClient) ConvertToStaticNode() Node {
+
+	return Node{
+		CommonNode: CommonNode{
+			Network: ext.Network,
+		},
+		Tags:       ext.Tags,
+		IsStatic:   true,
+		StaticNode: *ext,
+	}
 }

+ 7 - 7
models/tags.go

@@ -30,23 +30,23 @@ type Tag struct {
 type CreateTagReq struct {
 	TagName     string    `json:"tag_name"`
 	Network     NetworkID `json:"network"`
-	TaggedNodes []string  `json:"tagged_nodes"`
+	TaggedNodes []ApiNode `json:"tagged_nodes"`
 }
 
 type TagListResp struct {
 	Tag
-	UsedByCnt   int    `json:"used_by_count"`
-	TaggedNodes []Node `json:"tagged_nodes"`
+	UsedByCnt   int       `json:"used_by_count"`
+	TaggedNodes []ApiNode `json:"tagged_nodes"`
 }
 
 type TagListRespNodes struct {
 	Tag
-	UsedByCnt   int    `json:"used_by_count"`
-	TaggedNodes []Node `json:"tagged_nodes"`
+	UsedByCnt   int       `json:"used_by_count"`
+	TaggedNodes []ApiNode `json:"tagged_nodes"`
 }
 
 type UpdateTagReq struct {
 	Tag
-	NewName     string   `json:"new_name"`
-	TaggedNodes []string `json:"tagged_nodes"`
+	NewName     string    `json:"new_name"`
+	TaggedNodes []ApiNode `json:"tagged_nodes"`
 }