[Ingest Manager] improve error handling of package install (#73728)
* refactor to add assets refs to SO before install * get ingest pipeline refs by looping through datasets because names are diff than path dir * fix bug and improve error handling * bump package number from merge conflict * add integration test for the epm-package saved object * accidentally pasted line of code * rename errors for consistency * pass custom error when IngestManagerError * rename package from outdated to update
This commit is contained in:
parent
b9e5ae9c77
commit
5cabe9c95d
|
@ -15,9 +15,17 @@ export class IngestManagerError extends Error {
|
|||
export const getHTTPResponseCode = (error: IngestManagerError): number => {
|
||||
if (error instanceof RegistryError) {
|
||||
return 502; // Bad Gateway
|
||||
}
|
||||
if (error instanceof PackageNotFoundError) {
|
||||
return 404;
|
||||
}
|
||||
if (error instanceof PackageOutdatedError) {
|
||||
return 400;
|
||||
} else {
|
||||
return 400; // Bad Request
|
||||
}
|
||||
};
|
||||
|
||||
export class RegistryError extends IngestManagerError {}
|
||||
export class PackageNotFoundError extends IngestManagerError {}
|
||||
export class PackageOutdatedError extends IngestManagerError {}
|
||||
|
|
|
@ -32,6 +32,7 @@ import {
|
|||
getLimitedPackages,
|
||||
getInstallationObject,
|
||||
} from '../../services/epm/packages';
|
||||
import { IngestManagerError, getHTTPResponseCode } from '../../errors';
|
||||
|
||||
export const getCategoriesHandler: RequestHandler<
|
||||
undefined,
|
||||
|
@ -165,23 +166,25 @@ export const installPackageHandler: RequestHandler<TypeOf<
|
|||
};
|
||||
return response.ok({ body });
|
||||
} catch (e) {
|
||||
if (e instanceof IngestManagerError) {
|
||||
logger.error(e);
|
||||
return response.customError({
|
||||
statusCode: getHTTPResponseCode(e),
|
||||
body: { message: e.message },
|
||||
});
|
||||
}
|
||||
|
||||
// if there is an unknown server error, uninstall any package assets
|
||||
try {
|
||||
const installedPkg = await getInstallationObject({ savedObjectsClient, pkgName });
|
||||
const isUpdate = installedPkg && installedPkg.attributes.version < pkgVersion ? true : false;
|
||||
// if this is a failed install, remove any assets installed
|
||||
if (!isUpdate) {
|
||||
await removeInstallation({ savedObjectsClient, pkgkey, callCluster });
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error(`could not remove assets from failed installation attempt for ${pkgkey}`);
|
||||
}
|
||||
|
||||
if (e.isBoom) {
|
||||
return response.customError({
|
||||
statusCode: e.output.statusCode,
|
||||
body: { message: e.output.payload.message },
|
||||
});
|
||||
logger.error(`could not remove failed installation ${error}`);
|
||||
}
|
||||
logger.error(e);
|
||||
return response.customError({
|
||||
statusCode: 500,
|
||||
body: { message: e.message },
|
||||
|
|
|
@ -31,25 +31,38 @@ export const installPipelines = async (
|
|||
// it can be created pointing to the new template, without removing the old one and effecting data
|
||||
// so do not remove the currently installed pipelines here
|
||||
const datasets = registryPackage.datasets;
|
||||
if (!datasets?.length) return [];
|
||||
const pipelinePaths = paths.filter((path) => isPipeline(path));
|
||||
if (datasets) {
|
||||
const pipelines = datasets.reduce<Array<Promise<EsAssetReference[]>>>((acc, dataset) => {
|
||||
if (dataset.ingest_pipeline) {
|
||||
acc.push(
|
||||
installPipelinesForDataset({
|
||||
dataset,
|
||||
callCluster,
|
||||
paths: pipelinePaths,
|
||||
pkgVersion: registryPackage.version,
|
||||
})
|
||||
);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
const pipelinesToSave = await Promise.all(pipelines).then((results) => results.flat());
|
||||
return saveInstalledEsRefs(savedObjectsClient, registryPackage.name, pipelinesToSave);
|
||||
}
|
||||
return [];
|
||||
// get and save pipeline refs before installing pipelines
|
||||
const pipelineRefs = datasets.reduce<EsAssetReference[]>((acc, dataset) => {
|
||||
const filteredPaths = pipelinePaths.filter((path) => isDatasetPipeline(path, dataset.path));
|
||||
const pipelineObjectRefs = filteredPaths.map((path) => {
|
||||
const { name } = getNameAndExtension(path);
|
||||
const nameForInstallation = getPipelineNameForInstallation({
|
||||
pipelineName: name,
|
||||
dataset,
|
||||
packageVersion: registryPackage.version,
|
||||
});
|
||||
return { id: nameForInstallation, type: ElasticsearchAssetType.ingestPipeline };
|
||||
});
|
||||
acc.push(...pipelineObjectRefs);
|
||||
return acc;
|
||||
}, []);
|
||||
await saveInstalledEsRefs(savedObjectsClient, registryPackage.name, pipelineRefs);
|
||||
const pipelines = datasets.reduce<Array<Promise<EsAssetReference[]>>>((acc, dataset) => {
|
||||
if (dataset.ingest_pipeline) {
|
||||
acc.push(
|
||||
installPipelinesForDataset({
|
||||
dataset,
|
||||
callCluster,
|
||||
paths: pipelinePaths,
|
||||
pkgVersion: registryPackage.version,
|
||||
})
|
||||
);
|
||||
}
|
||||
return acc;
|
||||
}, []);
|
||||
return await Promise.all(pipelines).then((results) => results.flat());
|
||||
};
|
||||
|
||||
export function rewriteIngestPipeline(
|
||||
|
|
|
@ -41,6 +41,16 @@ export const installTemplates = async (
|
|||
);
|
||||
// build templates per dataset from yml files
|
||||
const datasets = registryPackage.datasets;
|
||||
if (!datasets) return [];
|
||||
// get template refs to save
|
||||
const installedTemplateRefs = datasets.map((dataset) => ({
|
||||
id: generateTemplateName(dataset),
|
||||
type: ElasticsearchAssetType.indexTemplate,
|
||||
}));
|
||||
|
||||
// add package installation's references to index templates
|
||||
await saveInstalledEsRefs(savedObjectsClient, registryPackage.name, installedTemplateRefs);
|
||||
|
||||
if (datasets) {
|
||||
const installTemplatePromises = datasets.reduce<Array<Promise<TemplateRef>>>((acc, dataset) => {
|
||||
acc.push(
|
||||
|
@ -55,14 +65,6 @@ export const installTemplates = async (
|
|||
|
||||
const res = await Promise.all(installTemplatePromises);
|
||||
const installedTemplates = res.flat();
|
||||
// get template refs to save
|
||||
const installedTemplateRefs = installedTemplates.map((template) => ({
|
||||
id: template.templateName,
|
||||
type: ElasticsearchAssetType.indexTemplate,
|
||||
}));
|
||||
|
||||
// add package installation's references to index templates
|
||||
await saveInstalledEsRefs(savedObjectsClient, registryPackage.name, installedTemplateRefs);
|
||||
|
||||
return installedTemplates;
|
||||
}
|
||||
|
|
|
@ -11,14 +11,8 @@ import {
|
|||
} from 'src/core/server';
|
||||
import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../../../common';
|
||||
import * as Registry from '../../registry';
|
||||
import {
|
||||
AssetType,
|
||||
KibanaAssetType,
|
||||
AssetReference,
|
||||
KibanaAssetReference,
|
||||
} from '../../../../types';
|
||||
import { deleteKibanaSavedObjectsAssets } from '../../packages/remove';
|
||||
import { getInstallationObject, savedObjectTypes } from '../../packages';
|
||||
import { AssetType, KibanaAssetType, AssetReference } from '../../../../types';
|
||||
import { savedObjectTypes } from '../../packages';
|
||||
|
||||
type SavedObjectToBe = Required<SavedObjectsBulkCreateObject> & { type: AssetType };
|
||||
export type ArchiveAsset = Pick<
|
||||
|
@ -28,7 +22,7 @@ export type ArchiveAsset = Pick<
|
|||
type: AssetType;
|
||||
};
|
||||
|
||||
export async function getKibanaAsset(key: string) {
|
||||
export async function getKibanaAsset(key: string): Promise<ArchiveAsset> {
|
||||
const buffer = Registry.getAsset(key);
|
||||
|
||||
// cache values are buffers. convert to string / JSON
|
||||
|
@ -51,31 +45,18 @@ export function createSavedObjectKibanaAsset(asset: ArchiveAsset): SavedObjectTo
|
|||
export async function installKibanaAssets(options: {
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
pkgName: string;
|
||||
paths: string[];
|
||||
kibanaAssets: ArchiveAsset[];
|
||||
isUpdate: boolean;
|
||||
}): Promise<KibanaAssetReference[]> {
|
||||
const { savedObjectsClient, paths, pkgName, isUpdate } = options;
|
||||
}): Promise<SavedObject[]> {
|
||||
const { savedObjectsClient, kibanaAssets } = options;
|
||||
|
||||
if (isUpdate) {
|
||||
// delete currently installed kibana saved objects and installation references
|
||||
const installedPkg = await getInstallationObject({ savedObjectsClient, pkgName });
|
||||
const installedKibanaRefs = installedPkg?.attributes.installed_kibana;
|
||||
|
||||
if (installedKibanaRefs?.length) {
|
||||
await deleteKibanaSavedObjectsAssets(savedObjectsClient, installedKibanaRefs);
|
||||
await deleteKibanaInstalledRefs(savedObjectsClient, pkgName, installedKibanaRefs);
|
||||
}
|
||||
}
|
||||
|
||||
// install the new assets and save installation references
|
||||
// install the assets
|
||||
const kibanaAssetTypes = Object.values(KibanaAssetType);
|
||||
const installedAssets = await Promise.all(
|
||||
kibanaAssetTypes.map((assetType) =>
|
||||
installKibanaSavedObjects({ savedObjectsClient, assetType, paths })
|
||||
installKibanaSavedObjects({ savedObjectsClient, assetType, kibanaAssets })
|
||||
)
|
||||
);
|
||||
// installKibanaSavedObjects returns AssetReference[], so .map creates AssetReference[][]
|
||||
// call .flat to flatten into one dimensional array
|
||||
return installedAssets.flat();
|
||||
}
|
||||
export const deleteKibanaInstalledRefs = async (
|
||||
|
@ -92,21 +73,25 @@ export const deleteKibanaInstalledRefs = async (
|
|||
installed_kibana: installedAssetsToSave,
|
||||
});
|
||||
};
|
||||
|
||||
export async function getKibanaAssets(paths: string[]) {
|
||||
const isKibanaAssetType = (path: string) => Registry.pathParts(path).type in KibanaAssetType;
|
||||
const filteredPaths = paths.filter(isKibanaAssetType);
|
||||
const kibanaAssets = await Promise.all(filteredPaths.map((path) => getKibanaAsset(path)));
|
||||
return kibanaAssets;
|
||||
}
|
||||
async function installKibanaSavedObjects({
|
||||
savedObjectsClient,
|
||||
assetType,
|
||||
paths,
|
||||
kibanaAssets,
|
||||
}: {
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
assetType: KibanaAssetType;
|
||||
paths: string[];
|
||||
kibanaAssets: ArchiveAsset[];
|
||||
}) {
|
||||
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 isSameType = (asset: ArchiveAsset) => assetType === asset.type;
|
||||
const filteredKibanaAssets = kibanaAssets.filter((asset) => isSameType(asset));
|
||||
const toBeSavedObjects = await Promise.all(
|
||||
kibanaAssets.map((asset) => createSavedObjectKibanaAsset(asset))
|
||||
filteredKibanaAssets.map((asset) => createSavedObjectKibanaAsset(asset))
|
||||
);
|
||||
|
||||
if (toBeSavedObjects.length === 0) {
|
||||
|
@ -115,13 +100,11 @@ async function installKibanaSavedObjects({
|
|||
const createResults = await savedObjectsClient.bulkCreate(toBeSavedObjects, {
|
||||
overwrite: true,
|
||||
});
|
||||
const createdObjects = createResults.saved_objects;
|
||||
const installed = createdObjects.map(toAssetReference);
|
||||
return installed;
|
||||
return createResults.saved_objects;
|
||||
}
|
||||
}
|
||||
|
||||
function toAssetReference({ id, type }: SavedObject) {
|
||||
export function toAssetReference({ id, type }: SavedObject) {
|
||||
const reference: AssetReference = { id, type: type as KibanaAssetType };
|
||||
|
||||
return reference;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
*/
|
||||
|
||||
import { SavedObjectsClientContract } from 'src/core/server';
|
||||
import Boom from 'boom';
|
||||
import semver from 'semver';
|
||||
import { PACKAGES_SAVED_OBJECT_TYPE } from '../../../constants';
|
||||
import {
|
||||
|
@ -25,8 +24,15 @@ import { installTemplates } from '../elasticsearch/template/install';
|
|||
import { generateESIndexPatterns } from '../elasticsearch/template/template';
|
||||
import { installPipelines, deletePipelines } from '../elasticsearch/ingest_pipeline/';
|
||||
import { installILMPolicy } from '../elasticsearch/ilm/install';
|
||||
import { installKibanaAssets } from '../kibana/assets/install';
|
||||
import {
|
||||
installKibanaAssets,
|
||||
getKibanaAssets,
|
||||
toAssetReference,
|
||||
ArchiveAsset,
|
||||
} from '../kibana/assets/install';
|
||||
import { updateCurrentWriteIndices } from '../elasticsearch/template/template';
|
||||
import { deleteKibanaSavedObjectsAssets } from './remove';
|
||||
import { PackageOutdatedError } from '../../../errors';
|
||||
|
||||
export async function installLatestPackage(options: {
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
|
@ -97,7 +103,7 @@ export async function installPackage(options: {
|
|||
// and be replaced by getPackageInfo after adjusting for it to not group/use archive assets
|
||||
const latestPackage = await Registry.fetchFindLatestPackage(pkgName);
|
||||
if (semver.lt(pkgVersion, latestPackage.version))
|
||||
throw Boom.badRequest('Cannot install or update to an out-of-date package');
|
||||
throw new PackageOutdatedError(`${pkgkey} is out-of-date and cannot be installed or updated`);
|
||||
|
||||
const paths = await Registry.getArchiveInfo(pkgName, pkgVersion);
|
||||
const registryPackageInfo = await Registry.fetchInfo(pkgName, pkgVersion);
|
||||
|
@ -124,12 +130,23 @@ export async function installPackage(options: {
|
|||
toSaveESIndexPatterns,
|
||||
});
|
||||
}
|
||||
|
||||
const installIndexPatternPromise = installIndexPatterns(savedObjectsClient, pkgName, pkgVersion);
|
||||
const kibanaAssets = await getKibanaAssets(paths);
|
||||
if (installedPkg)
|
||||
await deleteKibanaSavedObjectsAssets(
|
||||
savedObjectsClient,
|
||||
installedPkg.attributes.installed_kibana
|
||||
);
|
||||
// save new kibana refs before installing the assets
|
||||
const installedKibanaAssetsRefs = await saveKibanaAssetsRefs(
|
||||
savedObjectsClient,
|
||||
pkgName,
|
||||
kibanaAssets
|
||||
);
|
||||
const installKibanaAssetsPromise = installKibanaAssets({
|
||||
savedObjectsClient,
|
||||
pkgName,
|
||||
paths,
|
||||
kibanaAssets,
|
||||
isUpdate,
|
||||
});
|
||||
|
||||
|
@ -169,21 +186,14 @@ export async function installPackage(options: {
|
|||
);
|
||||
}
|
||||
|
||||
// get template refs to save
|
||||
const installedTemplateRefs = installedTemplates.map((template) => ({
|
||||
id: template.templateName,
|
||||
type: ElasticsearchAssetType.indexTemplate,
|
||||
}));
|
||||
|
||||
const [installedKibanaAssets] = await Promise.all([
|
||||
installKibanaAssetsPromise,
|
||||
installIndexPatternPromise,
|
||||
]);
|
||||
|
||||
await saveInstalledKibanaRefs(savedObjectsClient, pkgName, installedKibanaAssets);
|
||||
await Promise.all([installKibanaAssetsPromise, installIndexPatternPromise]);
|
||||
// update to newly installed version when all assets are successfully installed
|
||||
if (isUpdate) await updateVersion(savedObjectsClient, pkgName, pkgVersion);
|
||||
return [...installedKibanaAssets, ...installedPipelines, ...installedTemplateRefs];
|
||||
return [...installedKibanaAssetsRefs, ...installedPipelines, ...installedTemplateRefs];
|
||||
}
|
||||
const updateVersion = async (
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
|
@ -230,15 +240,16 @@ export async function createInstallation(options: {
|
|||
return [...installedKibana, ...installedEs];
|
||||
}
|
||||
|
||||
export const saveInstalledKibanaRefs = async (
|
||||
export const saveKibanaAssetsRefs = async (
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
pkgName: string,
|
||||
installedAssets: KibanaAssetReference[]
|
||||
kibanaAssets: ArchiveAsset[]
|
||||
) => {
|
||||
const assetRefs = kibanaAssets.map(toAssetReference);
|
||||
await savedObjectsClient.update(PACKAGES_SAVED_OBJECT_TYPE, pkgName, {
|
||||
installed_kibana: installedAssets,
|
||||
installed_kibana: assetRefs,
|
||||
});
|
||||
return installedAssets;
|
||||
return assetRefs;
|
||||
};
|
||||
|
||||
export const saveInstalledEsRefs = async (
|
||||
|
|
|
@ -102,10 +102,12 @@ async function deleteTemplate(callCluster: CallESAsCurrentUser, name: string): P
|
|||
|
||||
export async function deleteKibanaSavedObjectsAssets(
|
||||
savedObjectsClient: SavedObjectsClientContract,
|
||||
installedObjects: AssetReference[]
|
||||
installedRefs: AssetReference[]
|
||||
) {
|
||||
if (!installedRefs.length) return;
|
||||
|
||||
const logger = appContextService.getLogger();
|
||||
const deletePromises = installedObjects.map(({ id, type }) => {
|
||||
const deletePromises = installedRefs.map(({ id, type }) => {
|
||||
const assetType = type as AssetType;
|
||||
|
||||
if (savedObjectTypes.includes(assetType)) {
|
||||
|
|
|
@ -22,6 +22,7 @@ import { fetchUrl, getResponse, getResponseStream } from './requests';
|
|||
import { streamToBuffer } from './streams';
|
||||
import { getRegistryUrl } from './registry_url';
|
||||
import { appContextService } from '../..';
|
||||
import { PackageNotFoundError } from '../../../errors';
|
||||
|
||||
export { ArchiveEntry } from './extract';
|
||||
|
||||
|
@ -76,7 +77,7 @@ export async function fetchFindLatestPackage(packageName: string): Promise<Regis
|
|||
if (searchResults.length) {
|
||||
return searchResults[0];
|
||||
} else {
|
||||
throw new Error('package not found');
|
||||
throw new PackageNotFoundError(`${packageName} not found`);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
17
x-pack/test/ingest_manager_api_integration/apis/epm/index.js
Normal file
17
x-pack/test/ingest_manager_api_integration/apis/epm/index.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
export default function loadTests({ loadTestFile }) {
|
||||
describe('EPM Endpoints', () => {
|
||||
loadTestFile(require.resolve('./list'));
|
||||
loadTestFile(require.resolve('./file'));
|
||||
//loadTestFile(require.resolve('./template'));
|
||||
loadTestFile(require.resolve('./ilm'));
|
||||
loadTestFile(require.resolve('./install_overrides'));
|
||||
loadTestFile(require.resolve('./install_remove_assets'));
|
||||
loadTestFile(require.resolve('./install_errors'));
|
||||
});
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* 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 expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../../../api_integration/ftr_provider_context';
|
||||
import { skipIfNoDockerRegistry } from '../../helpers';
|
||||
|
||||
export default function (providerContext: FtrProviderContext) {
|
||||
const { getService } = providerContext;
|
||||
const kibanaServer = getService('kibanaServer');
|
||||
const supertest = getService('supertest');
|
||||
|
||||
describe('package error handling', async () => {
|
||||
skipIfNoDockerRegistry(providerContext);
|
||||
it('should return 404 if package does not exist', async function () {
|
||||
await supertest
|
||||
.post(`/api/ingest_manager/epm/packages/nonexistent-0.1.0`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.expect(404);
|
||||
let res;
|
||||
try {
|
||||
res = await kibanaServer.savedObjects.get({
|
||||
type: 'epm-package',
|
||||
id: 'nonexistent',
|
||||
});
|
||||
} catch (err) {
|
||||
res = err;
|
||||
}
|
||||
expect(res.response.data.statusCode).equal(404);
|
||||
});
|
||||
it('should return 400 if trying to update/install to an out-of-date package', async function () {
|
||||
await supertest
|
||||
.post(`/api/ingest_manager/epm/packages/update-0.1.0`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.expect(400);
|
||||
let res;
|
||||
try {
|
||||
res = await kibanaServer.savedObjects.get({
|
||||
type: 'epm-package',
|
||||
id: 'update',
|
||||
});
|
||||
} catch (err) {
|
||||
res = err;
|
||||
}
|
||||
expect(res.response.data.statusCode).equal(404);
|
||||
});
|
||||
});
|
||||
}
|
|
@ -108,6 +108,54 @@ export default function (providerContext: FtrProviderContext) {
|
|||
});
|
||||
expect(resSearch.id).equal('sample_search');
|
||||
});
|
||||
it('should have created the correct saved object', async function () {
|
||||
const res = await kibanaServer.savedObjects.get({
|
||||
type: 'epm-packages',
|
||||
id: 'all_assets',
|
||||
});
|
||||
expect(res.attributes).eql({
|
||||
installed_kibana: [
|
||||
{
|
||||
id: 'sample_dashboard',
|
||||
type: 'dashboard',
|
||||
},
|
||||
{
|
||||
id: 'sample_dashboard2',
|
||||
type: 'dashboard',
|
||||
},
|
||||
{
|
||||
id: 'sample_search',
|
||||
type: 'search',
|
||||
},
|
||||
{
|
||||
id: 'sample_visualization',
|
||||
type: 'visualization',
|
||||
},
|
||||
],
|
||||
installed_es: [
|
||||
{
|
||||
id: 'logs-all_assets.test_logs-0.1.0',
|
||||
type: 'ingest_pipeline',
|
||||
},
|
||||
{
|
||||
id: 'logs-all_assets.test_logs',
|
||||
type: 'index_template',
|
||||
},
|
||||
{
|
||||
id: 'metrics-all_assets.test_metrics',
|
||||
type: 'index_template',
|
||||
},
|
||||
],
|
||||
es_index_patterns: {
|
||||
test_logs: 'logs-all_assets.test_logs-*',
|
||||
test_metrics: 'metrics-all_assets.test_metrics-*',
|
||||
},
|
||||
name: 'all_assets',
|
||||
version: '0.1.0',
|
||||
internal: false,
|
||||
removable: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('uninstalls all assets when uninstalling a package', async () => {
|
||||
|
@ -192,6 +240,18 @@ export default function (providerContext: FtrProviderContext) {
|
|||
}
|
||||
expect(resSearch.response.data.statusCode).equal(404);
|
||||
});
|
||||
it('should have removed the saved object', async function () {
|
||||
let res;
|
||||
try {
|
||||
res = await kibanaServer.savedObjects.get({
|
||||
type: 'epm-packages',
|
||||
id: 'all_assets',
|
||||
});
|
||||
} catch (err) {
|
||||
res = err;
|
||||
}
|
||||
expect(res.response.data.statusCode).equal(404);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
return response.body;
|
||||
};
|
||||
const listResponse = await fetchPackageList();
|
||||
expect(listResponse.response.length).to.be(13);
|
||||
expect(listResponse.response.length).to.be(14);
|
||||
} else {
|
||||
warnAndSkipTest(this, log);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
- name: dataset.type
|
||||
type: constant_keyword
|
||||
description: >
|
||||
Dataset type.
|
||||
- name: dataset.name
|
||||
type: constant_keyword
|
||||
description: >
|
||||
Dataset name.
|
||||
- name: dataset.namespace
|
||||
type: constant_keyword
|
||||
description: >
|
||||
Dataset namespace.
|
||||
- name: '@timestamp'
|
||||
type: date
|
||||
description: >
|
||||
Event timestamp.
|
|
@ -0,0 +1,9 @@
|
|||
title: Test Dataset
|
||||
|
||||
type: logs
|
||||
|
||||
elasticsearch:
|
||||
index_template.mappings:
|
||||
dynamic: false
|
||||
index_template.settings:
|
||||
index.lifecycle.name: reference
|
|
@ -0,0 +1,3 @@
|
|||
# Test package
|
||||
|
||||
This is a test package for testing installing or updating to an out-of-date package
|
|
@ -0,0 +1,20 @@
|
|||
format_version: 1.0.0
|
||||
name: update
|
||||
title: Package update test
|
||||
description: This is a test package for updating a package
|
||||
version: 0.1.0
|
||||
categories: []
|
||||
release: beta
|
||||
type: integration
|
||||
license: basic
|
||||
|
||||
requirement:
|
||||
elasticsearch:
|
||||
versions: '>7.7.0'
|
||||
kibana:
|
||||
versions: '>7.7.0'
|
||||
|
||||
icons:
|
||||
- src: '/img/logo_overrides_64_color.svg'
|
||||
size: '16x16'
|
||||
type: 'image/svg+xml'
|
|
@ -0,0 +1,16 @@
|
|||
- name: dataset.type
|
||||
type: constant_keyword
|
||||
description: >
|
||||
Dataset type.
|
||||
- name: dataset.name
|
||||
type: constant_keyword
|
||||
description: >
|
||||
Dataset name.
|
||||
- name: dataset.namespace
|
||||
type: constant_keyword
|
||||
description: >
|
||||
Dataset namespace.
|
||||
- name: '@timestamp'
|
||||
type: date
|
||||
description: >
|
||||
Event timestamp.
|
|
@ -0,0 +1,9 @@
|
|||
title: Test Dataset
|
||||
|
||||
type: logs
|
||||
|
||||
elasticsearch:
|
||||
index_template.mappings:
|
||||
dynamic: false
|
||||
index_template.settings:
|
||||
index.lifecycle.name: reference
|
|
@ -0,0 +1,3 @@
|
|||
# Test package
|
||||
|
||||
This is a test package for testing installing or updating to an out-of-date package
|
|
@ -0,0 +1,20 @@
|
|||
format_version: 1.0.0
|
||||
name: update
|
||||
title: Package update test
|
||||
description: This is a test package for updating a package
|
||||
version: 0.2.0
|
||||
categories: []
|
||||
release: beta
|
||||
type: integration
|
||||
license: basic
|
||||
|
||||
requirement:
|
||||
elasticsearch:
|
||||
versions: '>7.7.0'
|
||||
kibana:
|
||||
versions: '>7.7.0'
|
||||
|
||||
icons:
|
||||
- src: '/img/logo_overrides_64_color.svg'
|
||||
size: '16x16'
|
||||
type: 'image/svg+xml'
|
|
@ -12,12 +12,7 @@ export default function ({ loadTestFile }) {
|
|||
loadTestFile(require.resolve('./fleet/index'));
|
||||
|
||||
// EPM
|
||||
loadTestFile(require.resolve('./epm/list'));
|
||||
loadTestFile(require.resolve('./epm/file'));
|
||||
//loadTestFile(require.resolve('./epm/template'));
|
||||
loadTestFile(require.resolve('./epm/ilm'));
|
||||
loadTestFile(require.resolve('./epm/install_overrides'));
|
||||
loadTestFile(require.resolve('./epm/install_remove_assets'));
|
||||
loadTestFile(require.resolve('./epm/index'));
|
||||
|
||||
// Package configs
|
||||
loadTestFile(require.resolve('./package_config/create'));
|
||||
|
|
Loading…
Reference in a new issue