Fix importing dashboards created before ~6.1.0 (#94332) (#94565)

This commit is contained in:
Anton Dosov 2021-03-15 16:13:39 +01:00 committed by GitHub
parent af793b703c
commit 26cb5b90a3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 198 additions and 12 deletions

View file

@ -30,11 +30,13 @@ describe('extractReferences', () => {
type: 'visualization',
id: '1',
title: 'Title 1',
version: '7.9.1',
},
{
type: 'visualization',
id: '2',
title: 'Title 2',
version: '7.9.1',
},
]),
},
@ -46,7 +48,7 @@ describe('extractReferences', () => {
Object {
"attributes": Object {
"foo": true,
"panelsJSON": "[{\\"embeddableConfig\\":{},\\"title\\":\\"Title 1\\",\\"panelRefName\\":\\"panel_0\\"},{\\"embeddableConfig\\":{},\\"title\\":\\"Title 2\\",\\"panelRefName\\":\\"panel_1\\"}]",
"panelsJSON": "[{\\"version\\":\\"7.9.1\\",\\"embeddableConfig\\":{},\\"title\\":\\"Title 1\\",\\"panelRefName\\":\\"panel_0\\"},{\\"version\\":\\"7.9.1\\",\\"embeddableConfig\\":{},\\"title\\":\\"Title 2\\",\\"panelRefName\\":\\"panel_1\\"}]",
},
"references": Array [
Object {
@ -73,6 +75,7 @@ describe('extractReferences', () => {
{
id: '1',
title: 'Title 1',
version: '7.9.1',
},
]),
},
@ -92,6 +95,7 @@ describe('extractReferences', () => {
{
type: 'visualization',
title: 'Title 1',
version: '7.9.1',
},
]),
},
@ -101,12 +105,85 @@ describe('extractReferences', () => {
Object {
"attributes": Object {
"foo": true,
"panelsJSON": "[{\\"type\\":\\"visualization\\",\\"embeddableConfig\\":{},\\"title\\":\\"Title 1\\"}]",
"panelsJSON": "[{\\"version\\":\\"7.9.1\\",\\"type\\":\\"visualization\\",\\"embeddableConfig\\":{},\\"title\\":\\"Title 1\\"}]",
},
"references": Array [],
}
`);
});
// https://github.com/elastic/kibana/issues/93772
test('passes when received older RAW SO with older panels', () => {
const doc = {
id: '1',
attributes: {
hits: 0,
timeFrom: 'now-16h/h',
timeTo: 'now',
refreshInterval: {
display: '1 minute',
section: 2,
value: 60000,
pause: false,
},
description: '',
uiStateJSON: '{"P-1":{"vis":{"legendOpen":false}}}',
title: 'Errors/Fatals/Warnings dashboard',
timeRestore: true,
version: 1,
panelsJSON:
'[{"col":1,"id":"544891f0-2cf2-11e8-9735-93e95b055f48","panelIndex":1,"row":1,"size_x":12,"size_y":8,"type":"visualization"}]',
optionsJSON: '{"darkTheme":true}',
kibanaSavedObjectMeta: {
searchSourceJSON:
'{"highlightAll":true,"filter":[{"query":{"query_string":{"analyze_wildcard":true,"query":"*"}}}]}',
},
},
references: [],
};
const updatedDoc = extractReferences(doc, deps);
expect(updatedDoc).toMatchInlineSnapshot(`
Object {
"attributes": Object {
"description": "",
"hits": 0,
"kibanaSavedObjectMeta": Object {
"searchSourceJSON": "{\\"highlightAll\\":true,\\"filter\\":[{\\"query\\":{\\"query_string\\":{\\"analyze_wildcard\\":true,\\"query\\":\\"*\\"}}}]}",
},
"optionsJSON": "{\\"darkTheme\\":true}",
"panelsJSON": "[{\\"col\\":1,\\"panelIndex\\":1,\\"row\\":1,\\"size_x\\":12,\\"size_y\\":8,\\"panelRefName\\":\\"panel_0\\"}]",
"refreshInterval": Object {
"display": "1 minute",
"pause": false,
"section": 2,
"value": 60000,
},
"timeFrom": "now-16h/h",
"timeRestore": true,
"timeTo": "now",
"title": "Errors/Fatals/Warnings dashboard",
"uiStateJSON": "{\\"P-1\\":{\\"vis\\":{\\"legendOpen\\":false}}}",
"version": 1,
},
"references": Array [
Object {
"id": "544891f0-2cf2-11e8-9735-93e95b055f48",
"name": "panel_0",
"type": "visualization",
},
],
}
`);
const panel = JSON.parse(updatedDoc.attributes.panelsJSON as string)[0];
// unknown older panel keys are left untouched
expect(panel).toHaveProperty('col');
expect(panel).toHaveProperty('row');
expect(panel).toHaveProperty('size_x');
expect(panel).toHaveProperty('size_y');
});
});
describe('injectReferences', () => {

View file

@ -6,6 +6,7 @@
* Side Public License, v 1.
*/
import semverSatisfies from 'semver/functions/satisfies';
import { SavedObjectAttributes, SavedObjectReference } from '../../../core/types';
import {
extractPanelsReferences,
@ -33,17 +34,35 @@ export function extractReferences(
const panelReferences: SavedObjectReference[] = [];
let panels: Array<Record<string, string>> = JSON.parse(String(attributes.panelsJSON));
const extractedReferencesResult = extractPanelsReferences(
(panels as unknown) as SavedDashboardPanel730ToLatest[],
deps
);
const isPre730Panel = (panel: Record<string, string>): boolean => {
return 'version' in panel ? semverSatisfies(panel.version, '<7.3') : true;
};
panels = (extractedReferencesResult.map((res) => res.panel) as unknown) as Array<
Record<string, string>
>;
extractedReferencesResult.forEach((res) => {
panelReferences.push(...res.references);
});
const hasPre730Panel = panels.some(isPre730Panel);
/**
* `extractPanelsReferences` only knows how to reliably handle "latest" panels
* It is possible that `extractReferences` is run on older dashboard SO with older panels,
* for example, when importing a saved object using saved object UI `extractReferences` is called BEFORE any server side migrations are run.
*
* In this case we skip running `extractPanelsReferences` on such object.
* We also know that there is nothing to extract
* (First possible entity to be extracted by this mechanism is a dashboard drilldown since 7.11)
*/
if (!hasPre730Panel) {
const extractedReferencesResult = extractPanelsReferences(
// it is ~safe~ to cast to `SavedDashboardPanel730ToLatest` because above we've checked that there are only >=7.3 panels
(panels as unknown) as SavedDashboardPanel730ToLatest[],
deps
);
panels = (extractedReferencesResult.map((res) => res.panel) as unknown) as Array<
Record<string, string>
>;
extractedReferencesResult.forEach((res) => {
panelReferences.push(...res.references);
});
}
// TODO: This extraction should be done by EmbeddablePersistableStateService
// https://github.com/elastic/kibana/issues/82830

View file

@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import path from 'path';
import { FtrProviderContext } from '../../ftr_provider_context';
export default function ({ getService, getPageObjects }: FtrProviderContext) {
const PageObjects = getPageObjects(['dashboard', 'header', 'settings', 'savedObjects', 'common']);
const dashboardExpect = getService('dashboardExpect');
describe('bwc import', function describeIndexTests() {
before(async function () {
await PageObjects.dashboard.initTests();
await PageObjects.settings.navigateTo();
await PageObjects.settings.clickKibanaSavedObjects();
await PageObjects.savedObjects.importFile(
path.join(__dirname, 'exports', 'dashboard_6_0_1.json')
);
await PageObjects.settings.associateIndexPattern(
'dd684000-8255-11eb-a5e7-93c302c8f329',
'logstash-*'
);
await PageObjects.savedObjects.clickConfirmChanges();
await PageObjects.savedObjects.clickImportDone();
await PageObjects.common.navigateToApp('dashboard');
});
describe('6.0.1 dashboard', () => {
it('loads an imported dashboard', async function () {
await PageObjects.dashboard.gotoDashboardLandingPage();
await PageObjects.dashboard.loadSavedDashboard('My custom bwc dashboard');
await PageObjects.header.waitUntilLoadingHasFinished();
await dashboardExpect.metricValuesExist(['14,004']);
});
});
});
}

View file

@ -0,0 +1,46 @@
[
{
"_id": "924ed3d0-8256-11eb-a5e7-93c302c8f329",
"_type": "dashboard",
"_source": {
"title": "My custom bwc dashboard",
"hits": 0,
"description": "",
"panelsJSON": "[{\"size_x\":6,\"size_y\":3,\"panelIndex\":1,\"type\":\"visualization\",\"id\":\"1bdf34a0-8266-11eb-a5e7-93c302c8f329\",\"col\":1,\"row\":1}]",
"optionsJSON": "{\"darkTheme\":false}",
"uiStateJSON": "{\"P-1\":{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}}}",
"version": 1,
"timeRestore": true,
"timeTo": "Wed Apr 20 2016 23:59:59 GMT+0200",
"timeFrom": "Thu Jan 01 2015 00:00:00 GMT+0100",
"refreshInterval": {
"display": "Off",
"pause": false,
"value": 0
},
"kibanaSavedObjectMeta": {
"searchSourceJSON": "{\"query\":{\"language\":\"lucene\",\"query\":\"\"},\"filter\":[],\"highlightAll\":true,\"version\":true}"
}
},
"_meta": {
"savedObjectVersion": 2
}
},
{
"_id": "1bdf34a0-8266-11eb-a5e7-93c302c8f329",
"_type": "visualization",
"_source": {
"title": "My custom bwc viz",
"visState": "{\"title\":\"My custom bwc viz\",\"type\":\"metric\",\"params\":{\"addTooltip\":true,\"addLegend\":false,\"type\":\"gauge\",\"gauge\":{\"verticalSplit\":false,\"autoExtend\":false,\"percentageMode\":false,\"gaugeType\":\"Metric\",\"gaugeStyle\":\"Full\",\"backStyle\":\"Full\",\"orientation\":\"vertical\",\"colorSchema\":\"Green to Red\",\"gaugeColorMode\":\"None\",\"useRange\":false,\"colorsRange\":[{\"from\":0,\"to\":100}],\"invertColors\":false,\"labels\":{\"show\":true,\"color\":\"black\"},\"scale\":{\"show\":false,\"labels\":false,\"color\":\"#333\",\"width\":2},\"type\":\"simple\",\"style\":{\"fontSize\":60,\"bgColor\":false,\"labelColor\":false,\"subText\":\"\"}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}}]}",
"uiStateJSON": "{\"vis\":{\"defaultColors\":{\"0 - 100\":\"rgb(0,104,55)\"}}}",
"description": "",
"version": 1,
"kibanaSavedObjectMeta": {
"searchSourceJSON": "{\"index\":\"dd684000-8255-11eb-a5e7-93c302c8f329\",\"filter\":[],\"query\":{\"query\":\"\",\"language\":\"lucene\"}}"
}
},
"_meta": {
"savedObjectVersion": 2
}
}
]

View file

@ -95,6 +95,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) {
loadTestFile(require.resolve('./dashboard_time_picker'));
loadTestFile(require.resolve('./bwc_shared_urls'));
loadTestFile(require.resolve('./bwc_import'));
loadTestFile(require.resolve('./panel_replacing'));
loadTestFile(require.resolve('./panel_cloning'));
loadTestFile(require.resolve('./copy_panel_to'));