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
This commit is contained in:
Torkel Ödegaard 2022-03-04 08:58:13 +01:00 committed by GitHub
parent 0544218bb7
commit a404dba29d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 69 additions and 0 deletions

View File

@ -17,6 +17,13 @@ const dataSources = {
prom: mockDataSource({
name: 'prom',
type: 'prometheus',
isDefault: true,
}),
notDefault: mockDataSource({
name: 'prom-not-default',
uid: 'prom-not-default-uid',
type: 'prometheus',
isDefault: false,
}),
[MIXED_DATASOURCE_NAME]: mockDataSource({
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', () => {
test('preserves x axis visibility', () => {
const model = new DashboardModel({

View File

@ -67,6 +67,40 @@ export class DashboardMigrator {
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) {
let i, j, k, n;
const oldVersion = this.dashboard.schemaVersion;

View File

@ -1071,6 +1071,7 @@ export class DashboardModel implements TimeModel {
private updateSchema(old: any) {
const migrator = new DashboardMigrator(this);
migrator.updateSchema(old);
migrator.syncQueryDataSources();
}
resetOriginalTime() {