Skip to content

Commit 7796bc1

Browse files
committed
Add minimum version for saved object namespace type conversion
1 parent bc3b7e0 commit 7796bc1

3 files changed

Lines changed: 42 additions & 3 deletions

File tree

src/core/server/saved_objects/migrations/core/document_migrator.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ describe('DocumentMigrator', () => {
5555
return {
5656
kibanaVersion,
5757
typeRegistry: createRegistry(),
58+
minimumConvertVersion: '0.0.0', // no minimum version unless we specify it for a test case
5859
log: mockLogger,
5960
};
6061
}
@@ -129,6 +130,7 @@ describe('DocumentMigrator', () => {
129130
name: 'foo',
130131
convertToMultiNamespaceTypeVersion: 'bar',
131132
}),
133+
minimumConvertVersion: '0.0.0',
132134
log: mockLogger,
133135
};
134136
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
@@ -144,13 +146,30 @@ describe('DocumentMigrator', () => {
144146
convertToMultiNamespaceTypeVersion: 'bar',
145147
namespaceType: 'multiple',
146148
}),
149+
minimumConvertVersion: '0.0.0',
147150
log: mockLogger,
148151
};
149152
expect(() => new DocumentMigrator(invalidDefinition)).toThrow(
150153
`Invalid convertToMultiNamespaceTypeVersion for type foo. Expected value to be a semver, but got 'bar'.`
151154
);
152155
});
153156

157+
it('validates convertToMultiNamespaceTypeVersion is not less than the minimum allowed version', () => {
158+
const invalidDefinition = {
159+
kibanaVersion: '3.2.3',
160+
typeRegistry: createRegistry({
161+
name: 'foo',
162+
convertToMultiNamespaceTypeVersion: '3.2.4',
163+
namespaceType: 'multiple',
164+
}),
165+
// not using a minimumConvertVersion parameter, the default is 8.0.0
166+
log: mockLogger,
167+
};
168+
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(
169+
`Invalid convertToMultiNamespaceTypeVersion for type foo. Value '3.2.4' cannot be less than '8.0.0'.`
170+
);
171+
});
172+
154173
it('validates convertToMultiNamespaceTypeVersion is not greater than the current Kibana version', () => {
155174
const invalidDefinition = {
156175
kibanaVersion: '3.2.3',
@@ -159,6 +178,7 @@ describe('DocumentMigrator', () => {
159178
convertToMultiNamespaceTypeVersion: '3.2.4',
160179
namespaceType: 'multiple',
161180
}),
181+
minimumConvertVersion: '0.0.0',
162182
log: mockLogger,
163183
};
164184
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(
@@ -174,6 +194,7 @@ describe('DocumentMigrator', () => {
174194
convertToMultiNamespaceTypeVersion: '3.1.1',
175195
namespaceType: 'multiple',
176196
}),
197+
minimumConvertVersion: '0.0.0',
177198
log: mockLogger,
178199
};
179200
expect(() => new DocumentMigrator(invalidDefinition)).toThrowError(

src/core/server/saved_objects/migrations/core/document_migrator.ts

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@ import { SavedObjectMigrationFn } from '../types';
7878
import { DEFAULT_NAMESPACE_STRING } from '../../service/lib/utils';
7979
import { LegacyUrlAlias, LEGACY_URL_ALIAS_TYPE } from '../../object_types';
8080

81+
const DEFAULT_MINIMUM_CONVERT_VERSION = '8.0.0';
82+
8183
export type MigrateFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc;
8284
export type MigrateAndConvertFn = (doc: SavedObjectUnsanitizedDoc) => SavedObjectUnsanitizedDoc[];
8385

@@ -105,6 +107,7 @@ interface TransformOptions {
105107
interface DocumentMigratorOptions {
106108
kibanaVersion: string;
107109
typeRegistry: ISavedObjectTypeRegistry;
110+
minimumConvertVersion?: string;
108111
log: Logger;
109112
}
110113

@@ -159,11 +162,17 @@ export class DocumentMigrator implements VersionedTransformer {
159162
* @param {DocumentMigratorOptions} opts
160163
* @prop {string} kibanaVersion - The current version of Kibana
161164
* @prop {SavedObjectTypeRegistry} typeRegistry - The type registry to get type migrations from
165+
* @prop {string} minimumConvertVersion - The minimum version of Kibana in which documents can be converted to multi-namespace types
162166
* @prop {Logger} log - The migration logger
163167
* @memberof DocumentMigrator
164168
*/
165-
constructor({ typeRegistry, kibanaVersion, log }: DocumentMigratorOptions) {
166-
validateMigrationDefinition(typeRegistry, kibanaVersion);
169+
constructor({
170+
typeRegistry,
171+
kibanaVersion,
172+
minimumConvertVersion = DEFAULT_MINIMUM_CONVERT_VERSION,
173+
log,
174+
}: DocumentMigratorOptions) {
175+
validateMigrationDefinition(typeRegistry, kibanaVersion, minimumConvertVersion);
167176

168177
this.migrations = buildActiveMigrations(typeRegistry, log);
169178
this.transformDoc = buildDocumentTransform({
@@ -231,7 +240,11 @@ export class DocumentMigrator implements VersionedTransformer {
231240
* language. So, this is just to provide a little developer-friendly error messaging. Joi was
232241
* giving weird errors, so we're just doing manual validation.
233242
*/
234-
function validateMigrationDefinition(registry: ISavedObjectTypeRegistry, kibanaVersion: string) {
243+
function validateMigrationDefinition(
244+
registry: ISavedObjectTypeRegistry,
245+
kibanaVersion: string,
246+
minimumConvertVersion: string
247+
) {
235248
function assertObject(obj: any, prefix: string) {
236249
if (!obj || typeof obj !== 'object') {
237250
throw new Error(`${prefix} Got ${obj}.`);
@@ -270,6 +283,10 @@ function validateMigrationDefinition(registry: ISavedObjectTypeRegistry, kibanaV
270283
throw new Error(
271284
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Expected value to be a semver, but got '${convertToMultiNamespaceTypeVersion}'.`
272285
);
286+
} else if (Semver.lt(convertToMultiNamespaceTypeVersion, minimumConvertVersion)) {
287+
throw new Error(
288+
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Value '${convertToMultiNamespaceTypeVersion}' cannot be less than '${minimumConvertVersion}'.`
289+
);
273290
} else if (Semver.gt(convertToMultiNamespaceTypeVersion, kibanaVersion)) {
274291
throw new Error(
275292
`Invalid convertToMultiNamespaceTypeVersion for type ${type}. Value '${convertToMultiNamespaceTypeVersion}' cannot be greater than the current Kibana version '${kibanaVersion}'.`

test/api_integration/apis/saved_objects/migrations.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,7 @@ async function migrateIndex({
641641
const documentMigrator = new DocumentMigrator({
642642
kibanaVersion: KIBANA_VERSION,
643643
typeRegistry,
644+
minimumConvertVersion: '0.0.0', // bypass the restriction of a minimum version of 8.0.0 for these integration tests
644645
log: getLogMock(),
645646
});
646647

0 commit comments

Comments
 (0)