The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/pkg/api/folder.go

321 lines
9.3 KiB

package api
import (
"errors"
"fmt"
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/api/apierrors"
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/dashboards"
"github.com/grafana/grafana/pkg/services/guardian"
LibraryPanels: removes feature toggle (#33839) * WIP: intial structure * Refactor: adds create library element endpoint * Feature: adds delete library element * wip * Refactor: adds get api * Refactor: adds get all api * Refactor: adds patch api * Refactor: changes to library_element_connection * Refactor: add get connections api * wip: in the middle of refactor * wip * Refactor: consolidating both api:s * Refactor: points front end to library elements api * Tests: Fixes broken test * LibraryPanels: removes feature toggle * Fix: fixes delete library elements in folder and adds tests * Tests: fixes snapshot * Refactor: adds service interfaces so they can be easily mocked * Refactor: changes order of tabs in manage folder * Refactor: fixes so link does not cover whole card * Refactor: fixes index string name * Update pkg/services/libraryelements/libraryelements.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update pkg/services/libraryelements/libraryelements_permissions_test.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update pkg/services/libraryelements/database.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Chore: changes after PR comments * Update libraryelements.go * Update libraryelements.go * Chore: updates after PR comments * Chore: trying to fix build error * Refactor: fixed stupid mistake * Update libraryelements.go * Chore: tries to fix build errors * Refactor: trying to fix MySQL key length * Update libraryelements.go * Update pkg/services/libraryelements/libraryelements.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update pkg/services/librarypanels/librarypanels.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Refactor: changes after PR comments * Refactor: changes after PR comments * Tests: fixes tests * Refactor: renames connections to connectedDashboards Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
"github.com/grafana/grafana/pkg/services/libraryelements"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
// swagger:route GET /folders folders getFolders
//
// Get all folders.
//
// Returns all folders that the authenticated user has permission to view.
//
// Responses:
// 200: getFoldersResponse
// 401: unauthorisedError
// 403: forbiddenError
// 500: internalServerError
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
func (hs *HTTPServer) GetFolders(c *models.ReqContext) response.Response {
folders, err := hs.folderService.GetFolders(c.Req.Context(), c.SignedInUser, c.OrgId, c.QueryInt64("limit"), c.QueryInt64("page"))
if err != nil {
return apierrors.ToFolderErrorResponse(err)
}
uids := make(map[string]bool, len(folders))
result := make([]dtos.FolderSearchHit, 0)
for _, f := range folders {
uids[f.Uid] = true
result = append(result, dtos.FolderSearchHit{
Id: f.Id,
Uid: f.Uid,
Title: f.Title,
})
}
metadata := hs.getMultiAccessControlMetadata(c, c.OrgId, dashboards.ScopeFoldersPrefix, uids)
if len(metadata) > 0 {
for i := range result {
result[i].AccessControl = metadata[result[i].Uid]
}
}
return response.JSON(http.StatusOK, result)
}
// swagger:route GET /folders/{folder_uid} folders getFolderByUID
//
// Get folder by uid.
//
// Responses:
// 200: folderResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
func (hs *HTTPServer) GetFolderByUID(c *models.ReqContext) response.Response {
folder, err := hs.folderService.GetFolderByUID(c.Req.Context(), c.SignedInUser, c.OrgId, web.Params(c.Req)[":uid"])
if err != nil {
return apierrors.ToFolderErrorResponse(err)
}
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
return response.JSON(http.StatusOK, hs.toFolderDto(c, g, folder))
}
// swagger:route GET /folders/id/{folder_id} folders getFolderByID
//
// Get folder by id.
//
// Returns the folder identified by id.
//
// Responses:
// 200: folderResponse
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
PluginManager: Make Plugins, Renderer and DataSources non-global (#31866) * PluginManager: Make Plugins and DataSources non-global Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Replace outdated command Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix build Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * DashboardService: Ensure it gets constructed with necessary parameters Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove FocusConvey Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Remove dead code Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Undo interface changes Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Backend: Move tsdbifaces.RequestHandler to plugins.DataRequestHandler Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Rename to DataSourceCount Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Consolidate dashboard interfaces into one Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix test Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com> * Fix dashboard integration tests Signed-off-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
func (hs *HTTPServer) GetFolderByID(c *models.ReqContext) response.Response {
id, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
if err != nil {
return response.Error(http.StatusBadRequest, "id is invalid", err)
}
folder, err := hs.folderService.GetFolderByID(c.Req.Context(), c.SignedInUser, id, c.OrgId)
if err != nil {
return apierrors.ToFolderErrorResponse(err)
}
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
return response.JSON(http.StatusOK, hs.toFolderDto(c, g, folder))
}
// swagger:route POST /folders folders createFolder
//
// Create folder.
//
// Responses:
// 200: folderResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 409: conflictError
// 500: internalServerError
func (hs *HTTPServer) CreateFolder(c *models.ReqContext) response.Response {
cmd := models.CreateFolderCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
folder, err := hs.folderService.CreateFolder(c.Req.Context(), c.SignedInUser, c.OrgId, cmd.Title, cmd.Uid)
if err != nil {
return apierrors.ToFolderErrorResponse(err)
}
g := guardian.New(c.Req.Context(), folder.Id, c.OrgId, c.SignedInUser)
return response.JSON(http.StatusOK, hs.toFolderDto(c, g, folder))
}
// swagger:route PUT /folders/{folder_uid} folders updateFolder
//
// Update folder.
//
// Responses:
// 200: folderResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 409: conflictError
// 500: internalServerError
func (hs *HTTPServer) UpdateFolder(c *models.ReqContext) response.Response {
cmd := models.UpdateFolderCommand{}
if err := web.Bind(c.Req, &cmd); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
err := hs.folderService.UpdateFolder(c.Req.Context(), c.SignedInUser, c.OrgId, web.Params(c.Req)[":uid"], &cmd)
if err != nil {
return apierrors.ToFolderErrorResponse(err)
}
g := guardian.New(c.Req.Context(), cmd.Result.Id, c.OrgId, c.SignedInUser)
return response.JSON(http.StatusOK, hs.toFolderDto(c, g, cmd.Result))
}
// swagger:route DELETE /folders/{folder_uid} folders deleteFolder
//
// Delete folder.
//
// Deletes an existing folder identified by UID along with all dashboards (and their alerts) stored in the folder. This operation cannot be reverted.
//
// Responses:
// 200: deleteFolderResponse
// 400: badRequestError
// 401: unauthorisedError
// 403: forbiddenError
// 404: notFoundError
// 500: internalServerError
func (hs *HTTPServer) DeleteFolder(c *models.ReqContext) response.Response { // temporarily adding this function to HTTPServer, will be removed from HTTPServer when librarypanels featuretoggle is removed
err := hs.LibraryElementService.DeleteLibraryElementsInFolder(c.Req.Context(), c.SignedInUser, web.Params(c.Req)[":uid"])
LibraryPanels: removes feature toggle (#33839) * WIP: intial structure * Refactor: adds create library element endpoint * Feature: adds delete library element * wip * Refactor: adds get api * Refactor: adds get all api * Refactor: adds patch api * Refactor: changes to library_element_connection * Refactor: add get connections api * wip: in the middle of refactor * wip * Refactor: consolidating both api:s * Refactor: points front end to library elements api * Tests: Fixes broken test * LibraryPanels: removes feature toggle * Fix: fixes delete library elements in folder and adds tests * Tests: fixes snapshot * Refactor: adds service interfaces so they can be easily mocked * Refactor: changes order of tabs in manage folder * Refactor: fixes so link does not cover whole card * Refactor: fixes index string name * Update pkg/services/libraryelements/libraryelements.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update pkg/services/libraryelements/libraryelements_permissions_test.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update pkg/services/libraryelements/database.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Chore: changes after PR comments * Update libraryelements.go * Update libraryelements.go * Chore: updates after PR comments * Chore: trying to fix build error * Refactor: fixed stupid mistake * Update libraryelements.go * Chore: tries to fix build errors * Refactor: trying to fix MySQL key length * Update libraryelements.go * Update pkg/services/libraryelements/libraryelements.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Update pkg/services/librarypanels/librarypanels.go Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com> * Refactor: changes after PR comments * Refactor: changes after PR comments * Tests: fixes tests * Refactor: renames connections to connectedDashboards Co-authored-by: Arve Knudsen <arve.knudsen@gmail.com>
4 years ago
if err != nil {
if errors.Is(err, libraryelements.ErrFolderHasConnectedLibraryElements) {
return response.Error(403, "Folder could not be deleted because it contains library elements in use", err)
}
return apierrors.ToFolderErrorResponse(err)
}
uid := web.Params(c.Req)[":uid"]
f, err := hs.folderService.DeleteFolder(c.Req.Context(), c.SignedInUser, c.OrgId, uid, c.QueryBool("forceDeleteRules"))
if err != nil {
return apierrors.ToFolderErrorResponse(err)
}
return response.JSON(http.StatusOK, util.DynMap{
"title": f.Title,
"message": fmt.Sprintf("Folder %s deleted", f.Title),
"id": f.Id,
})
}
func (hs *HTTPServer) toFolderDto(c *models.ReqContext, g guardian.DashboardGuardian, folder *models.Folder) dtos.Folder {
canEdit, _ := g.CanEdit()
canSave, _ := g.CanSave()
canAdmin, _ := g.CanAdmin()
Access control: Use access control for dashboard and folder (#44702) * Add actions and scopes * add resource service for dashboard and folder * Add dashboard guardian with fgac permission evaluation * Add CanDelete function to guardian interface * Add CanDelete property to folder and dashboard dto and set values * change to correct function name * Add accesscontrol to folder endpoints * add access control to dashboard endpoints * check access for nav links * Add fixed roles for dashboard and folders * use correct package * add hack to override guardian Constructor if accesscontrol is enabled * Add services * Add function to handle api backward compatability * Add permissionServices to HttpServer * Set permission when new dashboard is created * Add default permission when creating new dashboard * Set default permission when creating folder and dashboard * Add access control filter for dashboard search * Add to accept list * Add accesscontrol to dashboardimport * Disable access control in tests * Add check to see if user is allow to create a dashboard * Use SetPermissions * Use function to set several permissions at once * remove permissions for folder and dashboard on delete * update required permission * set permission for provisioning * Add CanCreate to dashboard guardian and set correct permisisons for provisioning * Dont set admin on folder / dashboard creation * Add dashboard and folder permission migrations * Add tests for CanCreate * Add roles and update descriptions * Solve uid to id for dashboard and folder permissions * Add folder and dashboard actions to permission filter * Handle viewer_can_edit flag * set folder and dashboard permissions services * Add dashboard permissions when importing a new dashboard * Set access control permissions on provisioning * Pass feature flags and only set permissions if access control is enabled * only add default permissions for folders and dashboards without folders * Batch create permissions in migrations * Remove `dashboards:edit` action * Remove unused function from interface * Update pkg/services/guardian/accesscontrol_guardian_test.go Co-authored-by: Gabriel MABILLE <gamab@users.noreply.github.com> Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
3 years ago
canDelete, _ := g.CanDelete()
// Finding creator and last updater of the folder
Fix goconst issues See, $ gometalinter --vendor --disable-all --enable=goconst --disable=gotype --deadline=6m ./... build.go:113:15:warning: 2 other occurrence(s) of "linux" found in: build.go:119:15 build.go:491:34 (goconst) build.go:119:15:warning: 2 other occurrence(s) of "linux" found in: build.go:113:15 build.go:491:34 (goconst) build.go:491:34:warning: 2 other occurrence(s) of "linux" found in: build.go:113:15 build.go:119:15 (goconst) build.go:381:21:warning: 2 other occurrence(s) of "windows" found in: build.go:423:13 build.go:487:13 (goconst) build.go:423:13:warning: 2 other occurrence(s) of "windows" found in: build.go:381:21 build.go:487:13 (goconst) build.go:487:13:warning: 2 other occurrence(s) of "windows" found in: build.go:381:21 build.go:423:13 (goconst) pkg/api/dashboard.go:67:22:warning: 5 other occurrence(s) of "Anonymous" found in: pkg/api/dashboard.go:67:35 pkg/api/dashboard.go:131:10 pkg/api/dashboard.go:406:13 pkg/api/folder.go:98:22 pkg/api/folder.go:98:35 (goconst) pkg/api/dashboard.go:67:35:warning: 5 other occurrence(s) of "Anonymous" found in: pkg/api/dashboard.go:67:22 pkg/api/dashboard.go:131:10 pkg/api/dashboard.go:406:13 pkg/api/folder.go:98:22 pkg/api/folder.go:98:35 (goconst) pkg/api/dashboard.go:131:10:warning: 5 other occurrence(s) of "Anonymous" found in: pkg/api/dashboard.go:67:22 pkg/api/dashboard.go:67:35 pkg/api/dashboard.go:406:13 pkg/api/folder.go:98:22 pkg/api/folder.go:98:35 (goconst) pkg/api/dashboard.go:406:13:warning: 5 other occurrence(s) of "Anonymous" found in: pkg/api/dashboard.go:67:22 pkg/api/dashboard.go:67:35 pkg/api/dashboard.go:131:10 pkg/api/folder.go:98:22 pkg/api/folder.go:98:35 (goconst) pkg/api/folder.go:98:22:warning: 5 other occurrence(s) of "Anonymous" found in: pkg/api/dashboard.go:67:22 pkg/api/dashboard.go:67:35 pkg/api/dashboard.go:131:10 pkg/api/dashboard.go:406:13 pkg/api/folder.go:98:35 (goconst) pkg/api/folder.go:98:35:warning: 5 other occurrence(s) of "Anonymous" found in: pkg/api/dashboard.go:67:22 pkg/api/dashboard.go:67:35 pkg/api/dashboard.go:131:10 pkg/api/dashboard.go:406:13 pkg/api/folder.go:98:22 (goconst) pkg/api/index.go:63:47:warning: 2 other occurrence(s) of "light" found in: pkg/api/index.go:91:22 pkg/api/index.go:93:16 (goconst) pkg/api/index.go:91:22:warning: 2 other occurrence(s) of "light" found in: pkg/api/index.go:63:47 pkg/api/index.go:93:16 (goconst) pkg/api/index.go:93:16:warning: 2 other occurrence(s) of "light" found in: pkg/api/index.go:63:47 pkg/api/index.go:91:22 (goconst) pkg/components/null/float.go:71:25:warning: 2 other occurrence(s) of "null" found in: pkg/components/null/float.go:103:10 pkg/components/null/float.go:112:10 (goconst) pkg/components/null/float.go:103:10:warning: 2 other occurrence(s) of "null" found in: pkg/components/null/float.go:71:25 pkg/components/null/float.go:112:10 (goconst) pkg/components/null/float.go:112:10:warning: 2 other occurrence(s) of "null" found in: pkg/components/null/float.go:71:25 pkg/components/null/float.go:103:10 (goconst) pkg/services/alerting/notifiers/pagerduty.go:79:16:warning: 2 other occurrence(s) of "Triggered metrics:\n\n" found in: pkg/services/alerting/notifiers/kafka.go:64:16 pkg/services/alerting/notifiers/opsgenie.go:98:16 (goconst) pkg/services/alerting/notifiers/kafka.go:64:16:warning: 2 other occurrence(s) of "Triggered metrics:\n\n" found in: pkg/services/alerting/notifiers/pagerduty.go:79:16 pkg/services/alerting/notifiers/opsgenie.go:98:16 (goconst) pkg/services/alerting/notifiers/opsgenie.go:98:16:warning: 2 other occurrence(s) of "Triggered metrics:\n\n" found in: pkg/services/alerting/notifiers/pagerduty.go:79:16 pkg/services/alerting/notifiers/kafka.go:64:16 (goconst) pkg/social/social.go:85:11:warning: 2 other occurrence(s) of "grafana_com" found in: pkg/social/social.go:162:14 pkg/social/social.go:197:11 (goconst) pkg/social/social.go:162:14:warning: 2 other occurrence(s) of "grafana_com" found in: pkg/social/social.go:85:11 pkg/social/social.go:197:11 (goconst) pkg/social/social.go:197:11:warning: 2 other occurrence(s) of "grafana_com" found in: pkg/social/social.go:85:11 pkg/social/social.go:162:14 (goconst) pkg/tsdb/elasticsearch/time_series_query.go:92:17:warning: 3 other occurrence(s) of "count" found in: pkg/tsdb/elasticsearch/response_parser.go:152:8 pkg/tsdb/elasticsearch/response_parser.go:167:31 pkg/tsdb/elasticsearch/response_parser.go:315:9 (goconst) pkg/tsdb/elasticsearch/response_parser.go:152:8:warning: 3 other occurrence(s) of "count" found in: pkg/tsdb/elasticsearch/time_series_query.go:92:17 pkg/tsdb/elasticsearch/response_parser.go:167:31 pkg/tsdb/elasticsearch/response_parser.go:315:9 (goconst) pkg/tsdb/elasticsearch/response_parser.go:167:31:warning: 3 other occurrence(s) of "count" found in: pkg/tsdb/elasticsearch/time_series_query.go:92:17 pkg/tsdb/elasticsearch/response_parser.go:152:8 pkg/tsdb/elasticsearch/response_parser.go:315:9 (goconst) pkg/tsdb/elasticsearch/response_parser.go:315:9:warning: 3 other occurrence(s) of "count" found in: pkg/tsdb/elasticsearch/time_series_query.go:92:17 pkg/tsdb/elasticsearch/response_parser.go:152:8 pkg/tsdb/elasticsearch/response_parser.go:167:31 (goconst) pkg/tsdb/elasticsearch/time_series_query.go:78:9:warning: 2 other occurrence(s) of "date_histogram" found in: pkg/tsdb/elasticsearch/response_parser.go:84:22 pkg/tsdb/elasticsearch/response_parser.go:369:24 (goconst) pkg/tsdb/elasticsearch/response_parser.go:84:22:warning: 2 other occurrence(s) of "date_histogram" found in: pkg/tsdb/elasticsearch/time_series_query.go:78:9 pkg/tsdb/elasticsearch/response_parser.go:369:24 (goconst) pkg/tsdb/elasticsearch/response_parser.go:369:24:warning: 2 other occurrence(s) of "date_histogram" found in: pkg/tsdb/elasticsearch/time_series_query.go:78:9 pkg/tsdb/elasticsearch/response_parser.go:84:22 (goconst)
7 years ago
updater, creator := anonString, anonString
if folder.CreatedBy > 0 {
creator = hs.getUserLogin(c.Req.Context(), folder.CreatedBy)
}
if folder.UpdatedBy > 0 {
updater = hs.getUserLogin(c.Req.Context(), folder.UpdatedBy)
}
return dtos.Folder{
Id: folder.Id,
Uid: folder.Uid,
Title: folder.Title,
Url: folder.Url,
HasACL: folder.HasACL,
CanSave: canSave,
CanEdit: canEdit,
CanAdmin: canAdmin,
CanDelete: canDelete,
CreatedBy: creator,
Created: folder.Created,
UpdatedBy: updater,
Updated: folder.Updated,
Version: folder.Version,
AccessControl: hs.getAccessControlMetadata(c, c.OrgId, dashboards.ScopeFoldersPrefix, folder.Uid),
}
}
// swagger:parameters getFolders
type GetFoldersParams struct {
// Limit the maximum number of folders to return
// in:query
// required:false
// default:1000
Limit int64 `json:"limit"`
// Page index for starting fetching folders
// in:query
// required:false
// default:1
Page int64 `json:"page"`
}
// swagger:parameters getFolderByUID
type GetFolderByUIDParams struct {
// in:path
// required:true
FolderUID string `json:"folder_uid"`
}
// swagger:parameters updateFolder
type UpdateFolderParams struct {
// in:path
// required:true
FolderUID string `json:"folder_uid"`
// To change the unique identifier (uid), provide another one.
// To overwrite an existing folder with newer version, set `overwrite` to `true`.
// Provide the current version to safelly update the folder: if the provided version differs from the stored one the request will fail, unless `overwrite` is `true`.
//
// in:body
// required:true
Body models.UpdateFolderCommand `json:"body"`
}
// swagger:parameters getFolderByID
type GetFolderByIDParams struct {
// in:path
// required:true
FolderID int64 `json:"folder_id"`
}
// swagger:parameters createFolder
type CreateFolderParams struct {
// in:body
// required:true
Body models.CreateFolderCommand `json:"body"`
}
// swagger:parameters deleteFolder
type DeleteFolderParams struct {
// in:path
// required:true
FolderUID string `json:"folder_uid"`
// If `true` any Grafana 8 Alerts under this folder will be deleted.
// Set to `false` so that the request will fail if the folder contains any Grafana 8 Alerts.
// in:query
// required:false
// default:false
ForceDeleteRules bool `json:"forceDeleteRules"`
}
// swagger:response getFoldersResponse
type GetFoldersResponse struct {
// The response message
// in: body
Body []dtos.FolderSearchHit `json:"body"`
}
// swagger:response folderResponse
type FolderResponse struct {
// The response message
// in: body
Body dtos.Folder `json:"body"`
}
// swagger:response deleteFolderResponse
type DeleteFolderResponse struct {
// The response message
// in: body
Body struct {
// ID Identifier of the deleted folder.
// required: true
// example: 65
ID int64 `json:"id"`
// Title of the deleted folder.
// required: true
// example: My Folder
Title string `json:"title"`
// Message Message of the deleted folder.
// required: true
// example: Folder My Folder deleted
Message string `json:"message"`
} `json:"body"`
}