Skip to content

Commit

Permalink
Add minimum version for saved object namespace type conversion
Browse files Browse the repository at this point in the history
  • Loading branch information
jportner committed Jan 19, 2021
1 parent bc3b7e0 commit 7796bc1
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ describe('DocumentMigrator', () => {
return {
kibanaVersion,
typeRegistry: createRegistry(),
minimumConvertVersion: '0.0.0', // no minimum version unless we specify it for a test case
log: mockLogger,
};
}
Expand Down Expand Up @@ -129,6 +130,7 @@ describe('DocumentMigrator', () => {
name: 'foo',
convertToMultiNamespaceTypeVersion: 'bar',
}),
minimumConvertVersion: '0.0.0',
log: mockLogger,
};
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
Expand All @@ -144,13 +146,30 @@ describe('DocumentMigrator', () => {
convertToMultiNamespaceTypeVersion: 'bar',
namespaceType: 'multiple',
}),
minimumConvertVersion: '0.0.0',
log: mockLogger,
};
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
`Invalid convertToMultiNamespaceTypeVersion for type foo. Expected value to be a semver, but got 'bar'.`
);
});

it('validates convertToMultiNamespaceTypeVersion is not less than the minimum allowed version', () => {
const invalidDefinition = {
kibanaVersion: '3.2.3',
typeRegistry: createRegistry({
name: 'foo',
convertToMultiNamespaceTypeVersion: '3.2.4',
namespaceType: 'multiple',
}),
// not using a minimumConvertVersion parameter, the default is 8.0.0
log: mockLogger,
};
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(
`Invalid convertToMultiNamespaceTypeVersion for type foo. Value '3.2.4' cannot be less than '8.0.0'.`
);
});

it('validates convertToMultiNamespaceTypeVersion is not greater than the current Kibana version', () => {
const invalidDefinition = {
kibanaVersion: '3.2.3',
Expand All @@ -159,6 +178,7 @@ describe('DocumentMigrator', () => {
convertToMultiNamespaceTypeVersion: '3.2.4',
namespaceType: 'multiple',
}),
minimumConvertVersion: '0.0.0',
log: mockLogger,
};
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(
Expand All @@ -174,6 +194,7 @@ describe('DocumentMigrator', () => {
convertToMultiNamespaceTypeVersion: '3.1.1',
namespaceType: 'multiple',
}),
minimumConvertVersion: '0.0.0',
log: mockLogger,
};
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(
Expand Down
23 changes: 20 additions & 3 deletions src/core/server/saved_objects/migrations/core/document_migrator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ import { SavedObjectMigrationFn } from '../types';
import { DEFAULT_NAMESPACE_STRING } from '../../service/lib/utils';
import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types';

const DEFAULT_MINIMUM_CONVERT_VERSION = '8.0.0';

export type MigrateFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc;
export type MigrateAndConvertFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc[];

Expand Down Expand Up @@ -105,6 +107,7 @@ interface TransformOptions {
interface DocumentMigratorOptions {
kibanaVersion: string;
typeRegistry: ISavedObjectTypeRegistry;
minimumConvertVersion?: string;
log: Logger;
}

Expand Down Expand Up @@ -159,11 +162,17 @@ 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 {Logger} log - The migration logger
* @memberof DocumentMigrator
*/
constructor({ typeRegistry, kibanaVersion, log }: DocumentMigratorOptions) {
validateMigrationDefinition(typeRegistry, kibanaVersion);
constructor({
typeRegistry,
kibanaVersion,
minimumConvertVersion = DEFAULT_MINIMUM_CONVERT_VERSION,
log,
}: DocumentMigratorOptions) {
validateMigrationDefinition(typeRegistry, kibanaVersion, minimumConvertVersion);

this.migrations = buildActiveMigrations(typeRegistry, log);
this.transformDoc = buildDocumentTransform({
Expand Down Expand Up @@ -231,7 +240,11 @@ export class DocumentMigrator implements VersionedTransformer {
* language. So, this is just to provide a little developer-friendly error messaging. Joi was
* giving weird errors, so we're just doing manual validation.
*/
function validateMigrationDefinition(registry: ISavedObjectTypeRegistry, kibanaVersion: string) {
function validateMigrationDefinition(
registry: ISavedObjectTypeRegistry,
kibanaVersion: string,
minimumConvertVersion: string
) {
function assertObject(obj: any, prefix: string) {
if (!obj || typeof obj !== 'object') {
throw new Error(`${prefix} Got ${obj}.`);
Expand Down Expand Up @@ -270,6 +283,10 @@ function validateMigrationDefinition(registry: ISavedObjectTypeRegistry, kibanaV
throw new Error(
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Expected value to be a semver, but got '${convertToMultiNamespaceTypeVersion}'.`
);
} else if (Semver.lt(convertToMultiNamespaceTypeVersion, minimumConvertVersion)) {
throw new Error(
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Value '${convertToMultiNamespaceTypeVersion}' cannot be less than '${minimumConvertVersion}'.`
);
} else if (Semver.gt(convertToMultiNamespaceTypeVersion, kibanaVersion)) {
throw new Error(
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Value '${convertToMultiNamespaceTypeVersion}' cannot be greater than the current Kibana version '${kibanaVersion}'.`
Expand Down
1 change: 1 addition & 0 deletions test/api_integration/apis/saved_objects/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -641,6 +641,7 @@ async function migrateIndex({
const documentMigrator = new DocumentMigrator({
kibanaVersion: KIBANA_VERSION,
typeRegistry,
minimumConvertVersion: '0.0.0', // bypass the restriction of a minimum version of 8.0.0 for these integration tests
log: getLogMock(),
});

Expand Down

0 comments on commit 7796bc1

Please sign in to comment.