From deb86e3250f5d6135e6e70c946a1f8f6e790dd9c Mon Sep 17 00:00:00 2001 From: owensmallwood Date: Wed, 14 Sep 2022 09:49:10 -0600 Subject: [PATCH] PublicDashboards: Dont support exemplars (#54933) Don't support exemplars in public dashboards --- docs/sources/dashboards/dashboard-public.md | 1 + .../queries}/dashboard_queries.go | 5 ++++- .../queries}/dashboard_queries_test.go | 21 +++++++++++++------ .../publicdashboards/service/service.go | 6 +++--- pkg/services/query/query.go | 6 +++--- .../prometheus/result_transformer.ts | 2 +- 6 files changed, 27 insertions(+), 14 deletions(-) rename pkg/services/{query/models => publicdashboards/queries}/dashboard_queries.go (96%) rename pkg/services/{query/models => publicdashboards/queries}/dashboard_queries_test.go (95%) diff --git a/docs/sources/dashboards/dashboard-public.md b/docs/sources/dashboards/dashboard-public.md index 9ccdd858b17..f7ed18e1c7e 100644 --- a/docs/sources/dashboards/dashboard-public.md +++ b/docs/sources/dashboards/dashboard-public.md @@ -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. diff --git a/pkg/services/query/models/dashboard_queries.go b/pkg/services/publicdashboards/queries/dashboard_queries.go similarity index 96% rename from pkg/services/query/models/dashboard_queries.go rename to pkg/services/publicdashboards/queries/dashboard_queries.go index 92202d8d4b0..f6df483b69c 100644 --- a/pkg/services/query/models/dashboard_queries.go +++ b/pkg/services/publicdashboards/queries/dashboard_queries.go @@ -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) diff --git a/pkg/services/query/models/dashboard_queries_test.go b/pkg/services/publicdashboards/queries/dashboard_queries_test.go similarity index 95% rename from pkg/services/query/models/dashboard_queries_test.go rename to pkg/services/publicdashboards/queries/dashboard_queries_test.go index 7bf14c62343..28a7914591d 100644 --- a/pkg/services/query/models/dashboard_queries_test.go +++ b/pkg/services/publicdashboards/queries/dashboard_queries_test.go @@ -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": "", diff --git a/pkg/services/publicdashboards/service/service.go b/pkg/services/publicdashboards/service/service.go index 4da151365b7..85a27e3797a 100644 --- a/pkg/services/publicdashboards/service/service.go +++ b/pkg/services/publicdashboards/service/service.go @@ -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)} diff --git a/pkg/services/query/query.go b/pkg/services/query/query.go index fb14d554697..aaf9dc7867b 100644 --- a/pkg/services/query/query.go +++ b/pkg/services/query/query.go @@ -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() diff --git a/public/app/plugins/datasource/prometheus/result_transformer.ts b/public/app/plugins/datasource/prometheus/result_transformer.ts index 7c502badbba..3870b8aafce 100644 --- a/public/app/plugins/datasource/prometheus/result_transformer.ts +++ b/public/app/plugins/datasource/prometheus/result_transformer.ts @@ -65,7 +65,7 @@ const isHeatmapResult = (dataFrame: DataFrame, options: DataQueryRequest,