dashboards.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. package models
  2. import (
  3. "errors"
  4. "fmt"
  5. "strings"
  6. "time"
  7. "github.com/gosimple/slug"
  8. "github.com/grafana/grafana/pkg/components/simplejson"
  9. "github.com/grafana/grafana/pkg/setting"
  10. )
  11. // Typed errors
  12. var (
  13. ErrDashboardNotFound = errors.New("Dashboard not found")
  14. ErrDashboardSnapshotNotFound = errors.New("Dashboard snapshot not found")
  15. ErrDashboardWithSameUIDExists = errors.New("A dashboard with the same uid already exists")
  16. ErrDashboardWithSameNameInFolderExists = errors.New("A dashboard with the same name in the folder already exists")
  17. ErrDashboardVersionMismatch = errors.New("The dashboard has been changed by someone else")
  18. ErrDashboardTitleEmpty = errors.New("Dashboard title cannot be empty")
  19. ErrDashboardFolderCannotHaveParent = errors.New("A Dashboard Folder cannot be added to another folder")
  20. ErrDashboardContainsInvalidAlertData = errors.New("Invalid alert data. Cannot save dashboard")
  21. ErrDashboardFailedToUpdateAlertData = errors.New("Failed to save alert data")
  22. ErrDashboardFailedGenerateUniqueUid = errors.New("Failed to generate unique dashboard uid.")
  23. )
  24. type UpdatePluginDashboardError struct {
  25. PluginId string
  26. }
  27. func (d UpdatePluginDashboardError) Error() string {
  28. return "Dashboard belong to plugin"
  29. }
  30. var (
  31. DashTypeJson = "file"
  32. DashTypeDB = "db"
  33. DashTypeScript = "script"
  34. DashTypeSnapshot = "snapshot"
  35. )
  36. // Dashboard model
  37. type Dashboard struct {
  38. Id int64
  39. Uid string
  40. Slug string
  41. OrgId int64
  42. GnetId int64
  43. Version int
  44. PluginId string
  45. Created time.Time
  46. Updated time.Time
  47. UpdatedBy int64
  48. CreatedBy int64
  49. FolderId int64
  50. IsFolder bool
  51. HasAcl bool
  52. Title string
  53. Data *simplejson.Json
  54. }
  55. // NewDashboard creates a new dashboard
  56. func NewDashboard(title string) *Dashboard {
  57. dash := &Dashboard{}
  58. dash.Data = simplejson.New()
  59. dash.Data.Set("title", title)
  60. dash.Title = title
  61. dash.Created = time.Now()
  62. dash.Updated = time.Now()
  63. dash.UpdateSlug()
  64. return dash
  65. }
  66. // NewDashboardFolder creates a new dashboard folder
  67. func NewDashboardFolder(title string) *Dashboard {
  68. folder := NewDashboard(title)
  69. folder.Data.Set("schemaVersion", 16)
  70. folder.Data.Set("editable", true)
  71. folder.Data.Set("hideControls", true)
  72. return folder
  73. }
  74. // GetTags turns the tags in data json into go string array
  75. func (dash *Dashboard) GetTags() []string {
  76. return dash.Data.Get("tags").MustStringArray()
  77. }
  78. func NewDashboardFromJson(data *simplejson.Json) *Dashboard {
  79. dash := &Dashboard{}
  80. dash.Data = data
  81. dash.Title = dash.Data.Get("title").MustString()
  82. dash.UpdateSlug()
  83. if id, err := dash.Data.Get("id").Float64(); err == nil {
  84. dash.Id = int64(id)
  85. if version, err := dash.Data.Get("version").Float64(); err == nil {
  86. dash.Version = int(version)
  87. dash.Updated = time.Now()
  88. }
  89. } else {
  90. dash.Data.Set("version", 0)
  91. dash.Created = time.Now()
  92. dash.Updated = time.Now()
  93. }
  94. if gnetId, err := dash.Data.Get("gnetId").Float64(); err == nil {
  95. dash.GnetId = int64(gnetId)
  96. }
  97. if uid, err := dash.Data.Get("uid").String(); err == nil {
  98. dash.Uid = uid
  99. }
  100. return dash
  101. }
  102. // GetDashboardModel turns the command into the savable model
  103. func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
  104. dash := NewDashboardFromJson(cmd.Dashboard)
  105. userId := cmd.UserId
  106. if userId == 0 {
  107. userId = -1
  108. }
  109. if dash.Data.Get("version").MustInt(0) == 0 {
  110. dash.CreatedBy = userId
  111. }
  112. dash.UpdatedBy = userId
  113. dash.OrgId = cmd.OrgId
  114. dash.PluginId = cmd.PluginId
  115. dash.IsFolder = cmd.IsFolder
  116. dash.FolderId = cmd.FolderId
  117. dash.UpdateSlug()
  118. return dash
  119. }
  120. // GetString a
  121. func (dash *Dashboard) GetString(prop string, defaultValue string) string {
  122. return dash.Data.Get(prop).MustString(defaultValue)
  123. }
  124. // UpdateSlug updates the slug
  125. func (dash *Dashboard) UpdateSlug() {
  126. title := dash.Data.Get("title").MustString()
  127. dash.Slug = SlugifyTitle(title)
  128. }
  129. func SlugifyTitle(title string) string {
  130. return slug.Make(strings.ToLower(title))
  131. }
  132. // GetUrl return the html url for a folder if it's folder, otherwise for a dashboard
  133. func (dash *Dashboard) GetUrl() string {
  134. return GetDashboardFolderUrl(dash.IsFolder, dash.Uid, dash.Slug)
  135. }
  136. // GetDashboardFolderUrl return the html url for a folder if it's folder, otherwise for a dashboard
  137. func GetDashboardFolderUrl(isFolder bool, uid string, slug string) string {
  138. if isFolder {
  139. return GetFolderUrl(uid, slug)
  140. }
  141. return GetDashboardUrl(uid, slug)
  142. }
  143. // GetDashboardUrl return the html url for a dashboard
  144. func GetDashboardUrl(uid string, slug string) string {
  145. return fmt.Sprintf("%s/d/%s/%s", setting.AppSubUrl, uid, slug)
  146. }
  147. // GetFolderUrl return the html url for a folder
  148. func GetFolderUrl(folderUid string, slug string) string {
  149. return fmt.Sprintf("%s/f/%v/%s", setting.AppSubUrl, folderUid, slug)
  150. }
  151. //
  152. // COMMANDS
  153. //
  154. type SaveDashboardCommand struct {
  155. Dashboard *simplejson.Json `json:"dashboard" binding:"Required"`
  156. UserId int64 `json:"userId"`
  157. Overwrite bool `json:"overwrite"`
  158. Message string `json:"message"`
  159. OrgId int64 `json:"-"`
  160. RestoredFrom int `json:"-"`
  161. PluginId string `json:"-"`
  162. FolderId int64 `json:"folderId"`
  163. IsFolder bool `json:"isFolder"`
  164. UpdatedAt time.Time
  165. Result *Dashboard
  166. }
  167. type DeleteDashboardCommand struct {
  168. Id int64
  169. OrgId int64
  170. }
  171. //
  172. // QUERIES
  173. //
  174. type GetDashboardQuery struct {
  175. Slug string // required if no Id or Uid is specified
  176. Id int64 // optional if slug is set
  177. Uid string // optional if slug is set
  178. OrgId int64
  179. Result *Dashboard
  180. }
  181. type DashboardTagCloudItem struct {
  182. Term string `json:"term"`
  183. Count int `json:"count"`
  184. }
  185. type GetDashboardTagsQuery struct {
  186. OrgId int64
  187. Result []*DashboardTagCloudItem
  188. }
  189. type GetDashboardsQuery struct {
  190. DashboardIds []int64
  191. Result []*Dashboard
  192. }
  193. type GetDashboardsByPluginIdQuery struct {
  194. OrgId int64
  195. PluginId string
  196. Result []*Dashboard
  197. }
  198. type GetDashboardSlugByIdQuery struct {
  199. Id int64
  200. Result string
  201. }