tags.go 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package controller
  2. import (
  3. "encoding/json"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "net/url"
  8. "strings"
  9. "time"
  10. "github.com/gorilla/mux"
  11. "github.com/gravitl/netmaker/logger"
  12. "github.com/gravitl/netmaker/logic"
  13. "github.com/gravitl/netmaker/models"
  14. )
  15. func tagHandlers(r *mux.Router) {
  16. r.HandleFunc("/api/v1/tags", logic.SecurityCheck(true, http.HandlerFunc(getTags))).
  17. Methods(http.MethodGet)
  18. r.HandleFunc("/api/v1/tags", logic.SecurityCheck(true, http.HandlerFunc(createTag))).
  19. Methods(http.MethodPost)
  20. r.HandleFunc("/api/v1/tags", logic.SecurityCheck(true, http.HandlerFunc(updateTag))).
  21. Methods(http.MethodPut)
  22. r.HandleFunc("/api/v1/tags", logic.SecurityCheck(true, http.HandlerFunc(deleteTag))).
  23. Methods(http.MethodDelete)
  24. }
  25. // @Summary List Tags in a network
  26. // @Router /api/v1/tags [get]
  27. // @Tags TAG
  28. // @Accept json
  29. // @Success 200 {array} models.SuccessResponse
  30. // @Failure 500 {object} models.ErrorResponse
  31. func getTags(w http.ResponseWriter, r *http.Request) {
  32. netID, _ := url.QueryUnescape(r.URL.Query().Get("network"))
  33. if netID == "" {
  34. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("network id param is missing"), "badrequest"))
  35. return
  36. }
  37. // check if network exists
  38. _, err := logic.GetNetwork(netID)
  39. if err != nil {
  40. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  41. return
  42. }
  43. tags, err := logic.ListTagsWithNodes(models.NetworkID(netID))
  44. if err != nil {
  45. logger.Log(0, r.Header.Get("user"), "failed to get all network tag entries: ", err.Error())
  46. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "internal"))
  47. return
  48. }
  49. logic.SortTagEntrys(tags[:])
  50. logic.ReturnSuccessResponseWithJson(w, r, tags, "fetched all tags in the network "+netID)
  51. }
  52. // @Summary Create Tag
  53. // @Router /api/v1/tags [post]
  54. // @Tags TAG
  55. // @Accept json
  56. // @Success 200 {array} models.SuccessResponse
  57. // @Failure 500 {object} models.ErrorResponse
  58. func createTag(w http.ResponseWriter, r *http.Request) {
  59. var req models.CreateTagReq
  60. err := json.NewDecoder(r.Body).Decode(&req)
  61. if err != nil {
  62. logger.Log(0, "error decoding request body: ",
  63. err.Error())
  64. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  65. return
  66. }
  67. user, err := logic.GetUser(r.Header.Get("user"))
  68. if err != nil {
  69. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  70. return
  71. }
  72. // check if tag network exists
  73. _, err = logic.GetNetwork(req.Network.String())
  74. if err != nil {
  75. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("failed to get network details for "+req.Network.String()), "badrequest"))
  76. return
  77. }
  78. // check if tag exists
  79. tag := models.Tag{
  80. ID: models.TagID(fmt.Sprintf("%s.%s", req.Network, req.TagName)),
  81. TagName: req.TagName,
  82. Network: req.Network,
  83. CreatedBy: user.UserName,
  84. CreatedAt: time.Now(),
  85. }
  86. err = logic.InsertTag(tag)
  87. if err != nil {
  88. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  89. return
  90. }
  91. go func() {
  92. for _, nodeID := range req.TaggedNodes {
  93. node, err := logic.GetNodeByID(nodeID)
  94. if err != nil {
  95. continue
  96. }
  97. if node.Tags == nil {
  98. node.Tags = make(map[models.TagID]struct{})
  99. }
  100. node.Tags[tag.ID] = struct{}{}
  101. logic.UpsertNode(&node)
  102. }
  103. }()
  104. logic.ReturnSuccessResponseWithJson(w, r, req, "created tag successfully")
  105. }
  106. // @Summary Update Tag
  107. // @Router /api/v1/tags [put]
  108. // @Tags TAG
  109. // @Accept json
  110. // @Success 200 {array} models.SuccessResponse
  111. // @Failure 500 {object} models.ErrorResponse
  112. func updateTag(w http.ResponseWriter, r *http.Request) {
  113. var updateTag models.UpdateTagReq
  114. err := json.NewDecoder(r.Body).Decode(&updateTag)
  115. if err != nil {
  116. logger.Log(0, "error decoding request body: ",
  117. err.Error())
  118. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  119. return
  120. }
  121. tag, err := logic.GetTag(updateTag.ID)
  122. if err != nil {
  123. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  124. return
  125. }
  126. updateTag.NewName = strings.TrimSpace(updateTag.NewName)
  127. var newID models.TagID
  128. if updateTag.NewName != "" {
  129. newID = models.TagID(fmt.Sprintf("%s.%s", tag.Network, updateTag.NewName))
  130. tag.ID = newID
  131. tag.TagName = updateTag.NewName
  132. err = logic.InsertTag(tag)
  133. if err != nil {
  134. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  135. return
  136. }
  137. // delete old Tag entry
  138. logic.DeleteTag(updateTag.ID)
  139. }
  140. go logic.UpdateTag(updateTag, newID)
  141. logic.ReturnSuccessResponse(w, r, "updating tags")
  142. }
  143. // @Summary Delete Tag
  144. // @Router /api/v1/tags [delete]
  145. // @Tags TAG
  146. // @Accept json
  147. // @Success 200 {array} models.SuccessResponse
  148. // @Failure 500 {object} models.ErrorResponse
  149. func deleteTag(w http.ResponseWriter, r *http.Request) {
  150. tagID, _ := url.QueryUnescape(r.URL.Query().Get("tag_id"))
  151. if tagID == "" {
  152. logic.ReturnErrorResponse(w, r, logic.FormatError(errors.New("role is required"), "badrequest"))
  153. return
  154. }
  155. err := logic.DeleteTag(models.TagID(tagID))
  156. if err != nil {
  157. logic.ReturnErrorResponse(w, r, logic.FormatError(err, "badrequest"))
  158. return
  159. }
  160. logic.ReturnSuccessResponse(w, r, "deleted tag "+tagID)
  161. }