annotations.go 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. package api
  2. import (
  3. "strings"
  4. "time"
  5. "github.com/grafana/grafana/pkg/api/dtos"
  6. "github.com/grafana/grafana/pkg/components/simplejson"
  7. "github.com/grafana/grafana/pkg/middleware"
  8. "github.com/grafana/grafana/pkg/services/annotations"
  9. )
  10. func GetAnnotations(c *middleware.Context) Response {
  11. query := &annotations.ItemQuery{
  12. From: c.QueryInt64("from") / 1000,
  13. To: c.QueryInt64("to") / 1000,
  14. OrgId: c.OrgId,
  15. AlertId: c.QueryInt64("alertId"),
  16. DashboardId: c.QueryInt64("dashboardId"),
  17. PanelId: c.QueryInt64("panelId"),
  18. Limit: c.QueryInt64("limit"),
  19. Tags: c.QueryStrings("tags"),
  20. }
  21. repo := annotations.GetRepository()
  22. items, err := repo.Find(query)
  23. if err != nil {
  24. return ApiError(500, "Failed to get annotations", err)
  25. }
  26. for _, item := range items {
  27. if item.Email != "" {
  28. item.AvatarUrl = dtos.GetGravatarUrl(item.Email)
  29. }
  30. item.Time = item.Time * 1000
  31. }
  32. return Json(200, items)
  33. }
  34. type CreateAnnotationError struct {
  35. message string
  36. }
  37. func (e *CreateAnnotationError) Error() string {
  38. return e.message
  39. }
  40. func PostAnnotation(c *middleware.Context, cmd dtos.PostAnnotationsCmd) Response {
  41. repo := annotations.GetRepository()
  42. if cmd.Text == "" {
  43. err := &CreateAnnotationError{"text field should not be empty"}
  44. return ApiError(500, "Failed to save annotation", err)
  45. }
  46. item := annotations.Item{
  47. OrgId: c.OrgId,
  48. UserId: c.UserId,
  49. DashboardId: cmd.DashboardId,
  50. PanelId: cmd.PanelId,
  51. Epoch: cmd.Time / 1000,
  52. Text: cmd.Text,
  53. Data: cmd.Data,
  54. Tags: cmd.Tags,
  55. }
  56. if item.Epoch == 0 {
  57. item.Epoch = time.Now().Unix()
  58. }
  59. if err := repo.Save(&item); err != nil {
  60. return ApiError(500, "Failed to save annotation", err)
  61. }
  62. // handle regions
  63. if cmd.IsRegion {
  64. item.RegionId = item.Id
  65. if item.Data == nil {
  66. item.Data = simplejson.New()
  67. }
  68. if err := repo.Update(&item); err != nil {
  69. return ApiError(500, "Failed set regionId on annotation", err)
  70. }
  71. item.Id = 0
  72. item.Epoch = cmd.TimeEnd / 1000
  73. if err := repo.Save(&item); err != nil {
  74. return ApiError(500, "Failed save annotation for region end time", err)
  75. }
  76. }
  77. return ApiSuccess("Annotation added")
  78. }
  79. func formatGraphiteAnnotation(what string, data string) string {
  80. text := what
  81. if data != "" {
  82. text = text + "\n" + data
  83. }
  84. return text
  85. }
  86. func PostGraphiteAnnotation(c *middleware.Context, cmd dtos.PostGraphiteAnnotationsCmd) Response {
  87. repo := annotations.GetRepository()
  88. if cmd.What == "" {
  89. err := &CreateAnnotationError{"what field should not be empty"}
  90. return ApiError(500, "Failed to save Graphite annotation", err)
  91. }
  92. if cmd.When == 0 {
  93. cmd.When = time.Now().Unix()
  94. }
  95. text := formatGraphiteAnnotation(cmd.What, cmd.Data)
  96. // Support tags in prior to Graphite 0.10.0 format (string of tags separated by space)
  97. var tagsArray []string
  98. switch tags := cmd.Tags.(type) {
  99. case string:
  100. if tags != "" {
  101. tagsArray = strings.Split(tags, " ")
  102. } else {
  103. tagsArray = []string{}
  104. }
  105. case []interface{}:
  106. for _, t := range tags {
  107. if tagStr, ok := t.(string); ok {
  108. tagsArray = append(tagsArray, tagStr)
  109. } else {
  110. err := &CreateAnnotationError{"tag should be a string"}
  111. return ApiError(500, "Failed to save Graphite annotation", err)
  112. }
  113. }
  114. default:
  115. err := &CreateAnnotationError{"unsupported tags format"}
  116. return ApiError(500, "Failed to save Graphite annotation", err)
  117. }
  118. item := annotations.Item{
  119. OrgId: c.OrgId,
  120. UserId: c.UserId,
  121. Epoch: cmd.When,
  122. Text: text,
  123. Tags: tagsArray,
  124. }
  125. if err := repo.Save(&item); err != nil {
  126. return ApiError(500, "Failed to save Graphite annotation", err)
  127. }
  128. return ApiSuccess("Graphite annotation added")
  129. }
  130. func UpdateAnnotation(c *middleware.Context, cmd dtos.UpdateAnnotationsCmd) Response {
  131. annotationId := c.ParamsInt64(":annotationId")
  132. repo := annotations.GetRepository()
  133. item := annotations.Item{
  134. OrgId: c.OrgId,
  135. UserId: c.UserId,
  136. Id: annotationId,
  137. Epoch: cmd.Time / 1000,
  138. Text: cmd.Text,
  139. Tags: cmd.Tags,
  140. }
  141. if err := repo.Update(&item); err != nil {
  142. return ApiError(500, "Failed to update annotation", err)
  143. }
  144. if cmd.IsRegion {
  145. itemRight := item
  146. itemRight.RegionId = item.Id
  147. itemRight.Epoch = cmd.TimeEnd / 1000
  148. // We don't know id of region right event, so set it to 0 and find then using query like
  149. // ... WHERE region_id = <item.RegionId> AND id != <item.RegionId> ...
  150. itemRight.Id = 0
  151. if err := repo.Update(&itemRight); err != nil {
  152. return ApiError(500, "Failed to update annotation for region end time", err)
  153. }
  154. }
  155. return ApiSuccess("Annotation updated")
  156. }
  157. func DeleteAnnotations(c *middleware.Context, cmd dtos.DeleteAnnotationsCmd) Response {
  158. repo := annotations.GetRepository()
  159. err := repo.Delete(&annotations.DeleteParams{
  160. AlertId: cmd.PanelId,
  161. DashboardId: cmd.DashboardId,
  162. PanelId: cmd.PanelId,
  163. })
  164. if err != nil {
  165. return ApiError(500, "Failed to delete annotations", err)
  166. }
  167. return ApiSuccess("Annotations deleted")
  168. }
  169. func DeleteAnnotationById(c *middleware.Context) Response {
  170. repo := annotations.GetRepository()
  171. annotationId := c.ParamsInt64(":annotationId")
  172. err := repo.Delete(&annotations.DeleteParams{
  173. Id: annotationId,
  174. })
  175. if err != nil {
  176. return ApiError(500, "Failed to delete annotation", err)
  177. }
  178. return ApiSuccess("Annotation deleted")
  179. }
  180. func DeleteAnnotationRegion(c *middleware.Context) Response {
  181. repo := annotations.GetRepository()
  182. regionId := c.ParamsInt64(":regionId")
  183. err := repo.Delete(&annotations.DeleteParams{
  184. RegionId: regionId,
  185. })
  186. if err != nil {
  187. return ApiError(500, "Failed to delete annotation region", err)
  188. }
  189. return ApiSuccess("Annotation region deleted")
  190. }