| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180 |
- package logic
- import (
- "encoding/json"
- "fmt"
- "sort"
- "sync"
- "github.com/gravitl/netmaker/database"
- "github.com/gravitl/netmaker/models"
- )
- var tagMutex = &sync.RWMutex{}
- // GetTag - fetches tag info
- func GetTag(tagID models.TagID) (models.Tag, error) {
- data, err := database.FetchRecord(database.TAG_TABLE_NAME, tagID.String())
- if err != nil {
- return models.Tag{}, err
- }
- tag := models.Tag{}
- err = json.Unmarshal([]byte(data), &tag)
- if err != nil {
- return tag, err
- }
- return tag, nil
- }
- // InsertTag - creates new tag
- func InsertTag(tag models.Tag) error {
- _, err := database.FetchRecord(database.TAG_TABLE_NAME, tag.ID.String())
- if err == nil {
- return fmt.Errorf("tag `%s` exists already", tag.ID)
- }
- d, err := json.Marshal(tag)
- if err != nil {
- return err
- }
- return database.Insert(tag.ID.String(), string(d), database.TAG_TABLE_NAME)
- }
- // DeleteTag - delete tag, will also untag hosts
- func DeleteTag(tagID models.TagID) error {
- // cleanUp tags on hosts
- tag, err := GetTag(tagID)
- if err != nil {
- return err
- }
- nodes, err := GetNetworkNodes(tag.Network.String())
- if err != nil {
- return err
- }
- for _, nodeI := range nodes {
- nodeI := nodeI
- if _, ok := nodeI.Tags[tagID]; ok {
- delete(nodeI.Tags, tagID)
- UpsertNode(&nodeI)
- }
- }
- return database.DeleteRecord(database.TAG_TABLE_NAME, tagID.String())
- }
- // ListTagsWithHosts - lists all tags with tagged hosts
- func ListTagsWithNodes(netID models.NetworkID) ([]models.TagListResp, error) {
- tagMutex.RLock()
- defer tagMutex.RUnlock()
- tags, err := ListNetworkTags(netID)
- if err != nil {
- return []models.TagListResp{}, err
- }
- tagsNodeMap := GetTagMapWithNodes(netID)
- resp := []models.TagListResp{}
- for _, tagI := range tags {
- tagRespI := models.TagListResp{
- Tag: tagI,
- UsedByCnt: len(tagsNodeMap[tagI.ID]),
- TaggedNodes: tagsNodeMap[tagI.ID],
- }
- resp = append(resp, tagRespI)
- }
- return resp, nil
- }
- // ListTags - lists all tags from DB
- func ListTags() ([]models.Tag, error) {
- data, err := database.FetchRecords(database.TAG_TABLE_NAME)
- if err != nil && !database.IsEmptyRecord(err) {
- return []models.Tag{}, err
- }
- tags := []models.Tag{}
- for _, dataI := range data {
- tag := models.Tag{}
- err := json.Unmarshal([]byte(dataI), &tag)
- if err != nil {
- continue
- }
- tags = append(tags, tag)
- }
- return tags, nil
- }
- // ListTags - lists all tags from DB
- func ListNetworkTags(netID models.NetworkID) ([]models.Tag, error) {
- data, err := database.FetchRecords(database.TAG_TABLE_NAME)
- if err != nil && !database.IsEmptyRecord(err) {
- return []models.Tag{}, err
- }
- tags := []models.Tag{}
- for _, dataI := range data {
- tag := models.Tag{}
- err := json.Unmarshal([]byte(dataI), &tag)
- if err != nil {
- continue
- }
- if tag.Network == netID {
- tags = append(tags, tag)
- }
- }
- return tags, nil
- }
- // UpdateTag - updates and syncs hosts with tag update
- func UpdateTag(req models.UpdateTagReq, newID models.TagID) {
- tagMutex.Lock()
- defer tagMutex.Unlock()
- tagNodesMap := GetNodesWithTag(req.ID)
- for _, nodeID := range req.TaggedNodes {
- node, err := GetNodeByID(nodeID)
- if err != nil {
- continue
- }
- if _, ok := tagNodesMap[node.ID.String()]; !ok {
- if node.Tags == nil {
- node.Tags = make(map[models.TagID]struct{})
- }
- if newID != "" {
- node.Tags[newID] = struct{}{}
- } else {
- node.Tags[req.ID] = struct{}{}
- }
- UpsertNode(&node)
- } else {
- if newID != "" {
- delete(node.Tags, req.ID)
- node.Tags[newID] = struct{}{}
- UpsertNode(&node)
- }
- delete(tagNodesMap, node.ID.String())
- }
- }
- for _, deletedTaggedNode := range tagNodesMap {
- deletedTaggedHost := deletedTaggedNode
- delete(deletedTaggedHost.Tags, req.ID)
- UpsertNode(&deletedTaggedHost)
- }
- go func(req models.UpdateTagReq) {
- if newID != "" {
- tagNodesMap = GetNodesWithTag(req.ID)
- for _, nodeI := range tagNodesMap {
- nodeI := nodeI
- delete(nodeI.Tags, req.ID)
- nodeI.Tags[newID] = struct{}{}
- UpsertNode(&nodeI)
- }
- }
- }(req)
- }
- // SortTagEntrys - Sorts slice of Tag entries by their id
- func SortTagEntrys(tags []models.TagListResp) {
- sort.Slice(tags, func(i, j int) bool {
- return tags[i].ID < tags[j].ID
- })
- }
|