mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
PublicDashboards: Dont support exemplars (#54933)
Don't support exemplars in public dashboards
This commit is contained in:
@@ -56,5 +56,6 @@ publicDashboards = true
|
||||
- Panels that use frontend datasources will fail to fetch data.
|
||||
- Template variables are currently not supported, but are planned to be in the future.
|
||||
- The time range is permanently set to the default time range on the dashboard. If you update the default time range for a dashboard, it will be reflected in the public dashboard.
|
||||
- Exemplars will be omitted from the panel.
|
||||
|
||||
We are excited to share this enhancement with you and we’d love your feedback! Please check out the [Github](https://github.com/grafana/grafana/discussions/49253) discussion and join the conversation.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
package query
|
||||
package queries
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
@@ -45,6 +45,9 @@ func GroupQueriesByPanelId(dashboard *simplejson.Json) map[int64][]*simplejson.J
|
||||
for _, queryObj := range panel.Get("targets").MustArray() {
|
||||
query := simplejson.NewFromAny(queryObj)
|
||||
|
||||
// We dont support exemplars for public dashboards currently
|
||||
query.Del("exemplar")
|
||||
|
||||
// if query target has no datasource, set it to have the datasource on the panel
|
||||
if _, ok := query.CheckGet("datasource"); !ok {
|
||||
uid := GetDataSourceUidFromJson(panel)
|
||||
@@ -1,4 +1,4 @@
|
||||
package query
|
||||
package queries
|
||||
|
||||
import (
|
||||
"testing"
|
||||
@@ -51,7 +51,7 @@ const (
|
||||
"schemaVersion": 35
|
||||
}`
|
||||
|
||||
dashboardWithQueries = `
|
||||
dashboardWithQueriesExemplarEnabled = `
|
||||
{
|
||||
"panels": [
|
||||
{
|
||||
@@ -362,6 +362,18 @@ func TestGroupQueriesByPanelId(t *testing.T) {
|
||||
queriesByDatasource := GroupQueriesByDataSource(queries[panelId])
|
||||
require.Len(t, queriesByDatasource[0], 1)
|
||||
})
|
||||
t.Run("will delete exemplar property from target if exists", func(t *testing.T) {
|
||||
json, err := simplejson.NewJson([]byte(dashboardWithQueriesExemplarEnabled))
|
||||
require.NoError(t, err)
|
||||
queries := GroupQueriesByPanelId(json)
|
||||
|
||||
panelId := int64(2)
|
||||
queriesByDatasource := GroupQueriesByDataSource(queries[panelId])
|
||||
for _, query := range queriesByDatasource[0] {
|
||||
_, ok := query.CheckGet("exemplar")
|
||||
require.False(t, ok)
|
||||
}
|
||||
})
|
||||
t.Run("can extract queries from dashboard with panel json datasource that has no datasource on panel targets", func(t *testing.T) {
|
||||
json, err := simplejson.NewJson([]byte(dashboardWithTargetsWithNoDatasources))
|
||||
require.NoError(t, err)
|
||||
@@ -390,7 +402,7 @@ func TestGroupQueriesByPanelId(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("can extract queries from panels", func(t *testing.T) {
|
||||
json, err := simplejson.NewJson([]byte(dashboardWithQueries))
|
||||
json, err := simplejson.NewJson([]byte(dashboardWithQueriesExemplarEnabled))
|
||||
require.NoError(t, err)
|
||||
|
||||
queries := GroupQueriesByPanelId(json)
|
||||
@@ -404,7 +416,6 @@ func TestGroupQueriesByPanelId(t *testing.T) {
|
||||
"type": "prometheus",
|
||||
"uid": "_yxMP8Ynk"
|
||||
},
|
||||
"exemplar": true,
|
||||
"expr": "go_goroutines{job=\"$job\"}",
|
||||
"interval": "",
|
||||
"legendFormat": "",
|
||||
@@ -417,7 +428,6 @@ func TestGroupQueriesByPanelId(t *testing.T) {
|
||||
"type": "prometheus",
|
||||
"uid": "promds2"
|
||||
},
|
||||
"exemplar": true,
|
||||
"expr": "query2",
|
||||
"interval": "",
|
||||
"legendFormat": "",
|
||||
@@ -440,7 +450,6 @@ func TestGroupQueriesByPanelId(t *testing.T) {
|
||||
"uid": "_yxMP8Ynk",
|
||||
"type": "public-ds"
|
||||
},
|
||||
"exemplar": true,
|
||||
"expr": "go_goroutines{job=\"$job\"}",
|
||||
"interval": "",
|
||||
"legendFormat": "",
|
||||
@@ -13,9 +13,9 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||
. "github.com/grafana/grafana/pkg/services/publicdashboards/models"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards/queries"
|
||||
"github.com/grafana/grafana/pkg/services/publicdashboards/validation"
|
||||
"github.com/grafana/grafana/pkg/services/query"
|
||||
queryModels "github.com/grafana/grafana/pkg/services/query/models"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tsdb/intervalv2"
|
||||
@@ -231,7 +231,7 @@ func (pd *PublicDashboardServiceImpl) GetMetricRequest(ctx context.Context, dash
|
||||
// dashboard and returns a metrics request to be sent to query backend
|
||||
func (pd *PublicDashboardServiceImpl) buildMetricRequest(ctx context.Context, dashboard *models.Dashboard, publicDashboard *PublicDashboard, panelId int64, reqDTO PublicDashboardQueryDTO) (dtos.MetricRequest, error) {
|
||||
// group queries by panel
|
||||
queriesByPanel := queryModels.GroupQueriesByPanelId(dashboard.Data)
|
||||
queriesByPanel := queries.GroupQueriesByPanelId(dashboard.Data)
|
||||
queries, ok := queriesByPanel[panelId]
|
||||
if !ok {
|
||||
return dtos.MetricRequest{}, ErrPublicDashboardPanelNotFound
|
||||
@@ -255,7 +255,7 @@ func (pd *PublicDashboardServiceImpl) buildMetricRequest(ctx context.Context, da
|
||||
|
||||
// BuildAnonymousUser creates a user with permissions to read from all datasources used in the dashboard
|
||||
func (pd *PublicDashboardServiceImpl) BuildAnonymousUser(ctx context.Context, dashboard *models.Dashboard) (*user.SignedInUser, error) {
|
||||
datasourceUids := queryModels.GetUniqueDashboardDatasourceUids(dashboard.Data)
|
||||
datasourceUids := queries.GetUniqueDashboardDatasourceUids(dashboard.Data)
|
||||
|
||||
// Create a temp user with read-only datasource permissions
|
||||
anonymousUser := &user.SignedInUser{OrgID: dashboard.OrgId, Permissions: make(map[int64]map[string][]string)}
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/plugins/adapters"
|
||||
"github.com/grafana/grafana/pkg/services/datasources"
|
||||
"github.com/grafana/grafana/pkg/services/oauthtoken"
|
||||
queryModels "github.com/grafana/grafana/pkg/services/query/models"
|
||||
publicDashboards "github.com/grafana/grafana/pkg/services/publicdashboards/queries"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/tsdb/grafanads"
|
||||
@@ -81,10 +81,10 @@ func (s *Service) QueryData(ctx context.Context, user *user.SignedInUser, skipCa
|
||||
|
||||
// QueryData can process queries and return query responses.
|
||||
func (s *Service) QueryDataMultipleSources(ctx context.Context, user *user.SignedInUser, skipCache bool, reqDTO dtos.MetricRequest, handleExpressions bool) (*backend.QueryDataResponse, error) {
|
||||
byDataSource := queryModels.GroupQueriesByDataSource(reqDTO.Queries)
|
||||
byDataSource := publicDashboards.GroupQueriesByDataSource(reqDTO.Queries)
|
||||
|
||||
// The expression service will handle mixed datasources, so we don't need to group them when an expression is present.
|
||||
if queryModels.HasExpressionQuery(reqDTO.Queries) || len(byDataSource) == 1 {
|
||||
if publicDashboards.HasExpressionQuery(reqDTO.Queries) || len(byDataSource) == 1 {
|
||||
return s.QueryData(ctx, user, skipCache, reqDTO, handleExpressions)
|
||||
} else {
|
||||
resp := backend.NewQueryDataResponse()
|
||||
|
||||
@@ -65,7 +65,7 @@ const isHeatmapResult = (dataFrame: DataFrame, options: DataQueryRequest<PromQue
|
||||
return target?.format === 'heatmap';
|
||||
};
|
||||
|
||||
// V2 result trasnformer used to transform query results from queries that were run trough prometheus backend
|
||||
// V2 result transformer used to transform query results from queries that were run through prometheus backend
|
||||
export function transformV2(
|
||||
response: DataQueryResponse,
|
||||
request: DataQueryRequest<PromQuery>,
|
||||
|
||||
Reference in New Issue
Block a user