diff --git a/controllers/tags.go b/controllers/tags.go index 5e271ba7..5b83179c 100644 --- a/controllers/tags.go +++ b/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 } diff --git a/logic/extpeers.go b/logic/extpeers.go index 24ee787f..542f98b5 100644 --- a/logic/extpeers.go +++ b/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 } diff --git a/logic/nodes.go b/logic/nodes.go index 07d4b29b..5b81c9b8 100644 --- a/logic/nodes.go +++ b/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 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,41 @@ 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 + } + 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 } diff --git a/logic/tags.go b/logic/tags.go index 394c7db1..7cdf0f32 100644 --- a/logic/tags.go +++ b/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) diff --git a/models/extclient.go b/models/extclient.go index 9d67207d..b84a7c8d 100644 --- a/models/extclient.go +++ b/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,5 @@ 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"` } diff --git a/models/tags.go b/models/tags.go index c611ade7..9fcb449d 100644 --- a/models/tags.go +++ b/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"` }