[v8.4.x] Datasource: Fixes changing default data source causes inconsistency between panel data source and query data source (#46221)
* Datasource: Fixes changing default data source causes inconsistency between panel data source and query data source (#46167)
* Datasource: Fixes changing default data source causes inconsistency between panel data source and query data source
* Fix unit tests
(cherry picked from commit a404dba29d)
* updated test
Co-authored-by: Torkel Ödegaard <torkel@grafana.com>
This commit is contained in:
co-authored by
Torkel Ödegaard
parent
3af9f2fa2e
commit
90a99a4719
@@ -17,6 +17,13 @@ const dataSources = {
|
|||||||
prom: mockDataSource({
|
prom: mockDataSource({
|
||||||
name: 'prom',
|
name: 'prom',
|
||||||
type: 'prometheus',
|
type: 'prometheus',
|
||||||
|
isDefault: true,
|
||||||
|
}),
|
||||||
|
notDefault: mockDataSource({
|
||||||
|
name: 'prom-not-default',
|
||||||
|
uid: 'prom-not-default-uid',
|
||||||
|
type: 'prometheus',
|
||||||
|
isDefault: false,
|
||||||
}),
|
}),
|
||||||
[MIXED_DATASOURCE_NAME]: mockDataSource({
|
[MIXED_DATASOURCE_NAME]: mockDataSource({
|
||||||
name: MIXED_DATASOURCE_NAME,
|
name: MIXED_DATASOURCE_NAME,
|
||||||
@@ -1840,6 +1847,33 @@ describe('DashboardModel', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('when fixing query and panel data source refs out of sync due to default data source change', () => {
|
||||||
|
let model: DashboardModel;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
model = new DashboardModel({
|
||||||
|
templating: {
|
||||||
|
list: [],
|
||||||
|
},
|
||||||
|
panels: [
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
datasource: null,
|
||||||
|
targets: [
|
||||||
|
{
|
||||||
|
datasource: 'prom-not-default',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not update panel datasource to that of query level ds', () => {
|
||||||
|
expect(model.panels[0].datasource?.uid).toEqual('prom-not-default-uid');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('when migrating time series axis visibility', () => {
|
describe('when migrating time series axis visibility', () => {
|
||||||
test('preserves x axis visibility', () => {
|
test('preserves x axis visibility', () => {
|
||||||
const model = new DashboardModel({
|
const model = new DashboardModel({
|
||||||
|
|||||||
@@ -67,6 +67,40 @@ export class DashboardMigrator {
|
|||||||
this.dashboard = dashboardModel;
|
this.dashboard = dashboardModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When changing default datasource which is stored as null Grafana get's into a mixed state where queries have
|
||||||
|
* data source uid & type set that is different from the now new default
|
||||||
|
*/
|
||||||
|
syncQueryDataSources() {
|
||||||
|
const dataSourceSrv = getDataSourceSrv();
|
||||||
|
// This only happens in some unit tests that does not set a DataSourceSrv
|
||||||
|
if (!dataSourceSrv) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultDS = getDataSourceSrv().getInstanceSettings(null);
|
||||||
|
// if default ds is mixed then skip this
|
||||||
|
if (!defaultDS || defaultDS.meta.mixed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const panel of this.dashboard.panels) {
|
||||||
|
// only interested in panels that use default (null) data source
|
||||||
|
if (panel.datasource) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const target of panel.targets) {
|
||||||
|
// If query level data source is different from panel
|
||||||
|
if (target.datasource && target.datasource.uid !== defaultDS?.uid) {
|
||||||
|
// set panel level data source to data source on the query as this is more likely the correct one
|
||||||
|
// But impossible to say, and this changes the behavior of of what default means ahead of the big change to default
|
||||||
|
panel.datasource = target.datasource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
updateSchema(old: any) {
|
updateSchema(old: any) {
|
||||||
let i, j, k, n;
|
let i, j, k, n;
|
||||||
const oldVersion = this.dashboard.schemaVersion;
|
const oldVersion = this.dashboard.schemaVersion;
|
||||||
|
|||||||
@@ -1067,6 +1067,7 @@ export class DashboardModel {
|
|||||||
private updateSchema(old: any) {
|
private updateSchema(old: any) {
|
||||||
const migrator = new DashboardMigrator(this);
|
const migrator = new DashboardMigrator(this);
|
||||||
migrator.updateSchema(old);
|
migrator.updateSchema(old);
|
||||||
|
migrator.syncQueryDataSources();
|
||||||
}
|
}
|
||||||
|
|
||||||
resetOriginalTime() {
|
resetOriginalTime() {
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ function setup(state?: any) {
|
|||||||
return Object.values(datasources).map((d) => ({ name: d.name }));
|
return Object.values(datasources).map((d) => ({ name: d.name }));
|
||||||
},
|
},
|
||||||
getInstanceSettings(name: string) {
|
getInstanceSettings(name: string) {
|
||||||
return { name, getRef: () => ({ uid: name }) };
|
return { name, getRef: () => ({ uid: name }), meta: { name } };
|
||||||
},
|
},
|
||||||
get(name?: string) {
|
get(name?: string) {
|
||||||
return Promise.resolve(
|
return Promise.resolve(
|
||||||
@@ -90,6 +90,7 @@ function setup(state?: any) {
|
|||||||
testDatasource: jest.fn(),
|
testDatasource: jest.fn(),
|
||||||
init: jest.fn(),
|
init: jest.fn(),
|
||||||
name: 'default',
|
name: 'default',
|
||||||
|
meta: {},
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user