mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
[Fleet] catching only mapper errors (#167044)
Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
01f4d61d00
commit
08d44fe52b
12 changed files with 447 additions and 16 deletions
|
@ -572,6 +572,24 @@
|
|||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/kbn_xsrf"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "ignoreMappingUpdateErrors",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"description": "avoid erroring out on unexpected mapping update errors"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "skipDataStreamRollover",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"description": "skip data stream rollover during index template mapping or settings update"
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
|
@ -810,6 +828,24 @@
|
|||
"name": "pkgkey",
|
||||
"in": "path",
|
||||
"required": true
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "ignoreMappingUpdateErrors",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"description": "avoid erroring out on unexpected mapping update errors"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "skipDataStreamRollover",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"description": "skip data stream rollover during index template mapping or settings update"
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
|
@ -1090,6 +1126,24 @@
|
|||
"parameters": [
|
||||
{
|
||||
"$ref": "#/components/parameters/kbn_xsrf"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "ignoreMappingUpdateErrors",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"description": "avoid erroring out on unexpected mapping update errors"
|
||||
},
|
||||
{
|
||||
"in": "query",
|
||||
"name": "skipDataStreamRollover",
|
||||
"schema": {
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"description": "skip data stream rollover during index template mapping or settings update"
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
|
|
|
@ -368,6 +368,20 @@ paths:
|
|||
description: ''
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/kbn_xsrf'
|
||||
- in: query
|
||||
name: ignoreMappingUpdateErrors
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: avoid erroring out on unexpected mapping update errors
|
||||
- in: query
|
||||
name: skipDataStreamRollover
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: >-
|
||||
skip data stream rollover during index template mapping or settings
|
||||
update
|
||||
requestBody:
|
||||
content:
|
||||
application/zip:
|
||||
|
@ -516,6 +530,20 @@ paths:
|
|||
name: pkgkey
|
||||
in: path
|
||||
required: true
|
||||
- in: query
|
||||
name: ignoreMappingUpdateErrors
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: avoid erroring out on unexpected mapping update errors
|
||||
- in: query
|
||||
name: skipDataStreamRollover
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: >-
|
||||
skip data stream rollover during index template mapping or settings
|
||||
update
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
|
@ -689,6 +717,20 @@ paths:
|
|||
description: ''
|
||||
parameters:
|
||||
- $ref: '#/components/parameters/kbn_xsrf'
|
||||
- in: query
|
||||
name: ignoreMappingUpdateErrors
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: avoid erroring out on unexpected mapping update errors
|
||||
- in: query
|
||||
name: skipDataStreamRollover
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: >-
|
||||
skip data stream rollover during index template mapping or settings
|
||||
update
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
|
|
|
@ -83,6 +83,18 @@ post:
|
|||
description: ''
|
||||
parameters:
|
||||
- $ref: ../components/headers/kbn_xsrf.yaml
|
||||
- in: query
|
||||
name: ignoreMappingUpdateErrors
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: avoid erroring out on unexpected mapping update errors
|
||||
- in: query
|
||||
name: skipDataStreamRollover
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: skip data stream rollover during index template mapping or settings update
|
||||
requestBody:
|
||||
content:
|
||||
application/zip:
|
||||
|
|
|
@ -111,6 +111,18 @@ post:
|
|||
description: ''
|
||||
parameters:
|
||||
- $ref: ../components/headers/kbn_xsrf.yaml
|
||||
- in: query
|
||||
name: ignoreMappingUpdateErrors
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: avoid erroring out on unexpected mapping update errors
|
||||
- in: query
|
||||
name: skipDataStreamRollover
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: skip data stream rollover during index template mapping or settings update
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
|
|
|
@ -84,6 +84,18 @@ post:
|
|||
name: pkgkey
|
||||
in: path
|
||||
required: true
|
||||
- in: query
|
||||
name: ignoreMappingUpdateErrors
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: avoid erroring out on unexpected mapping update errors
|
||||
- in: query
|
||||
name: skipDataStreamRollover
|
||||
schema:
|
||||
type: boolean
|
||||
default: false
|
||||
description: skip data stream rollover during index template mapping or settings update
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
|
|
|
@ -392,6 +392,8 @@ export const installPackageFromRegistryHandler: FleetRequestHandler<
|
|||
ignoreConstraints: request.body?.ignore_constraints,
|
||||
prerelease: request.query?.prerelease,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors: request.query?.ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover: request.query?.skipDataStreamRollover,
|
||||
});
|
||||
|
||||
if (!res.error) {
|
||||
|
@ -509,7 +511,7 @@ export const bulkInstallPackagesFromRegistryHandler: FleetRequestHandler<
|
|||
|
||||
export const installPackageByUploadHandler: FleetRequestHandler<
|
||||
undefined,
|
||||
undefined,
|
||||
TypeOf<typeof InstallPackageByUploadRequestSchema.query>,
|
||||
TypeOf<typeof InstallPackageByUploadRequestSchema.body>
|
||||
> = async (context, request, response) => {
|
||||
const coreContext = await context.core;
|
||||
|
@ -531,6 +533,8 @@ export const installPackageByUploadHandler: FleetRequestHandler<
|
|||
spaceId,
|
||||
contentType,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors: request.query?.ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover: request.query?.skipDataStreamRollover,
|
||||
});
|
||||
if (!res.error) {
|
||||
const body: InstallPackageResponse = {
|
||||
|
|
|
@ -12,6 +12,8 @@ import { safeLoad } from 'js-yaml';
|
|||
import { loggerMock } from '@kbn/logging-mocks';
|
||||
import { elasticsearchServiceMock } from '@kbn/core/server/mocks';
|
||||
|
||||
import { errors } from '@elastic/elasticsearch';
|
||||
|
||||
import { createAppContextStartContractMock } from '../../../../mocks';
|
||||
import { appContextService } from '../../..';
|
||||
import type { RegistryDataStream } from '../../../../types';
|
||||
|
@ -1261,5 +1263,134 @@ describe('EPM template', () => {
|
|||
},
|
||||
});
|
||||
});
|
||||
it('should rollover on expected error', async () => {
|
||||
const esClient = elasticsearchServiceMock.createElasticsearchClient();
|
||||
esClient.indices.getDataStream.mockResponse({
|
||||
data_streams: [{ name: 'test.prefix1-default' }],
|
||||
} as any);
|
||||
esClient.indices.simulateTemplate.mockImplementation(() => {
|
||||
throw new errors.ResponseError({
|
||||
statusCode: 400,
|
||||
body: {
|
||||
error: {
|
||||
type: 'illegal_argument_exception',
|
||||
},
|
||||
},
|
||||
} as any);
|
||||
});
|
||||
const logger = loggerMock.create();
|
||||
await updateCurrentWriteIndices(esClient, logger, [
|
||||
{
|
||||
templateName: 'test',
|
||||
indexTemplate: {
|
||||
index_patterns: ['test.*-*'],
|
||||
template: {
|
||||
settings: { index: {} },
|
||||
mappings: { properties: {} },
|
||||
},
|
||||
} as any,
|
||||
},
|
||||
]);
|
||||
|
||||
expect(esClient.indices.rollover).toHaveBeenCalled();
|
||||
});
|
||||
it('should skip rollover on expected error when flag is on', async () => {
|
||||
const esClient = elasticsearchServiceMock.createElasticsearchClient();
|
||||
esClient.indices.getDataStream.mockResponse({
|
||||
data_streams: [{ name: 'test.prefix1-default' }],
|
||||
} as any);
|
||||
esClient.indices.simulateTemplate.mockImplementation(() => {
|
||||
throw new errors.ResponseError({
|
||||
statusCode: 400,
|
||||
body: {
|
||||
error: {
|
||||
type: 'illegal_argument_exception',
|
||||
},
|
||||
},
|
||||
} as any);
|
||||
});
|
||||
const logger = loggerMock.create();
|
||||
await updateCurrentWriteIndices(
|
||||
esClient,
|
||||
logger,
|
||||
[
|
||||
{
|
||||
templateName: 'test',
|
||||
indexTemplate: {
|
||||
index_patterns: ['test.*-*'],
|
||||
template: {
|
||||
settings: { index: {} },
|
||||
mappings: { properties: {} },
|
||||
},
|
||||
} as any,
|
||||
},
|
||||
],
|
||||
{
|
||||
skipDataStreamRollover: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(esClient.indices.rollover).not.toHaveBeenCalled();
|
||||
});
|
||||
it('should not rollover on unexpected error', async () => {
|
||||
const esClient = elasticsearchServiceMock.createElasticsearchClient();
|
||||
esClient.indices.getDataStream.mockResponse({
|
||||
data_streams: [{ name: 'test.prefix1-default' }],
|
||||
} as any);
|
||||
esClient.indices.simulateTemplate.mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
const logger = loggerMock.create();
|
||||
try {
|
||||
await updateCurrentWriteIndices(esClient, logger, [
|
||||
{
|
||||
templateName: 'test',
|
||||
indexTemplate: {
|
||||
index_patterns: ['test.*-*'],
|
||||
template: {
|
||||
settings: { index: {} },
|
||||
mappings: { properties: {} },
|
||||
},
|
||||
} as any,
|
||||
},
|
||||
]);
|
||||
fail('expected updateCurrentWriteIndices to throw error');
|
||||
} catch (err) {
|
||||
// noop
|
||||
}
|
||||
|
||||
expect(esClient.indices.rollover).not.toHaveBeenCalled();
|
||||
});
|
||||
it('should not throw on unexpected error when flag is on', async () => {
|
||||
const esClient = elasticsearchServiceMock.createElasticsearchClient();
|
||||
esClient.indices.getDataStream.mockResponse({
|
||||
data_streams: [{ name: 'test.prefix1-default' }],
|
||||
} as any);
|
||||
esClient.indices.simulateTemplate.mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
const logger = loggerMock.create();
|
||||
await updateCurrentWriteIndices(
|
||||
esClient,
|
||||
logger,
|
||||
[
|
||||
{
|
||||
templateName: 'test',
|
||||
indexTemplate: {
|
||||
index_patterns: ['test.*-*'],
|
||||
template: {
|
||||
settings: { index: {} },
|
||||
mappings: { properties: {} },
|
||||
},
|
||||
} as any,
|
||||
},
|
||||
],
|
||||
{
|
||||
ignoreMappingUpdateErrors: true,
|
||||
}
|
||||
);
|
||||
|
||||
expect(esClient.indices.rollover).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -12,6 +12,7 @@ import type {
|
|||
} from '@elastic/elasticsearch/lib/api/typesWithBodyKey';
|
||||
|
||||
import pMap from 'p-map';
|
||||
import { isResponseError } from '@kbn/es-errors';
|
||||
|
||||
import type { Field, Fields } from '../../fields/field';
|
||||
import type {
|
||||
|
@ -662,7 +663,11 @@ function getBaseTemplate({
|
|||
export const updateCurrentWriteIndices = async (
|
||||
esClient: ElasticsearchClient,
|
||||
logger: Logger,
|
||||
templates: IndexTemplateEntry[]
|
||||
templates: IndexTemplateEntry[],
|
||||
options?: {
|
||||
ignoreMappingUpdateErrors?: boolean;
|
||||
skipDataStreamRollover?: boolean;
|
||||
}
|
||||
): Promise<void> => {
|
||||
if (!templates.length) return;
|
||||
|
||||
|
@ -677,7 +682,7 @@ export const updateCurrentWriteIndices = async (
|
|||
return true;
|
||||
});
|
||||
if (!allUpdatablesIndices.length) return;
|
||||
return updateAllDataStreams(allUpdatablesIndices, esClient, logger);
|
||||
return updateAllDataStreams(allUpdatablesIndices, esClient, logger, options);
|
||||
};
|
||||
|
||||
function isCurrentDataStream(item: CurrentDataStream[] | undefined): item is CurrentDataStream[] {
|
||||
|
@ -729,7 +734,11 @@ const rolloverDataStream = (dataStreamName: string, esClient: ElasticsearchClien
|
|||
const updateAllDataStreams = async (
|
||||
indexNameWithTemplates: CurrentDataStream[],
|
||||
esClient: ElasticsearchClient,
|
||||
logger: Logger
|
||||
logger: Logger,
|
||||
options?: {
|
||||
ignoreMappingUpdateErrors?: boolean;
|
||||
skipDataStreamRollover?: boolean;
|
||||
}
|
||||
): Promise<void> => {
|
||||
await pMap(
|
||||
indexNameWithTemplates,
|
||||
|
@ -738,6 +747,7 @@ const updateAllDataStreams = async (
|
|||
esClient,
|
||||
logger,
|
||||
dataStreamName: templateEntry.dataStreamName,
|
||||
options,
|
||||
});
|
||||
},
|
||||
{
|
||||
|
@ -751,10 +761,15 @@ const updateExistingDataStream = async ({
|
|||
dataStreamName,
|
||||
esClient,
|
||||
logger,
|
||||
options,
|
||||
}: {
|
||||
dataStreamName: string;
|
||||
esClient: ElasticsearchClient;
|
||||
logger: Logger;
|
||||
options?: {
|
||||
ignoreMappingUpdateErrors?: boolean;
|
||||
skipDataStreamRollover?: boolean;
|
||||
};
|
||||
}) => {
|
||||
const existingDs = await esClient.indices.get({
|
||||
index: dataStreamName,
|
||||
|
@ -804,18 +819,45 @@ const updateExistingDataStream = async ({
|
|||
|
||||
// if update fails, rollover data stream and bail out
|
||||
} catch (err) {
|
||||
logger.info(`Mappings update for ${dataStreamName} failed due to ${err}`);
|
||||
logger.info(`Triggering a rollover for ${dataStreamName}`);
|
||||
await rolloverDataStream(dataStreamName, esClient);
|
||||
return;
|
||||
if (
|
||||
isResponseError(err) &&
|
||||
err.statusCode === 400 &&
|
||||
err.body?.error?.type === 'illegal_argument_exception'
|
||||
) {
|
||||
logger.info(`Mappings update for ${dataStreamName} failed due to ${err}`);
|
||||
if (options?.skipDataStreamRollover === true) {
|
||||
logger.info(
|
||||
`Skipping rollover for ${dataStreamName} as "skipDataStreamRollover" is enabled`
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
logger.info(`Triggering a rollover for ${dataStreamName}`);
|
||||
await rolloverDataStream(dataStreamName, esClient);
|
||||
return;
|
||||
}
|
||||
}
|
||||
logger.error(`Mappings update for ${dataStreamName} failed due to unexpected error: ${err}`);
|
||||
if (options?.ignoreMappingUpdateErrors === true) {
|
||||
logger.info(`Ignore mapping update errors as "ignoreMappingUpdateErrors" is enabled`);
|
||||
return;
|
||||
} else {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
// Trigger a rollover if the index mode or source type has changed
|
||||
if (currentIndexMode !== settings?.index?.mode || currentSourceType !== mappings?._source?.mode) {
|
||||
logger.info(
|
||||
`Index mode or source type has changed for ${dataStreamName}, triggering a rollover`
|
||||
);
|
||||
await rolloverDataStream(dataStreamName, esClient);
|
||||
if (options?.skipDataStreamRollover === true) {
|
||||
logger.info(
|
||||
`Index mode or source type has changed for ${dataStreamName}, skipping rollover as "skipDataStreamRollover" is enabled`
|
||||
);
|
||||
return;
|
||||
} else {
|
||||
logger.info(
|
||||
`Index mode or source type has changed for ${dataStreamName}, triggering a rollover`
|
||||
);
|
||||
await rolloverDataStream(dataStreamName, esClient);
|
||||
}
|
||||
}
|
||||
|
||||
if (lifecycle?.data_retention) {
|
||||
|
|
|
@ -77,6 +77,8 @@ export async function _installPackage({
|
|||
force,
|
||||
verificationResult,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
}: {
|
||||
savedObjectsClient: SavedObjectsClientContract;
|
||||
savedObjectsImporter: Pick<ISavedObjectsImporter, 'import' | 'resolveImportErrors'>;
|
||||
|
@ -93,6 +95,8 @@ export async function _installPackage({
|
|||
force?: boolean;
|
||||
verificationResult?: PackageVerificationResult;
|
||||
authorizationHeader?: HTTPAuthorizationHeader | null;
|
||||
ignoreMappingUpdateErrors?: boolean;
|
||||
skipDataStreamRollover?: boolean;
|
||||
}): Promise<AssetReference[]> {
|
||||
const { name: pkgName, version: pkgVersion, title: pkgTitle } = packageInfo;
|
||||
|
||||
|
@ -250,7 +254,10 @@ export async function _installPackage({
|
|||
|
||||
// update current backing indices of each data stream
|
||||
await withPackageSpan('Update write indices', () =>
|
||||
updateCurrentWriteIndices(esClient, logger, indexTemplates)
|
||||
updateCurrentWriteIndices(esClient, logger, indexTemplates, {
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
})
|
||||
);
|
||||
|
||||
({ esReferences } = await withPackageSpan('Install transforms', () =>
|
||||
|
|
|
@ -300,6 +300,8 @@ interface InstallRegistryPackageParams {
|
|||
ignoreConstraints?: boolean;
|
||||
prerelease?: boolean;
|
||||
authorizationHeader?: HTTPAuthorizationHeader | null;
|
||||
ignoreMappingUpdateErrors?: boolean;
|
||||
skipDataStreamRollover?: boolean;
|
||||
}
|
||||
|
||||
export interface CustomPackageDatasetConfiguration {
|
||||
|
@ -324,6 +326,8 @@ interface InstallUploadedArchiveParams {
|
|||
spaceId: string;
|
||||
version?: string;
|
||||
authorizationHeader?: HTTPAuthorizationHeader | null;
|
||||
ignoreMappingUpdateErrors?: boolean;
|
||||
skipDataStreamRollover?: boolean;
|
||||
}
|
||||
|
||||
function getTelemetryEvent(pkgName: string, pkgVersion: string): PackageUpdateEvent {
|
||||
|
@ -356,6 +360,8 @@ async function installPackageFromRegistry({
|
|||
ignoreConstraints = false,
|
||||
neverIgnoreVerificationError = false,
|
||||
prerelease = false,
|
||||
ignoreMappingUpdateErrors = false,
|
||||
skipDataStreamRollover = false,
|
||||
}: InstallRegistryPackageParams): Promise<InstallResult> {
|
||||
const logger = appContextService.getLogger();
|
||||
// TODO: change epm API to /packageName/version so we don't need to do this
|
||||
|
@ -429,6 +435,8 @@ async function installPackageFromRegistry({
|
|||
paths,
|
||||
verificationResult,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
});
|
||||
} catch (e) {
|
||||
sendEvent({
|
||||
|
@ -464,6 +472,8 @@ async function installPackageCommon(options: {
|
|||
verificationResult?: PackageVerificationResult;
|
||||
telemetryEvent?: PackageUpdateEvent;
|
||||
authorizationHeader?: HTTPAuthorizationHeader | null;
|
||||
ignoreMappingUpdateErrors?: boolean;
|
||||
skipDataStreamRollover?: boolean;
|
||||
}): Promise<InstallResult> {
|
||||
const {
|
||||
pkgName,
|
||||
|
@ -479,6 +489,8 @@ async function installPackageCommon(options: {
|
|||
paths,
|
||||
verificationResult,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
} = options;
|
||||
let { telemetryEvent } = options;
|
||||
const logger = appContextService.getLogger();
|
||||
|
@ -568,6 +580,8 @@ async function installPackageCommon(options: {
|
|||
installSource,
|
||||
authorizationHeader,
|
||||
force,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
})
|
||||
.then(async (assets) => {
|
||||
await removeOldAssets({
|
||||
|
@ -622,6 +636,8 @@ async function installPackageByUpload({
|
|||
spaceId,
|
||||
version,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
}: InstallUploadedArchiveParams): Promise<InstallResult> {
|
||||
// if an error happens during getInstallType, report that we don't know
|
||||
let installType: InstallType = 'unknown';
|
||||
|
@ -670,6 +686,8 @@ async function installPackageByUpload({
|
|||
packageInfo,
|
||||
paths,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
});
|
||||
} catch (e) {
|
||||
return {
|
||||
|
@ -703,8 +721,16 @@ export async function installPackage(args: InstallPackageParams): Promise<Instal
|
|||
const bundledPackages = await getBundledPackages();
|
||||
|
||||
if (args.installSource === 'registry') {
|
||||
const { pkgkey, force, ignoreConstraints, spaceId, neverIgnoreVerificationError, prerelease } =
|
||||
args;
|
||||
const {
|
||||
pkgkey,
|
||||
force,
|
||||
ignoreConstraints,
|
||||
spaceId,
|
||||
neverIgnoreVerificationError,
|
||||
prerelease,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
} = args;
|
||||
|
||||
const matchingBundledPackage = bundledPackages.find(
|
||||
(pkg) => Registry.pkgToPkgKey(pkg) === pkgkey
|
||||
|
@ -723,6 +749,8 @@ export async function installPackage(args: InstallPackageParams): Promise<Instal
|
|||
spaceId,
|
||||
version: matchingBundledPackage.version,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
});
|
||||
|
||||
return { ...response, installSource: 'bundled' };
|
||||
|
@ -739,10 +767,18 @@ export async function installPackage(args: InstallPackageParams): Promise<Instal
|
|||
ignoreConstraints,
|
||||
prerelease,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
});
|
||||
return response;
|
||||
} else if (args.installSource === 'upload') {
|
||||
const { archiveBuffer, contentType, spaceId } = args;
|
||||
const {
|
||||
archiveBuffer,
|
||||
contentType,
|
||||
spaceId,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
} = args;
|
||||
const response = await installPackageByUpload({
|
||||
savedObjectsClient,
|
||||
esClient,
|
||||
|
@ -750,6 +786,8 @@ export async function installPackage(args: InstallPackageParams): Promise<Instal
|
|||
contentType,
|
||||
spaceId,
|
||||
authorizationHeader,
|
||||
ignoreMappingUpdateErrors,
|
||||
skipDataStreamRollover,
|
||||
});
|
||||
return response;
|
||||
} else if (args.installSource === 'custom') {
|
||||
|
|
|
@ -138,6 +138,8 @@ export const InstallPackageFromRegistryRequestSchema = {
|
|||
}),
|
||||
query: schema.object({
|
||||
prerelease: schema.maybe(schema.boolean()),
|
||||
ignoreMappingUpdateErrors: schema.boolean({ defaultValue: false }),
|
||||
skipDataStreamRollover: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
body: schema.nullable(
|
||||
schema.object({
|
||||
|
@ -166,6 +168,8 @@ export const InstallPackageFromRegistryRequestSchemaDeprecated = {
|
|||
}),
|
||||
query: schema.object({
|
||||
prerelease: schema.maybe(schema.boolean()),
|
||||
ignoreMappingUpdateErrors: schema.boolean({ defaultValue: false }),
|
||||
skipDataStreamRollover: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
body: schema.nullable(
|
||||
schema.object({
|
||||
|
@ -191,6 +195,10 @@ export const BulkInstallPackagesFromRegistryRequestSchema = {
|
|||
};
|
||||
|
||||
export const InstallPackageByUploadRequestSchema = {
|
||||
query: schema.object({
|
||||
ignoreMappingUpdateErrors: schema.boolean({ defaultValue: false }),
|
||||
skipDataStreamRollover: schema.boolean({ defaultValue: false }),
|
||||
}),
|
||||
body: schema.buffer(),
|
||||
};
|
||||
|
||||
|
|
|
@ -143,5 +143,74 @@ export default function (providerContext: FtrProviderContext) {
|
|||
// datastream did not roll over
|
||||
expect(indicesAfter).equal(indicesBefore);
|
||||
});
|
||||
|
||||
it('should not rollover datastream when failed to update mappings and skipDataStreamRollover is true', async function () {
|
||||
await supertest
|
||||
.post(`/api/fleet/epm/packages/apm/8.7.0`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({ force: true })
|
||||
.expect(200);
|
||||
|
||||
await es.index({
|
||||
index: 'metrics-apm.service_summary.10m-default',
|
||||
document: {
|
||||
'@timestamp': '2023-05-30T07:50:00.000Z',
|
||||
agent: {
|
||||
name: 'go',
|
||||
},
|
||||
data_stream: {
|
||||
dataset: 'apm.service_summary.10m',
|
||||
namespace: 'default',
|
||||
type: 'metrics',
|
||||
},
|
||||
ecs: {
|
||||
version: '8.6.0-dev',
|
||||
},
|
||||
event: {
|
||||
agent_id_status: 'missing',
|
||||
ingested: '2023-05-30T07:57:12Z',
|
||||
},
|
||||
metricset: {
|
||||
interval: '10m',
|
||||
name: 'service_summary',
|
||||
},
|
||||
observer: {
|
||||
hostname: '047e282994fb',
|
||||
type: 'apm-server',
|
||||
version: '8.7.0',
|
||||
},
|
||||
processor: {
|
||||
event: 'metric',
|
||||
name: 'metric',
|
||||
},
|
||||
service: {
|
||||
language: {
|
||||
name: 'go',
|
||||
},
|
||||
name: '___main_elastic_cloud_87_ilm_fix',
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
let ds = await es.indices.get({
|
||||
index: 'metrics-apm.service_summary*',
|
||||
expand_wildcards: ['open', 'hidden'],
|
||||
});
|
||||
const indicesBefore = Object.keys(ds).length;
|
||||
|
||||
await supertest
|
||||
.post(`/api/fleet/epm/packages/apm/8.8.0?skipDataStreamRollover=true`)
|
||||
.set('kbn-xsrf', 'xxxx')
|
||||
.send({ force: true })
|
||||
.expect(200);
|
||||
|
||||
ds = await es.indices.get({
|
||||
index: 'metrics-apm.service_summary*',
|
||||
expand_wildcards: ['open', 'hidden'],
|
||||
});
|
||||
const indicesAfter = Object.keys(ds).length;
|
||||
// datastream did not roll over
|
||||
expect(indicesAfter).equal(indicesBefore);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue