mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Fix importing dashboards created before ~6.1.0 (#94332)
This commit is contained in:
parent
ed5bbdaa95
commit
df98465982
5 changed files with 198 additions and 12 deletions
|
@ -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', () => {
|
||||
|
|
|
@ -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
|
||||
|
|
43
test/functional/apps/dashboard/bwc_import.ts
Normal file
43
test/functional/apps/dashboard/bwc_import.ts
Normal 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']);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
46
test/functional/apps/dashboard/exports/dashboard_6_0_1.json
Normal file
46
test/functional/apps/dashboard/exports/dashboard_6_0_1.json
Normal 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
|
||||
}
|
||||
}
|
||||
]
|
|
@ -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'));
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue