[8.16] Update mappings if/when new SO types are introduced (#197061) (#197573)

# Backport

This will backport the following commits from `main` to `8.16`:
- [Update mappings if/when new SO types are introduced
(#197061)](https://github.com/elastic/kibana/pull/197061)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Gerard
Soldevila","email":"gerard.soldevila@elastic.co"},"sourceCommit":{"committedDate":"2024-10-24T08:21:43Z","message":"Update
mappings if/when new SO types are introduced (#197061)\n\n##
Summary\r\n\r\nAddresses
https://github.com/elastic/elastic-entity-model/issues/70\r\nFixes
regression introduced
in\r\nhttps://github.com/elastic/kibana/pull/176803","sha":"8de3636e43be7c874b2c3457f1496a0fc31f224d","branchLabelMapping":{"^v9.0.0$":"main","^v8.17.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["bug","Team:Core","release_note:skip","v9.0.0","backport:prev-minor","backport:prev-major","v8.16.0","v8.15.3"],"title":"Update
mappings if/when new SO types are
introduced","number":197061,"url":"https://github.com/elastic/kibana/pull/197061","mergeCommit":{"message":"Update
mappings if/when new SO types are introduced (#197061)\n\n##
Summary\r\n\r\nAddresses
https://github.com/elastic/elastic-entity-model/issues/70\r\nFixes
regression introduced
in\r\nhttps://github.com/elastic/kibana/pull/176803","sha":"8de3636e43be7c874b2c3457f1496a0fc31f224d"}},"sourceBranch":"main","suggestedTargetBranches":["8.16","8.15"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/197061","number":197061,"mergeCommit":{"message":"Update
mappings if/when new SO types are introduced (#197061)\n\n##
Summary\r\n\r\nAddresses
https://github.com/elastic/elastic-entity-model/issues/70\r\nFixes
regression introduced
in\r\nhttps://github.com/elastic/kibana/pull/176803","sha":"8de3636e43be7c874b2c3457f1496a0fc31f224d"}},{"branch":"8.16","label":"v8.16.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.15","label":"v8.15.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Gerard Soldevila <gerard.soldevila@elastic.co>
This commit is contained in:
Kibana Machine 2024-10-24 21:11:52 +11:00 committed by GitHub
parent 6a58931276
commit 3687435cb4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
13 changed files with 217 additions and 102 deletions

View file

@ -176,8 +176,9 @@ describe('checkTargetTypesMappings', () => {
const result = await task();
expect(result).toEqual(
Either.right({
type: 'types_match' as const,
Either.left({
type: 'types_added' as const,
newTypes: ['type3'],
})
);
});

View file

@ -11,7 +11,7 @@ import * as Either from 'fp-ts/lib/Either';
import * as TaskEither from 'fp-ts/lib/TaskEither';
import type { IndexMapping, VirtualVersionMap } from '@kbn/core-saved-objects-base-server-internal';
import { getUpdatedTypes } from '../core/compare_mappings';
import { getNewAndUpdatedTypes } from '../core/compare_mappings';
/** @internal */
export interface CheckTargetTypesMappingsParams {
@ -38,6 +38,12 @@ export interface TypesChanged {
updatedTypes: string[];
}
/** @internal */
export interface TypesAdded {
type: 'types_added';
newTypes: string[];
}
export const checkTargetTypesMappings =
({
indexTypes,
@ -46,7 +52,7 @@ export const checkTargetTypesMappings =
latestMappingsVersions,
hashToVersionMap = {},
}: CheckTargetTypesMappingsParams): TaskEither.TaskEither<
IndexMappingsIncomplete | TypesChanged,
IndexMappingsIncomplete | TypesChanged | TypesAdded,
TypesMatch
> =>
async () => {
@ -58,7 +64,7 @@ export const checkTargetTypesMappings =
return Either.left({ type: 'index_mappings_incomplete' as const });
}
const updatedTypes = getUpdatedTypes({
const { newTypes, updatedTypes } = getNewAndUpdatedTypes({
indexTypes,
indexMeta: indexMappings?._meta,
latestMappingsVersions,
@ -70,6 +76,11 @@ export const checkTargetTypesMappings =
type: 'types_changed' as const,
updatedTypes,
});
} else if (newTypes.length) {
return Either.left({
type: 'types_added' as const,
newTypes,
});
} else {
return Either.right({ type: 'types_match' as const });
}

View file

@ -112,7 +112,7 @@ import type { UnknownDocsFound } from './check_for_unknown_docs';
import type { IncompatibleClusterRoutingAllocation } from './check_cluster_routing_allocation';
import type { ClusterShardLimitExceeded } from './create_index';
import type { SynchronizationFailed } from './synchronize_migrators';
import type { IndexMappingsIncomplete, TypesChanged } from './check_target_mappings';
import type { IndexMappingsIncomplete, TypesAdded, TypesChanged } from './check_target_mappings';
export type {
CheckForUnknownDocsParams,
@ -193,6 +193,7 @@ export interface ActionErrorTypeMap {
synchronization_failed: SynchronizationFailed;
index_mappings_incomplete: IndexMappingsIncomplete;
types_changed: TypesChanged;
types_added: TypesAdded;
operation_not_supported: OperationNotSupported;
source_equals_target: SourceEqualsTarget;
}

View file

@ -47,6 +47,7 @@ describe('updateSourceMappingsProperties', () => {
appMappings: {
properties: {
a: { type: 'keyword' },
b: { type: 'long' },
c: { type: 'long' },
...getBaseMappings().properties,
},
@ -66,6 +67,21 @@ describe('updateSourceMappingsProperties', () => {
});
it('should not update mappings when there are no changes', async () => {
// we overwrite the app mappings to have the "unchanged" values with respect to the index mappings
const sameMappingsParams = chain(params)
// let's not introduce 'c' for now
.set('indexTypes', ['a', 'b'])
// even if the app versions are more recent, we emulate a scenario where mappings haven NOT changed
.set('latestMappingsVersions', { a: '10.1.0', b: '10.1.0' })
.value();
const result = await updateSourceMappingsProperties(sameMappingsParams)();
expect(client.indices.putMapping).not.toHaveBeenCalled();
expect(Either.isRight(result)).toEqual(true);
expect(result).toHaveProperty('right', 'update_mappings_succeeded');
});
it('should update mappings if there are new types', async () => {
// we overwrite the app mappings to have the "unchanged" values with respect to the index mappings
const sameMappingsParams = chain(params)
// even if the app versions are more recent, we emulate a scenario where mappings haven NOT changed
@ -73,7 +89,16 @@ describe('updateSourceMappingsProperties', () => {
.value();
const result = await updateSourceMappingsProperties(sameMappingsParams)();
expect(client.indices.putMapping).not.toHaveBeenCalled();
expect(client.indices.putMapping).toHaveBeenCalledTimes(1);
expect(client.indices.putMapping).toHaveBeenCalledWith(
expect.objectContaining({
properties: expect.objectContaining({
a: { type: 'keyword' },
b: { type: 'long' },
c: { type: 'long' },
}),
})
);
expect(Either.isRight(result)).toEqual(true);
expect(result).toHaveProperty('right', 'update_mappings_succeeded');
});

View file

@ -9,17 +9,20 @@
import type { IndexMappingMeta } from '@kbn/core-saved-objects-base-server-internal';
import { getBaseMappings } from './build_active_mappings';
import { getUpdatedTypes, getUpdatedRootFields } from './compare_mappings';
import { getUpdatedRootFields, getNewAndUpdatedTypes } from './compare_mappings';
describe('getUpdatedTypes', () => {
describe('getNewAndUpdatedTypes', () => {
test('returns all types if _meta is missing in indexMappings', () => {
const indexTypes = ['foo', 'bar'];
const latestMappingsVersions = {};
expect(getUpdatedTypes({ indexTypes, indexMeta: undefined, latestMappingsVersions })).toEqual([
'foo',
'bar',
]);
const { newTypes, updatedTypes } = getNewAndUpdatedTypes({
indexTypes,
indexMeta: undefined,
latestMappingsVersions,
});
expect(newTypes).toEqual([]);
expect(updatedTypes).toEqual(['foo', 'bar']);
});
test('returns all types if migrationMappingPropertyHashes and mappingVersions are missing in indexMappings', () => {
@ -27,14 +30,17 @@ describe('getUpdatedTypes', () => {
const indexMeta: IndexMappingMeta = {};
const latestMappingsVersions = {};
expect(getUpdatedTypes({ indexTypes, indexMeta, latestMappingsVersions })).toEqual([
'foo',
'bar',
]);
const { newTypes, updatedTypes } = getNewAndUpdatedTypes({
indexTypes,
indexMeta,
latestMappingsVersions,
});
expect(newTypes).toEqual([]);
expect(updatedTypes).toEqual(['foo', 'bar']);
});
describe('when ONLY migrationMappingPropertyHashes exists in indexMappings', () => {
test('uses the provided hashToVersionMap to compare changes and return only the types that have changed', async () => {
test('uses the provided hashToVersionMap to compare changes and return new types and types that have changed', async () => {
const indexTypes = ['type1', 'type2', 'type4'];
const indexMeta: IndexMappingMeta = {
migrationMappingPropertyHashes: {
@ -56,14 +62,19 @@ describe('getUpdatedTypes', () => {
type4: '10.5.0', // new type, no need to pick it up
};
expect(
getUpdatedTypes({ indexTypes, indexMeta, latestMappingsVersions, hashToVersionMap })
).toEqual(['type2']);
const { newTypes, updatedTypes } = getNewAndUpdatedTypes({
indexTypes,
indexMeta,
latestMappingsVersions,
hashToVersionMap,
});
expect(newTypes).toEqual(['type4']);
expect(updatedTypes).toEqual(['type2']);
});
});
describe('when mappingVersions exist in indexMappings', () => {
test('compares the modelVersions and returns only the types that have changed', async () => {
test('compares the modelVersions and returns new types and types that have changed', async () => {
const indexTypes = ['type1', 'type2', 'type4'];
const indexMeta: IndexMappingMeta = {
@ -90,9 +101,14 @@ describe('getUpdatedTypes', () => {
// empty on purpose, not used as mappingVersions is present in indexMappings
};
expect(
getUpdatedTypes({ indexTypes, indexMeta, latestMappingsVersions, hashToVersionMap })
).toEqual(['type2']);
const { newTypes, updatedTypes } = getNewAndUpdatedTypes({
indexTypes,
indexMeta,
latestMappingsVersions,
hashToVersionMap,
});
expect(newTypes).toEqual(['type4']);
expect(updatedTypes).toEqual(['type2']);
});
});
});

View file

@ -33,43 +33,56 @@ export const getUpdatedRootFields = (indexMappings: IndexMapping): string[] => {
.map(([propertyName]) => propertyName);
};
/**
* Compares the current vs stored mappings' hashes or modelVersions.
* Returns a list with all the types that have been updated.
* @param indexMeta The meta information stored in the SO index
* @param knownTypes The list of SO types that belong to the index and are enabled
* @param latestMappingsVersions A map holding [type => version] with the latest versions where mappings have changed for each type
* @param hashToVersionMap A map holding information about [md5 => modelVersion] equivalence
* @returns the list of types that have been updated (in terms of their mappings)
*/
export const getUpdatedTypes = ({
indexMeta,
indexTypes,
latestMappingsVersions,
hashToVersionMap = {},
}: {
interface GetUpdatedTypesParams {
indexMeta?: IndexMappingMeta;
indexTypes: string[];
latestMappingsVersions: VirtualVersionMap;
hashToVersionMap?: Record<string, string>;
}): string[] => {
}
/**
* Compares the current vs stored mappings' hashes or modelVersions.
* Returns 2 lists: one with all the new types and one with the types that have been updated.
* @param indexMeta The meta information stored in the SO index
* @param knownTypes The list of SO types that belong to the index and are enabled
* @param latestMappingsVersions A map holding [type => version] with the latest versions where mappings have changed for each type
* @param hashToVersionMap A map holding information about [md5 => modelVersion] equivalence
* @returns the lists of new types and updated types
*/
export const getNewAndUpdatedTypes = ({
indexMeta,
indexTypes,
latestMappingsVersions,
hashToVersionMap = {},
}: GetUpdatedTypesParams) => {
if (!indexMeta || (!indexMeta.mappingVersions && !indexMeta.migrationMappingPropertyHashes)) {
// if we currently do NOT have meta information stored in the index
// we consider that all types have been updated
return indexTypes;
return { newTypes: [], updatedTypes: indexTypes };
}
// If something exists in stored, but is missing in current
// we don't care, as it could be a disabled plugin, etc
// and keeping stale stuff around is better than migrating unecessesarily.
return indexTypes.filter((type) =>
isTypeUpdated({
const newTypes: string[] = [];
const updatedTypes: string[] = [];
indexTypes.forEach((type) => {
const status = checkTypeStatus({
type,
mappingVersion: latestMappingsVersions[type],
indexMeta,
hashToVersionMap,
})
);
});
if (status === 'new') {
newTypes.push(type);
} else if (status === 'updated') {
updatedTypes.push(type);
}
});
return { newTypes, updatedTypes };
};
/**
@ -78,9 +91,9 @@ export const getUpdatedTypes = ({
* @param mappingVersion The most recent model version that includes mappings changes
* @param indexMeta The meta information stored in the SO index
* @param hashToVersionMap A map holding information about [md5 => modelVersion] equivalence
* @returns true if the mappings for the given type have changed since Kibana was last started
* @returns 'new' | 'updated' | 'unchanged' depending on whether the type has changed
*/
function isTypeUpdated({
function checkTypeStatus({
type,
mappingVersion,
indexMeta,
@ -90,7 +103,7 @@ function isTypeUpdated({
mappingVersion: string;
indexMeta: IndexMappingMeta;
hashToVersionMap: Record<string, string>;
}): boolean {
}): 'new' | 'updated' | 'unchanged' {
const latestMappingsVersion = Semver.parse(mappingVersion);
if (!latestMappingsVersion) {
throw new Error(
@ -104,26 +117,28 @@ function isTypeUpdated({
if (!indexVersion) {
// either a new type, and thus there's not need to update + pickup any docs
// or an old re-enabled type, which will be updated on OUTDATED_DOCUMENTS_TRANSFORM
return false;
return 'new';
}
// if the last version where mappings have changed is more recent than the one stored in the index
// it means that the type has been updated
return latestMappingsVersion.compare(indexVersion) === 1;
return latestMappingsVersion.compare(indexVersion) === 1 ? 'updated' : 'unchanged';
} else if (indexMeta.migrationMappingPropertyHashes) {
const latestHash = indexMeta.migrationMappingPropertyHashes?.[type];
if (!latestHash) {
// either a new type, and thus there's not need to update + pickup any docs
// or an old re-enabled type, which will be updated on OUTDATED_DOCUMENTS_TRANSFORM
return false;
return 'new';
}
const indexEquivalentVersion = hashToVersionMap[`${type}|${latestHash}`];
return !indexEquivalentVersion || latestMappingsVersion.compare(indexEquivalentVersion) === 1;
return !indexEquivalentVersion || latestMappingsVersion.compare(indexEquivalentVersion) === 1
? 'updated'
: 'unchanged';
}
// at this point, the mappings do not contain any meta informataion
// we consider the type has been updated, out of caution
return true;
return 'updated';
}

View file

@ -9,12 +9,14 @@
import type { IndexMapping } from '@kbn/core-saved-objects-base-server-internal';
import { getBaseMappings } from './build_active_mappings';
import { getUpdatedRootFields, getUpdatedTypes } from './compare_mappings';
import { getUpdatedRootFields, getNewAndUpdatedTypes } from './compare_mappings';
import { diffMappings } from './diff_mappings';
jest.mock('./compare_mappings');
const getUpdatedRootFieldsMock = getUpdatedRootFields as jest.MockedFn<typeof getUpdatedRootFields>;
const getUpdatedTypesMock = getUpdatedTypes as jest.MockedFn<typeof getUpdatedTypes>;
const getNewAndUpdatedTypesMock = getNewAndUpdatedTypes as jest.MockedFn<
typeof getNewAndUpdatedTypes
>;
const dummyMappings: IndexMapping = {
_meta: {
@ -56,7 +58,7 @@ const dummyHashToVersionMap = {
describe('diffMappings', () => {
beforeEach(() => {
getUpdatedRootFieldsMock.mockReset();
getUpdatedTypesMock.mockReset();
getNewAndUpdatedTypesMock.mockReset();
});
test('is different if dynamic is different', () => {
@ -114,14 +116,17 @@ describe('diffMappings', () => {
expect(getUpdatedRootFieldsMock).toHaveBeenCalledTimes(1);
expect(getUpdatedRootFieldsMock).toHaveBeenCalledWith(initialMappings);
expect(getUpdatedTypesMock).not.toHaveBeenCalled();
expect(getNewAndUpdatedTypesMock).not.toHaveBeenCalled();
});
});
describe('if some types have changed', () => {
describe('if there are new or updated types', () => {
test('returns a changed type', () => {
getUpdatedRootFieldsMock.mockReturnValueOnce([]);
getUpdatedTypesMock.mockReturnValueOnce(['foo', 'bar']);
getNewAndUpdatedTypesMock.mockReturnValueOnce({
newTypes: ['baz'],
updatedTypes: ['foo'],
});
expect(
diffMappings({
@ -137,8 +142,8 @@ describe('diffMappings', () => {
expect(getUpdatedRootFieldsMock).toHaveBeenCalledTimes(1);
expect(getUpdatedRootFieldsMock).toHaveBeenCalledWith(initialMappings);
expect(getUpdatedTypesMock).toHaveBeenCalledTimes(1);
expect(getUpdatedTypesMock).toHaveBeenCalledWith({
expect(getNewAndUpdatedTypesMock).toHaveBeenCalledTimes(1);
expect(getNewAndUpdatedTypesMock).toHaveBeenCalledWith({
indexTypes: ['foo', 'bar', 'baz'],
indexMeta: initialMappings._meta,
latestMappingsVersions: {
@ -152,7 +157,10 @@ describe('diffMappings', () => {
describe('if no root field or types have changed', () => {
test('returns undefined', () => {
getUpdatedRootFieldsMock.mockReturnValueOnce([]);
getUpdatedTypesMock.mockReturnValueOnce([]);
getNewAndUpdatedTypesMock.mockReturnValueOnce({
newTypes: [],
updatedTypes: [],
});
expect(
diffMappings({

View file

@ -8,7 +8,7 @@
*/
import type { IndexMapping, VirtualVersionMap } from '@kbn/core-saved-objects-base-server-internal';
import { getUpdatedRootFields, getUpdatedTypes } from './compare_mappings';
import { getNewAndUpdatedTypes, getUpdatedRootFields } from './compare_mappings';
/**
* Diffs the stored vs app mappings.
@ -56,8 +56,9 @@ export function diffMappings({
}
/**
* Finds a property that has changed its schema with respect to the mappings stored in the SO index
* It can either be a root field or a SO type
* Finds a property (either a root field or a SO type) that either:
* - is new (did not exist in the current mappings)
* - has changed its schema with respect to the mappings stored in the SO index
* @returns the name of the property (if any)
*/
function findChangedProp({
@ -76,7 +77,7 @@ function findChangedProp({
return updatedFields[0];
}
const updatedTypes = getUpdatedTypes({
const { newTypes, updatedTypes } = getNewAndUpdatedTypes({
indexMeta: indexMappings._meta,
indexTypes,
latestMappingsVersions,
@ -84,6 +85,8 @@ function findChangedProp({
});
if (updatedTypes.length) {
return updatedTypes[0];
} else if (newTypes.length) {
return newTypes[0];
}
return undefined;

View file

@ -2689,6 +2689,18 @@ describe('migrations v2 model', () => {
});
});
it('CHECK_TARGET_MAPPINGS -> UPDATE_TARGET_MAPPINGS_META if ONLY new SO types have been added', () => {
const res: ResponseType<'CHECK_TARGET_MAPPINGS'> = Either.left({
type: 'types_added' as const,
updatedFields: [],
newTypes: ['newFeatureType'],
});
const newState = model(checkTargetTypesMappingsState, res) as UpdateTargetMappingsMeta;
expect(newState.controlState).toEqual('UPDATE_TARGET_MAPPINGS_META');
expect(newState.retryCount).toEqual(0);
expect(newState.retryDelay).toEqual(0);
});
it('CHECK_TARGET_MAPPINGS -> CHECK_VERSION_INDEX_READY_ACTIONS if types match (there might be additions in core fields)', () => {
const res: ResponseType<'CHECK_TARGET_MAPPINGS'> = Either.right({
type: 'types_match' as const,

View file

@ -1522,6 +1522,12 @@ export const model = (currentState: State, resW: ResponseType<AllActionStates>):
},
],
};
} else if (isTypeof(left, 'types_added')) {
// compatible migration: ONLY new SO types have been introduced, skip directly to UPDATE_TARGET_MAPPINGS_META
return {
...stateP,
controlState: 'UPDATE_TARGET_MAPPINGS_META',
};
} else {
throwBadResponse(stateP, res as never);
}

View file

@ -67,34 +67,48 @@ describe('v2 migration', () => {
migrationResults = await upToDateKit.runMigrations();
});
it('updates the index mappings to account for new SO types', async () => {
const res = await upToDateKit.client.indices.getMapping({ index: defaultKibanaIndex });
const mappings = res[`${defaultKibanaIndex}_${currentVersion}_001`].mappings;
expect(mappings._meta?.indexTypesMap[defaultKibanaIndex]).toContain('recent');
expect(mappings.properties?.recent).toEqual({
properties: {
name: {
type: 'keyword',
},
},
});
});
it('skips UPDATE_TARGET_MAPPINGS_PROPERTIES if there are no changes in the mappings', async () => {
const logs = await readLog(logFilePath);
expect(logs).not.toMatch('CREATE_NEW_TARGET');
// defaultKibana index has a new SO type ('recent'), thus we must update the _meta properties
expect(logs).toMatch(
`[${defaultKibanaIndex}] CHECK_TARGET_MAPPINGS -> CHECK_VERSION_INDEX_READY_ACTIONS`
`[${defaultKibanaIndex}] CHECK_TARGET_MAPPINGS -> UPDATE_TARGET_MAPPINGS_META.`
);
expect(logs).toMatch(
`[${defaultKibanaTaskIndex}] CHECK_TARGET_MAPPINGS -> CHECK_VERSION_INDEX_READY_ACTIONS`
);
// no updated types, so no pickup
expect(logs).not.toMatch('UPDATE_TARGET_MAPPINGS_PROPERTIES');
expect(logs).not.toMatch('UPDATE_TARGET_MAPPINGS_PROPERTIES_WAIT_FOR_TASK');
expect(logs).not.toMatch('UPDATE_TARGET_MAPPINGS_META');
});
it(`returns a 'patched' status for each SO index`, () => {
// omit elapsedMs as it varies in each execution
expect(migrationResults.map((result) => omit(result, 'elapsedMs'))).toMatchInlineSnapshot(`
Array [
Object {
"destIndex": ".kibana_migrator_${currentVersion}_001",
"status": "patched",
},
Object {
"destIndex": ".kibana_migrator_tasks_${currentVersion}_001",
"status": "patched",
},
]
`);
expect(migrationResults.map((result) => omit(result, 'elapsedMs'))).toEqual([
{
destIndex: `${defaultKibanaIndex}_${currentVersion}_001`,
status: 'patched',
},
{
destIndex: `${defaultKibanaTaskIndex}_${currentVersion}_001`,
status: 'patched',
},
]);
});
it('each migrator takes less than 10 seconds', () => {
@ -318,21 +332,18 @@ describe('v2 migration', () => {
it('returns a migrated status for each SO index', () => {
// omit elapsedMs as it varies in each execution
expect(migrationResults.map((result) => omit(result, 'elapsedMs')))
.toMatchInlineSnapshot(`
Array [
Object {
"destIndex": ".kibana_migrator_${nextMinor}_001",
"sourceIndex": ".kibana_migrator_${currentVersion}_001",
"status": "migrated",
},
Object {
"destIndex": ".kibana_migrator_tasks_${currentVersion}_001",
"sourceIndex": ".kibana_migrator_tasks_${currentVersion}_001",
"status": "migrated",
},
]
`);
expect(migrationResults.map((result) => omit(result, 'elapsedMs'))).toEqual([
{
destIndex: `${defaultKibanaIndex}_${nextMinor}_001`,
sourceIndex: `${defaultKibanaIndex}_${currentVersion}_001`,
status: 'migrated',
},
{
destIndex: `${defaultKibanaTaskIndex}_${currentVersion}_001`,
sourceIndex: `${defaultKibanaTaskIndex}_${currentVersion}_001`,
status: 'migrated',
},
]);
});
it('each migrator takes less than 60 seconds', () => {

View file

@ -139,7 +139,7 @@ describe('multiple Kibana nodes performing a reindexing migration', () => {
const typesMap =
indicesInfo[`${defaultKibanaIndex}_${nextMinor}_001`].mappings?._meta?.indexTypesMap;
expect(typesMap[defaultKibanaIndex]).toEqual(['complex', 'server']); // 'deprecated' no longer present
expect(typesMap[defaultKibanaIndex]).toEqual(['complex', 'recent', 'server']); // 'deprecated' no longer present
expect(typesMap[kibanaSplitIndex]).toEqual(['basic', 'task']);
}
@ -239,11 +239,11 @@ describe('multiple Kibana nodes performing a reindexing migration', () => {
)
).toEqual([
{
destIndex: `.kibana_migrator_${nextMinor}_001`,
destIndex: `${defaultKibanaIndex}_${nextMinor}_001`,
status: 'patched',
},
{
destIndex: `.kibana_migrator_split_${nextMinor}_001`,
destIndex: `${kibanaSplitIndex}_${nextMinor}_001`,
status: 'patched',
},
]);

View file

@ -81,8 +81,14 @@ export const baselineTypes: Array<SavedObjectsType<any>> = [
},
];
export const getUpToDateBaselineTypes = (filterDeprecated: boolean) =>
baselineTypes.filter((type) => !filterDeprecated || type.name !== 'deprecated');
export const getUpToDateBaselineTypes = (filterDeprecated: boolean) => [
...baselineTypes.filter((type) => !filterDeprecated || type.name !== 'deprecated'),
// we add a new SO type
{
...defaultType,
name: 'recent',
},
];
export const getCompatibleBaselineTypes = (filterDeprecated: boolean) =>
getUpToDateBaselineTypes(filterDeprecated).map<SavedObjectsType>((type) => {