dashboards.go 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  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. ErrDashboardsWithSameSlugExists = errors.New("Multiple dashboards with the same slug exists")
  23. ErrDashboardFailedGenerateUniqueUid = errors.New("Failed to generate unique dashboard id")
  24. )
  25. type UpdatePluginDashboardError struct {
  26. PluginId string
  27. }
  28. func (d UpdatePluginDashboardError) Error() string {
  29. return "Dashboard belong to plugin"
  30. }
  31. var (
  32. DashTypeJson = "file"
  33. DashTypeDB = "db"
  34. DashTypeScript = "script"
  35. DashTypeSnapshot = "snapshot"
  36. )
  37. // Dashboard model
  38. type Dashboard struct {
  39. Id int64
  40. Uid string
  41. Slug string
  42. OrgId int64
  43. GnetId int64
  44. Version int
  45. PluginId string
  46. Created time.Time
  47. Updated time.Time
  48. UpdatedBy int64
  49. CreatedBy int64
  50. FolderId int64
  51. IsFolder bool
  52. HasAcl bool
  53. Title string
  54. Data *simplejson.Json
  55. }
  56. // NewDashboard creates a new dashboard
  57. func NewDashboard(title string) *Dashboard {
  58. dash := &Dashboard{}
  59. dash.Data = simplejson.New()
  60. dash.Data.Set("title", title)
  61. dash.Title = title
  62. dash.Created = time.Now()
  63. dash.Updated = time.Now()
  64. dash.UpdateSlug()
  65. return dash
  66. }
  67. // NewDashboardFolder creates a new dashboard folder
  68. func NewDashboardFolder(title string) *Dashboard {
  69. folder := NewDashboard(title)
  70. folder.Data.Set("schemaVersion", 16)
  71. folder.Data.Set("editable", true)
  72. folder.Data.Set("hideControls", true)
  73. return folder
  74. }
  75. // GetTags turns the tags in data json into go string array
  76. func (dash *Dashboard) GetTags() []string {
  77. return dash.Data.Get("tags").MustStringArray()
  78. }
  79. func NewDashboardFromJson(data *simplejson.Json) *Dashboard {
  80. dash := &Dashboard{}
  81. dash.Data = data
  82. dash.Title = dash.Data.Get("title").MustString()
  83. dash.UpdateSlug()
  84. if id, err := dash.Data.Get("id").Float64(); err == nil {
  85. dash.Id = int64(id)
  86. if version, err := dash.Data.Get("version").Float64(); err == nil {
  87. dash.Version = int(version)
  88. dash.Updated = time.Now()
  89. }
  90. } else {
  91. dash.Data.Set("version", 0)
  92. dash.Created = time.Now()
  93. dash.Updated = time.Now()
  94. }
  95. if gnetId, err := dash.Data.Get("gnetId").Float64(); err == nil {
  96. dash.GnetId = int64(gnetId)
  97. }
  98. if uid, err := dash.Data.Get("uid").String(); err == nil {
  99. dash.Uid = uid
  100. }
  101. return dash
  102. }
  103. // GetDashboardModel turns the command into the savable model
  104. func (cmd *SaveDashboardCommand) GetDashboardModel() *Dashboard {
  105. dash := NewDashboardFromJson(cmd.Dashboard)
  106. userId := cmd.UserId
  107. if userId == 0 {
  108. userId = -1
  109. }
  110. if dash.Data.Get("version").MustInt(0) == 0 {
  111. dash.CreatedBy = userId
  112. }
  113. dash.UpdatedBy = userId
  114. dash.OrgId = cmd.OrgId
  115. dash.PluginId = cmd.PluginId
  116. dash.IsFolder = cmd.IsFolder
  117. dash.FolderId = cmd.FolderId
  118. dash.UpdateSlug()
  119. return dash
  120. }
  121. // GetString a
  122. func (dash *Dashboard) GetString(prop string, defaultValue string) string {
  123. return dash.Data.Get(prop).MustString(defaultValue)
  124. }
  125. // UpdateSlug updates the slug
  126. func (dash *Dashboard) UpdateSlug() {
  127. title := dash.Data.Get("title").MustString()
  128. dash.Slug = SlugifyTitle(title)
  129. }
  130. func SlugifyTitle(title string) string {
  131. return slug.Make(strings.ToLower(title))
  132. }
  133. // GetUrl return the html url for a folder if it's folder, otherwise for a dashboard
  134. func (dash *Dashboard) GetUrl() string {
  135. return GetDashboardFolderUrl(dash.IsFolder, dash.Uid, dash.Slug)
  136. }
  137. // Return the html url for a dashboard
  138. func (dash *Dashboard) GenerateUrl() string {
  139. return GetDashboardUrl(dash.Uid, dash.Slug)
  140. }
  141. // GetDashboardFolderUrl return the html url for a folder if it's folder, otherwise for a dashboard
  142. func GetDashboardFolderUrl(isFolder bool, uid string, slug string) string {
  143. if isFolder {
  144. return GetFolderUrl(uid, slug)
  145. }
  146. return GetDashboardUrl(uid, slug)
  147. }
  148. // Return the html url for a dashboard
  149. func GetDashboardUrl(uid string, slug string) string {
  150. return fmt.Sprintf("%s/d/%s/%s", setting.AppSubUrl, uid, slug)
  151. }
  152. // Return the full url for a dashboard
  153. func GetFullDashboardUrl(uid string, slug string) string {
  154. return fmt.Sprintf("%s%s", setting.AppUrl, GetDashboardUrl(uid, slug))
  155. }
  156. // GetFolderUrl return the html url for a folder
  157. func GetFolderUrl(folderUid string, slug string) string {
  158. return fmt.Sprintf("%s/dashboards/f/%s/%s", setting.AppSubUrl, folderUid, slug)
  159. }
  160. //
  161. // COMMANDS
  162. //
  163. type SaveDashboardCommand struct {
  164. Dashboard *simplejson.Json `json:"dashboard" binding:"Required"`
  165. UserId int64 `json:"userId"`
  166. Overwrite bool `json:"overwrite"`
  167. Message string `json:"message"`
  168. OrgId int64 `json:"-"`
  169. RestoredFrom int `json:"-"`
  170. PluginId string `json:"-"`
  171. FolderId int64 `json:"folderId"`
  172. IsFolder bool `json:"isFolder"`
  173. UpdatedAt time.Time
  174. Result *Dashboard
  175. }
  176. type DeleteDashboardCommand struct {
  177. Id int64
  178. OrgId int64
  179. }
  180. //
  181. // QUERIES
  182. //
  183. type GetDashboardQuery struct {
  184. Slug string // required if no Id or Uid is specified
  185. Id int64 // optional if slug is set
  186. Uid string // optional if slug is set
  187. OrgId int64
  188. Result *Dashboard
  189. }
  190. type DashboardTagCloudItem struct {
  191. Term string `json:"term"`
  192. Count int `json:"count"`
  193. }
  194. type GetDashboardTagsQuery struct {
  195. OrgId int64
  196. Result []*DashboardTagCloudItem
  197. }
  198. type GetDashboardsQuery struct {
  199. DashboardIds []int64
  200. Result []*Dashboard
  201. }
  202. type GetDashboardPermissionsForUserQuery struct {
  203. DashboardIds []int64
  204. OrgId int64
  205. UserId int64
  206. OrgRole RoleType
  207. Result []*DashboardPermissionForUser
  208. }
  209. type GetDashboardsByPluginIdQuery struct {
  210. OrgId int64
  211. PluginId string
  212. Result []*Dashboard
  213. }
  214. type GetDashboardSlugByIdQuery struct {
  215. Id int64
  216. Result string
  217. }
  218. type GetDashboardsBySlugQuery struct {
  219. OrgId int64
  220. Slug string
  221. Result []*Dashboard
  222. }
  223. type GetFoldersForSignedInUserQuery struct {
  224. OrgId int64
  225. SignedInUser *SignedInUser
  226. Title string
  227. Result []*DashboardFolder
  228. }
  229. type DashboardFolder struct {
  230. Id int64 `json:"id"`
  231. Title string `json:"title"`
  232. }
  233. type DashboardPermissionForUser struct {
  234. DashboardId int64 `json:"dashboardId"`
  235. Permission PermissionType `json:"permission"`
  236. PermissionName string `json:"permissionName"`
  237. }
  238. type DashboardRef struct {
  239. Uid string
  240. Slug string
  241. }
  242. type GetDashboardRefByIdQuery struct {
  243. Id int64
  244. Result *DashboardRef
  245. }