PublicDashboards: Resolve interval for public dashboard data source (#55489)

* Resolve interval for public dashboard data source

* Remove type assertions in favor of 'in'

* Add org id to public dashboard requests
This commit is contained in:
Guilherme Caulada 2022-09-21 13:29:27 -03:00 committed by GitHub
parent 48a8b35ece
commit 9c2f3045b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 65 additions and 20 deletions

View File

@ -3902,11 +3902,9 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"public/app/features/dashboard/services/PublicDashboardDataSource.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Do not use any type assertions.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Unexpected any. Specify a different type.", "4"]
[0, 0, 0, "Do not use any type assertions.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"public/app/features/dashboard/services/TimeSrv.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
@ -5046,11 +5044,7 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "2"],
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
[0, 0, 0, "Do not use any type assertions.", "4"],
[0, 0, 0, "Do not use any type assertions.", "5"],
[0, 0, 0, "Do not use any type assertions.", "6"],
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
[0, 0, 0, "Do not use any type assertions.", "8"],
[0, 0, 0, "Do not use any type assertions.", "9"]
[0, 0, 0, "Do not use any type assertions.", "5"]
],
"public/app/features/query/state/runRequest.test.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]

View File

@ -2,6 +2,7 @@ package api
import (
"net/http"
"strconv"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
@ -11,6 +12,12 @@ import (
func SetPublicDashboardFlag() func(c *models.ReqContext) {
return func(c *models.ReqContext) {
// TODO: Find a better place to set this, or rename this function
orgIDValue := c.Req.URL.Query().Get("orgId")
orgID, err := strconv.ParseInt(orgIDValue, 10, 64)
if err == nil && orgID > 0 && orgID != c.OrgID {
c.OrgID = orgID
}
c.IsPublicDashboardView = true
}
}

View File

@ -4,7 +4,7 @@ import { DataQueryRequest, DataSourceInstanceSettings, DataSourceRef } from '@gr
import { BackendSrvRequest, BackendSrv, DataSourceWithBackend } from '@grafana/runtime';
import { MIXED_DATASOURCE_NAME } from 'app/plugins/datasource/mixed/MixedDataSource';
import { PublicDashboardDataSource, PUBLIC_DATASOURCE } from './PublicDashboardDataSource';
import { PublicDashboardDataSource, PUBLIC_DATASOURCE, DEFAULT_INTERVAL } from './PublicDashboardDataSource';
const mockDatasourceRequest = jest.fn();
@ -93,4 +93,35 @@ describe('PublicDashboardDatasource', () => {
let ds = new PublicDashboardDataSource(null);
expect(ds.meta.mixed).toBeFalsy();
});
test('returns default datasource interval when datasource passed in is null', () => {
let ds = new PublicDashboardDataSource(null);
expect(ds.interval).toBe(DEFAULT_INTERVAL);
});
test('returns default datasource interval when datasource passed in is a string', () => {
let ds = new PublicDashboardDataSource('theDatasourceUid');
expect(ds.interval).toBe(DEFAULT_INTERVAL);
});
test('returns default datasource interval when datasource passed in is a DataSourceRef implementation', () => {
const datasource = { type: 'datasource', uid: 'abc123' };
let ds = new PublicDashboardDataSource(datasource);
expect(ds.interval).toBe(DEFAULT_INTERVAL);
});
test('returns default datasource interval when datasource passed in is a DatasourceApi instance that has no interval', () => {
const settings: DataSourceInstanceSettings = { id: 1, uid: 'abc123' } as DataSourceInstanceSettings;
const datasource = new DataSourceWithBackend(settings);
let ds = new PublicDashboardDataSource(datasource);
expect(ds.interval).toBe(DEFAULT_INTERVAL);
});
test('returns datasource interval when datasource passed in is a DatasourceApi instance that has interval', () => {
const settings: DataSourceInstanceSettings = { id: 1, uid: 'abc123' } as DataSourceInstanceSettings;
const datasource = new DataSourceWithBackend(settings);
datasource.interval = 'abc123';
let ds = new PublicDashboardDataSource(datasource);
expect(ds.interval).toBe('abc123');
});
});

View File

@ -5,6 +5,7 @@ import {
DataQueryRequest,
DataQueryResponse,
DataSourceApi,
DataSourceJsonData,
DataSourcePluginMeta,
DataSourceRef,
} from '@grafana/data';
@ -13,8 +14,9 @@ import { BackendDataSourceResponse, getBackendSrv, toDataQueryResponse } from '@
import { MIXED_DATASOURCE_NAME } from '../../../plugins/datasource/mixed/MixedDataSource';
export const PUBLIC_DATASOURCE = '-- Public --';
export const DEFAULT_INTERVAL = '1min';
export class PublicDashboardDataSource extends DataSourceApi<any> {
export class PublicDashboardDataSource extends DataSourceApi<DataQuery, DataSourceJsonData, {}> {
constructor(datasource: DataSourceRef | string | DataSourceApi | null) {
let meta = {} as DataSourcePluginMeta;
if (PublicDashboardDataSource.isMixedDatasource(datasource)) {
@ -32,7 +34,7 @@ export class PublicDashboardDataSource extends DataSourceApi<any> {
readOnly: true,
});
this.interval = '1min';
this.interval = PublicDashboardDataSource.resolveInterval(datasource);
}
/**
@ -54,10 +56,20 @@ export class PublicDashboardDataSource extends DataSourceApi<any> {
return datasource?.uid === MIXED_DATASOURCE_NAME;
}
private static resolveInterval(datasource: DataSourceRef | string | DataSourceApi | null): string {
if (typeof datasource === 'string' || datasource === null) {
return DEFAULT_INTERVAL;
}
const interval = 'interval' in datasource ? datasource.interval : undefined;
return interval ?? DEFAULT_INTERVAL;
}
/**
* Ideally final -- any other implementation may not work as expected
*/
query(request: DataQueryRequest<any>): Observable<DataQueryResponse> {
query(request: DataQueryRequest<DataQuery>): Observable<DataQueryResponse> {
const { intervalMs, maxDataPoints, requestId, publicDashboardAccessToken, panelId } = request;
let queries: DataQuery[];

View File

@ -370,13 +370,14 @@ async function getDataSource(
scopedVars: ScopedVars,
publicDashboardAccessToken?: string
): Promise<DataSourceApi> {
if (!publicDashboardAccessToken && datasource && typeof datasource === 'object' && 'query' in datasource) {
return datasource;
}
const ds = await getDatasourceSrv().get(datasource, scopedVars);
if (publicDashboardAccessToken) {
return new PublicDashboardDataSource(datasource);
return new PublicDashboardDataSource(ds);
}
if (datasource && (datasource as any).query) {
return datasource as DataSourceApi;
}
return await getDatasourceSrv().get(datasource as string, scopedVars);
return ds;
}