Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Ingest Manager ] prepend kibana asset ids with package name #70502

Merged
merged 5 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import {
SavedObject,
SavedObjectsBulkCreateObject,
SavedObjectsClientContract,
} from 'src/core/server';
import * as Registry from '../../registry';
import { AssetType, KibanaAssetType, AssetReference } from '../../../../types';

type SavedObjectToBe = Required<SavedObjectsBulkCreateObject> & { type: AssetType };
export type ArchiveAsset = Pick<
SavedObject,
'id' | 'attributes' | 'migrationVersion' | 'references'
> & {
type: AssetType;
};

export async function getKibanaAsset(key: string) {
const buffer = Registry.getAsset(key);

// cache values are buffers. convert to string / JSON
return JSON.parse(buffer.toString('utf8'));
}

export function createSavedObjectKibanaAsset(
jsonAsset: ArchiveAsset,
pkgName: string
): SavedObjectToBe {
// convert that to an object
const asset = changeAssetIds(jsonAsset, pkgName);

return {
type: asset.type,
id: asset.id,
attributes: asset.attributes,
references: asset.references || [],
migrationVersion: asset.migrationVersion || {},
};
}

// modifies id property and the id property of references objects (not index-pattern)
// to be prepended with the package name to distinguish assets from Beats modules' assets
export const changeAssetIds = (asset: ArchiveAsset, pkgName: string): ArchiveAsset => {
const references = asset.references.map((ref) => {
if (ref.type === KibanaAssetType.indexPattern) return ref;
const id = getAssetId(ref.id, pkgName);
return { ...ref, id };
});
return {
...asset,
id: getAssetId(asset.id, pkgName),
references,
};
};

export const getAssetId = (id: string, pkgName: string) => {
return `${pkgName}-${id}`;
};

// TODO: make it an exhaustive list
// e.g. switch statement with cases for each enum key returning `never` for default case
export async function installKibanaAssets(options: {
savedObjectsClient: SavedObjectsClientContract;
pkgName: string;
paths: string[];
}) {
const { savedObjectsClient, paths, pkgName } = options;

// Only install Kibana assets during package installation.
const kibanaAssetTypes = Object.values(KibanaAssetType);
const installationPromises = kibanaAssetTypes.map((assetType) =>
installKibanaSavedObjects({ savedObjectsClient, assetType, paths, pkgName })
);

// installKibanaSavedObjects returns AssetReference[], so .map creates AssetReference[][]
// call .flat to flatten into one dimensional array
return Promise.all(installationPromises).then((results) => results.flat());
}

async function installKibanaSavedObjects({
savedObjectsClient,
assetType,
paths,
pkgName,
}: {
savedObjectsClient: SavedObjectsClientContract;
assetType: KibanaAssetType;
paths: string[];
pkgName: string;
}) {
const isSameType = (path: string) => assetType === Registry.pathParts(path).type;
const pathsOfType = paths.filter((path) => isSameType(path));
const kibanaAssets = await Promise.all(pathsOfType.map((path) => getKibanaAsset(path)));
const toBeSavedObjects = await Promise.all(
kibanaAssets.map((asset) => createSavedObjectKibanaAsset(asset, pkgName))
);

if (toBeSavedObjects.length === 0) {
return [];
} else {
const createResults = await savedObjectsClient.bulkCreate(toBeSavedObjects, {
overwrite: true,
});
const createdObjects = createResults.saved_objects;
const installed = createdObjects.map(toAssetReference);
return installed;
}
}

function toAssetReference({ id, type }: SavedObject) {
const reference: AssetReference = { id, type: type as KibanaAssetType };

return reference;
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{
"attributes": {
"description": "Overview dashboard for the Nginx integration in Metrics",
"hits": 0,
"kibanaSavedObjectMeta": {
"searchSourceJSON": {
"filter": [],
"highlightAll": true,
"query": {
"language": "kuery",
"query": ""
},
"version": true
}
},
"optionsJSON": {
"darkTheme": false,
"hidePanelTitles": false,
"useMargins": true
},
"panelsJSON": [
{
"embeddableConfig": {},
"gridData": {
"h": 12,
"i": "1",
"w": 24,
"x": 24,
"y": 0
},
"panelIndex": "1",
"panelRefName": "panel_0",
"version": "7.3.0"
},
{
"embeddableConfig": {},
"gridData": {
"h": 12,
"i": "2",
"w": 24,
"x": 24,
"y": 12
},
"panelIndex": "2",
"panelRefName": "panel_1",
"version": "7.3.0"
},
{
"embeddableConfig": {},
"gridData": {
"h": 12,
"i": "3",
"w": 24,
"x": 0,
"y": 12
},
"panelIndex": "3",
"panelRefName": "panel_2",
"version": "7.3.0"
},
{
"embeddableConfig": {},
"gridData": {
"h": 12,
"i": "4",
"w": 24,
"x": 0,
"y": 0
},
"panelIndex": "4",
"panelRefName": "panel_3",
"version": "7.3.0"
},
{
"embeddableConfig": {},
"gridData": {
"h": 12,
"i": "5",
"w": 48,
"x": 0,
"y": 24
},
"panelIndex": "5",
"panelRefName": "panel_4",
"version": "7.3.0"
}
],
"timeRestore": false,
"title": "[Metrics Nginx] Overview ECS",
"version": 1
},
"id": "023d2930-f1a5-11e7-a9ef-93c69af7b129-ecs",
"migrationVersion": {
"dashboard": "7.3.0"
},
"references": [
{
"id": "metrics-*",
"name": "kibanaSavedObjectMeta.searchSourceJSON.filter[0].meta.index",
"type": "index-pattern"
},
{
"id": "555df8a0-f1a1-11e7-a9ef-93c69af7b129-ecs",
"name": "panel_0",
"type": "search"
},
{
"id": "a1d92240-f1a1-11e7-a9ef-93c69af7b129-ecs",
"name": "panel_1",
"type": "map"
},
{
"id": "d763a570-f1a1-11e7-a9ef-93c69af7b129-ecs",
"name": "panel_2",
"type": "dashboard"
},
{
"id": "47a8e0f0-f1a4-11e7-a9ef-93c69af7b129-ecs",
"name": "panel_3",
"type": "visualization"
},
{
"id": "dcbffe30-f1a4-11e7-a9ef-93c69af7b129-ecs",
"name": "panel_4",
"type": "visualization"
}
],
"type": "dashboard"
}
Loading