mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 09:19:04 -04:00
Prevent future convertToMultiNamespaceType migrations (#147369)
Addresses https://github.com/elastic/kibana/issues/147344
This commit is contained in:
parent
b61066d82a
commit
57dad8fc07
7 changed files with 25 additions and 23 deletions
|
@ -4,6 +4,9 @@
|
|||
This guide describes the "Sharing saved objects" effort, and the breaking changes that plugin developers need to be aware of for the planned
|
||||
8.0 release of {kib}. It also describes how developers can take advantage of this feature.
|
||||
|
||||
From 8.7.0, as a step towards _zero downtime upgrades_, plugins are no longer allowed to update existing single space saved object types to become shareable.
|
||||
Note that new saved object types can still be defined as `'multiple'` or `'multiple-isolated'`.
|
||||
|
||||
[[sharing-saved-objects-overview]]
|
||||
=== Overview
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ export const expectErrorInvalidType = (obj: TypeIdTuple, overrides?: Record<stri
|
|||
expectErrorResult(obj, createUnsupportedTypeErrorPayload(obj.type), overrides);
|
||||
|
||||
export const KIBANA_VERSION = '2.0.0';
|
||||
export const ALLOWED_CONVERT_VERSION = '8.0.0';
|
||||
export const CUSTOM_INDEX_TYPE = 'customIndex';
|
||||
/** This type has namespaceType: 'agnostic'. */
|
||||
export const NAMESPACE_AGNOSTIC_TYPE = 'globalType';
|
||||
|
@ -372,6 +373,7 @@ export const createDocumentMigrator = (registry: SavedObjectTypeRegistry) => {
|
|||
return new DocumentMigrator({
|
||||
typeRegistry: registry,
|
||||
kibanaVersion: KIBANA_VERSION,
|
||||
convertVersion: ALLOWED_CONVERT_VERSION,
|
||||
log: loggerMock.create(),
|
||||
});
|
||||
};
|
||||
|
|
|
@ -55,7 +55,6 @@ describe('DocumentMigrator', () => {
|
|||
return {
|
||||
kibanaVersion,
|
||||
typeRegistry: createRegistry(),
|
||||
minimumConvertVersion: '0.0.0', // no minimum version unless we specify it for a test case
|
||||
log: mockLogger,
|
||||
};
|
||||
}
|
||||
|
@ -63,6 +62,7 @@ describe('DocumentMigrator', () => {
|
|||
describe('validation', () => {
|
||||
const createDefinition = (migrations: any) => ({
|
||||
kibanaVersion: '3.2.3',
|
||||
convertVersion: '8.0.0',
|
||||
typeRegistry: createRegistry({
|
||||
name: 'foo',
|
||||
migrations: migrations as any,
|
||||
|
@ -163,7 +163,6 @@ describe('DocumentMigrator', () => {
|
|||
name: 'foo',
|
||||
convertToMultiNamespaceTypeVersion: 'bar',
|
||||
}),
|
||||
minimumConvertVersion: '0.0.0',
|
||||
log: mockLogger,
|
||||
};
|
||||
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
|
||||
|
@ -179,7 +178,6 @@ describe('DocumentMigrator', () => {
|
|||
convertToMultiNamespaceTypeVersion: 'bar',
|
||||
namespaceType: 'multiple',
|
||||
}),
|
||||
minimumConvertVersion: '0.0.0',
|
||||
log: mockLogger,
|
||||
};
|
||||
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
|
||||
|
@ -187,7 +185,7 @@ describe('DocumentMigrator', () => {
|
|||
);
|
||||
});
|
||||
|
||||
it('validates convertToMultiNamespaceTypeVersion is not less than the minimum allowed version', () => {
|
||||
it('validates convertToMultiNamespaceTypeVersion matches the convertVersion, if specified', () => {
|
||||
const invalidDefinition = {
|
||||
kibanaVersion: '3.2.3',
|
||||
typeRegistry: createRegistry({
|
||||
|
@ -195,11 +193,11 @@ describe('DocumentMigrator', () => {
|
|||
convertToMultiNamespaceTypeVersion: '3.2.4',
|
||||
namespaceType: 'multiple',
|
||||
}),
|
||||
// not using a minimumConvertVersion parameter, the default is 8.0.0
|
||||
convertVersion: '3.2.3',
|
||||
log: mockLogger,
|
||||
};
|
||||
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(
|
||||
`Invalid convertToMultiNamespaceTypeVersion for type foo. Value '3.2.4' cannot be less than '8.0.0'.`
|
||||
`Invalid convertToMultiNamespaceTypeVersion for type foo. Value '3.2.4' cannot be any other than '3.2.3'.`
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -211,7 +209,6 @@ describe('DocumentMigrator', () => {
|
|||
convertToMultiNamespaceTypeVersion: '3.2.4',
|
||||
namespaceType: 'multiple',
|
||||
}),
|
||||
minimumConvertVersion: '0.0.0',
|
||||
log: mockLogger,
|
||||
};
|
||||
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(
|
||||
|
@ -227,7 +224,6 @@ describe('DocumentMigrator', () => {
|
|||
convertToMultiNamespaceTypeVersion: '3.1.1',
|
||||
namespaceType: 'multiple',
|
||||
}),
|
||||
minimumConvertVersion: '0.0.0',
|
||||
log: mockLogger,
|
||||
};
|
||||
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(
|
||||
|
|
|
@ -66,8 +66,6 @@ import {
|
|||
import { MigrationLogger } from './migration_logger';
|
||||
import { TransformSavedObjectDocumentError } from '.';
|
||||
|
||||
const DEFAULT_MINIMUM_CONVERT_VERSION = '8.0.0';
|
||||
|
||||
export type MigrateFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc;
|
||||
export type MigrateAndConvertFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc[];
|
||||
|
||||
|
@ -95,7 +93,7 @@ interface TransformOptions {
|
|||
interface DocumentMigratorOptions {
|
||||
kibanaVersion: string;
|
||||
typeRegistry: ISavedObjectTypeRegistry;
|
||||
minimumConvertVersion?: string;
|
||||
convertVersion?: string;
|
||||
log: Logger;
|
||||
}
|
||||
|
||||
|
@ -142,7 +140,7 @@ export interface VersionedTransformer {
|
|||
* A concrete implementation of the VersionedTransformer interface.
|
||||
*/
|
||||
export class DocumentMigrator implements VersionedTransformer {
|
||||
private documentMigratorOptions: Omit<DocumentMigratorOptions, 'minimumConvertVersion'>;
|
||||
private documentMigratorOptions: Omit<DocumentMigratorOptions, 'convertVersion'>;
|
||||
private migrations?: ActiveMigrations;
|
||||
private transformDoc?: ApplyTransformsFn;
|
||||
|
||||
|
@ -152,17 +150,12 @@ export class DocumentMigrator implements VersionedTransformer {
|
|||
* @param {DocumentMigratorOptions} opts
|
||||
* @prop {string} kibanaVersion - The current version of Kibana
|
||||
* @prop {SavedObjectTypeRegistry} typeRegistry - The type registry to get type migrations from
|
||||
* @prop {string} minimumConvertVersion - The minimum version of Kibana in which documents can be converted to multi-namespace types
|
||||
* @prop {string} convertVersion - The version of Kibana in which documents can be converted to multi-namespace types
|
||||
* @prop {Logger} log - The migration logger
|
||||
* @memberof DocumentMigrator
|
||||
*/
|
||||
constructor({
|
||||
typeRegistry,
|
||||
kibanaVersion,
|
||||
minimumConvertVersion = DEFAULT_MINIMUM_CONVERT_VERSION,
|
||||
log,
|
||||
}: DocumentMigratorOptions) {
|
||||
validateMigrationDefinition(typeRegistry, kibanaVersion, minimumConvertVersion);
|
||||
constructor({ typeRegistry, kibanaVersion, convertVersion, log }: DocumentMigratorOptions) {
|
||||
validateMigrationDefinition(typeRegistry, kibanaVersion, convertVersion);
|
||||
|
||||
this.documentMigratorOptions = { typeRegistry, kibanaVersion, log };
|
||||
}
|
||||
|
@ -300,7 +293,7 @@ function validateMigrationsMapObject(
|
|||
function validateMigrationDefinition(
|
||||
registry: ISavedObjectTypeRegistry,
|
||||
kibanaVersion: string,
|
||||
minimumConvertVersion: string
|
||||
convertVersion?: string
|
||||
) {
|
||||
function assertObjectOrFunction(entity: any, prefix: string) {
|
||||
if (!entity || (typeof entity !== 'function' && typeof entity !== 'object')) {
|
||||
|
@ -321,9 +314,9 @@ function validateMigrationDefinition(
|
|||
throw new Error(
|
||||
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Expected value to be a semver, but got '${convertToMultiNamespaceTypeVersion}'.`
|
||||
);
|
||||
} else if (Semver.lt(convertToMultiNamespaceTypeVersion, minimumConvertVersion)) {
|
||||
} else if (convertVersion && Semver.neq(convertToMultiNamespaceTypeVersion, convertVersion)) {
|
||||
throw new Error(
|
||||
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Value '${convertToMultiNamespaceTypeVersion}' cannot be less than '${minimumConvertVersion}'.`
|
||||
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Value '${convertToMultiNamespaceTypeVersion}' cannot be any other than '${convertVersion}'.`
|
||||
);
|
||||
} else if (Semver.gt(convertToMultiNamespaceTypeVersion, kibanaVersion)) {
|
||||
throw new Error(
|
||||
|
@ -345,6 +338,7 @@ function validateMigrationDefinition(
|
|||
);
|
||||
}
|
||||
if (convertToMultiNamespaceTypeVersion) {
|
||||
// CHECKPOINT 1
|
||||
assertValidConvertToMultiNamespaceType(
|
||||
namespaceType,
|
||||
convertToMultiNamespaceTypeVersion,
|
||||
|
|
|
@ -37,6 +37,10 @@ import { createIndexMap } from './core/build_index_map';
|
|||
import { runResilientMigrator } from './run_resilient_migrator';
|
||||
import { migrateRawDocsSafely } from './core/migrate_raw_docs';
|
||||
|
||||
// ensure plugins don't try to convert SO namespaceTypes after 8.0.0
|
||||
// see https://github.com/elastic/kibana/issues/147344
|
||||
const ALLOWED_CONVERT_VERSION = '8.0.0';
|
||||
|
||||
export interface KibanaMigratorOptions {
|
||||
client: ElasticsearchClient;
|
||||
typeRegistry: ISavedObjectTypeRegistry;
|
||||
|
@ -92,6 +96,7 @@ export class KibanaMigrator implements IKibanaMigrator {
|
|||
this.kibanaVersion = kibanaVersion;
|
||||
this.documentMigrator = new DocumentMigrator({
|
||||
kibanaVersion: this.kibanaVersion,
|
||||
convertVersion: ALLOWED_CONVERT_VERSION,
|
||||
typeRegistry,
|
||||
log: this.log,
|
||||
});
|
||||
|
|
|
@ -76,6 +76,7 @@ export interface SavedObjectMigrationContext {
|
|||
readonly migrationVersion: string;
|
||||
/**
|
||||
* The version in which this object type is being converted to a multi-namespace type
|
||||
* @deprecated Converting to multi-namespace clashes with the ZDT requirement for serverless
|
||||
*/
|
||||
readonly convertToMultiNamespaceTypeVersion?: string;
|
||||
/**
|
||||
|
|
|
@ -113,6 +113,7 @@ export interface SavedObjectsType<Attributes = any> {
|
|||
* ```
|
||||
*
|
||||
* Note: migration function(s) can be optionally specified for any of these versions and will not interfere with the conversion process.
|
||||
* @deprecated Converting to multi-namespace clashes with the ZDT requirement for serverless
|
||||
*/
|
||||
convertToMultiNamespaceTypeVersion?: string;
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue