func ProxyDataSourceRequest(c *middleware.Context) { c.TimeRequest(metrics.M_DataSource_ProxyReq_Timer) ds, err := getDatasource(c.ParamsInt64(":id"), c.OrgId) if err != nil { c.JsonApiErr(500, "Unable to load datasource meta data", err) return } targetUrl, _ := url.Parse(ds.Url) if len(setting.DataProxyWhiteList) > 0 { if _, exists := setting.DataProxyWhiteList[targetUrl.Host]; !exists { c.JsonApiErr(403, "Data proxy hostname and ip are not included in whitelist", nil) return } } if ds.Type == m.DS_CLOUDWATCH { cloudwatch.HandleRequest(c, ds) } else { proxyPath := c.Params("*") proxy := NewReverseProxy(ds, proxyPath, targetUrl) proxy.Transport = dataProxyTransport proxy.ServeHTTP(c.Resp, c.Req.Request) c.Resp.Header().Del("Set-Cookie") } }
func ProxyDataSourceRequest(c *middleware.Context) { c.TimeRequest(metrics.M_DataSource_ProxyReq_Timer) ds, err := getDatasource(c.ParamsInt64(":id"), c.OrgId) if err != nil { c.JsonApiErr(500, "Unable to load datasource meta data", err) return } if ds.Type == m.DS_CLOUDWATCH { cloudwatch.HandleRequest(c, ds) return } if ds.Type == m.DS_INFLUXDB { if c.Query("db") != ds.Database { c.JsonApiErr(403, "Datasource is not configured to allow this database", nil) return } } targetUrl, _ := url.Parse(ds.Url) if len(setting.DataProxyWhiteList) > 0 { if _, exists := setting.DataProxyWhiteList[targetUrl.Host]; !exists { c.JsonApiErr(403, "Data proxy hostname and ip are not included in whitelist", nil) return } } proxyPath := c.Params("*") if ds.Type == m.DS_ES { if c.Req.Request.Method == "DELETE" { c.JsonApiErr(403, "Deletes not allowed on proxied Elasticsearch datasource", nil) return } if c.Req.Request.Method == "PUT" { c.JsonApiErr(403, "Puts not allowed on proxied Elasticsearch datasource", nil) return } if c.Req.Request.Method == "POST" && proxyPath != "_msearch" { c.JsonApiErr(403, "Posts not allowed on proxied Elasticsearch datasource except on /_msearch", nil) return } } proxy := NewReverseProxy(ds, proxyPath, targetUrl) proxy.Transport, err = ds.GetHttpTransport() if err != nil { c.JsonApiErr(400, "Unable to load TLS certificate", err) return } logProxyRequest(ds.Type, c) proxy.ServeHTTP(c.Resp, c.Req.Request) c.Resp.Header().Del("Set-Cookie") }
func PostDashboard(c *middleware.Context, cmd m.SaveDashboardCommand) Response { cmd.OrgId = c.OrgId if !c.IsSignedIn { cmd.UserId = -1 } else { cmd.UserId = c.UserId } dash := cmd.GetDashboardModel() if dash.Id == 0 { limitReached, err := middleware.QuotaReached(c, "dashboard") if err != nil { return ApiError(500, "failed to get quota", err) } if limitReached { return ApiError(403, "Quota reached", nil) } } err := bus.Dispatch(&cmd) if err != nil { if err == m.ErrDashboardWithSameNameExists { return Json(412, util.DynMap{"status": "name-exists", "message": err.Error()}) } if err == m.ErrDashboardVersionMismatch { return Json(412, util.DynMap{"status": "version-mismatch", "message": err.Error()}) } if pluginErr, ok := err.(m.UpdatePluginDashboardError); ok { message := "The dashboard belongs to plugin " + pluginErr.PluginId + "." // look up plugin name if pluginDef, exist := plugins.Plugins[pluginErr.PluginId]; exist { message = "The dashboard belongs to plugin " + pluginDef.Name + "." } return Json(412, util.DynMap{"status": "plugin-dashboard", "message": message}) } if err == m.ErrDashboardNotFound { return Json(404, util.DynMap{"status": "not-found", "message": err.Error()}) } return ApiError(500, "Failed to save dashboard", err) } if setting.AlertingEnabled { alertCmd := alerting.UpdateDashboardAlertsCommand{ OrgId: c.OrgId, UserId: c.UserId, Dashboard: cmd.Result, } if err := bus.Dispatch(&alertCmd); err != nil { return ApiError(500, "Failed to save alerts", err) } } c.TimeRequest(metrics.M_Api_Dashboard_Save) return Json(200, util.DynMap{"status": "success", "slug": cmd.Result.Slug, "version": cmd.Result.Version}) }
func GetDashboard(c *middleware.Context) { slug := strings.ToLower(c.Params(":slug")) query := m.GetDashboardQuery{Slug: slug, OrgId: c.OrgId} err := bus.Dispatch(&query) if err != nil { c.JsonApiErr(404, "Dashboard not found", nil) return } isStarred, err := isDashboardStarredByUser(c, query.Result.Id) if err != nil { c.JsonApiErr(500, "Error while checking if dashboard was starred by user", err) return } dash := query.Result // Finding creator and last updater of the dashboard updater, creator := "Anonymous", "Anonymous" if dash.UpdatedBy > 0 { updater = getUserLogin(dash.UpdatedBy) } if dash.CreatedBy > 0 { creator = getUserLogin(dash.CreatedBy) } dto := dtos.DashboardFullWithMeta{ Dashboard: dash.Data, Meta: dtos.DashboardMeta{ IsStarred: isStarred, Slug: slug, Type: m.DashTypeDB, CanStar: c.IsSignedIn, CanSave: c.OrgRole == m.ROLE_ADMIN || c.OrgRole == m.ROLE_EDITOR, CanEdit: canEditDashboard(c.OrgRole), Created: dash.Created, Updated: dash.Updated, UpdatedBy: updater, CreatedBy: creator, Version: dash.Version, }, } c.TimeRequest(metrics.M_Api_Dashboard_Get) c.JSON(200, dto) }
func PostDashboard(c *middleware.Context, cmd m.SaveDashboardCommand) { cmd.OrgId = c.OrgId if !c.IsSignedIn { cmd.UserId = -1 } else { cmd.UserId = c.UserId } dash := cmd.GetDashboardModel() if dash.Id == 0 { limitReached, err := middleware.QuotaReached(c, "dashboard") if err != nil { c.JsonApiErr(500, "failed to get quota", err) return } if limitReached { c.JsonApiErr(403, "Quota reached", nil) return } } err := bus.Dispatch(&cmd) if err != nil { if err == m.ErrDashboardWithSameNameExists { c.JSON(412, util.DynMap{"status": "name-exists", "message": err.Error()}) return } if err == m.ErrDashboardVersionMismatch { c.JSON(412, util.DynMap{"status": "version-mismatch", "message": err.Error()}) return } if err == m.ErrDashboardNotFound { c.JSON(404, util.DynMap{"status": "not-found", "message": err.Error()}) return } c.JsonApiErr(500, "Failed to save dashboard", err) return } c.TimeRequest(metrics.M_Api_Dashboard_Save) c.JSON(200, util.DynMap{"status": "success", "slug": cmd.Result.Slug, "version": cmd.Result.Version}) }
func Search(c *middleware.Context) { query := c.Query("query") tags := c.QueryStrings("tag") starred := c.Query("starred") limit := c.QueryInt("limit") if limit == 0 { limit = 1000 } dbids := make([]int, 0) for _, id := range c.QueryStrings("dashboardIds") { dashboardId, err := strconv.Atoi(id) if err == nil { dbids = append(dbids, dashboardId) } } searchQuery := search.Query{ Title: query, Tags: tags, UserId: c.UserId, Limit: limit, IsStarred: starred == "true", OrgId: c.OrgId, DashboardIds: dbids, } err := bus.Dispatch(&searchQuery) if err != nil { c.JsonApiErr(500, "Search failed", err) return } c.TimeRequest(metrics.M_Api_Dashboard_Search) c.JSON(200, searchQuery.Result) }