Skip to content

Commit

Permalink
added migration via EOS plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
gmmorris committed Jun 17, 2020
1 parent 0c34bd7 commit 6ded0a8
Show file tree
Hide file tree
Showing 17 changed files with 1,350 additions and 44 deletions.
1 change: 1 addition & 0 deletions src/core/server/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export { httpServiceMock } from './http/http_service.mock';
export { loggingServiceMock } from './logging/logging_service.mock';
export { savedObjectsRepositoryMock } from './saved_objects/service/lib/repository.mock';
export { savedObjectsServiceMock } from './saved_objects/saved_objects_service.mock';
export { migrationMocks } from './saved_objects/migrations/mocks';
export { typeRegistryMock as savedObjectsTypeRegistryMock } from './saved_objects/saved_objects_type_registry.mock';
export { uiSettingsServiceMock } from './ui_settings/ui_settings_service.mock';
export { metricsServiceMock } from './metrics/metrics_service.mock';
Expand Down
2 changes: 1 addition & 1 deletion x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@
"@elastic/eui": "24.1.0",
"@elastic/filesaver": "1.1.2",
"@elastic/maki": "6.3.0",
"@elastic/node-crypto": "1.1.1",
"@elastic/node-crypto": "1.2.1",
"@elastic/numeral": "^2.5.0",
"@kbn/babel-preset": "1.0.0",
"@kbn/config-schema": "1.0.0",
Expand Down
22 changes: 13 additions & 9 deletions x-pack/plugins/alerts/server/saved_objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,21 +6,14 @@

import { SavedObjectsServiceSetup } from 'kibana/server';
import mappings from './mappings.json';
import { getMigrations } from './migrations';
import { EncryptedSavedObjectsPluginSetup } from '../../../encrypted_saved_objects/server';

export function setupSavedObjects(
savedObjects: SavedObjectsServiceSetup,
encryptedSavedObjects: EncryptedSavedObjectsPluginSetup
) {
savedObjects.registerType({
name: 'alert',
hidden: true,
namespaceType: 'single',
mappings: mappings.alert,
});

// Encrypted attributes
encryptedSavedObjects.registerType({
const encryptedType = {
type: 'alert',
attributesToEncrypt: new Set(['apiKey']),
attributesToExcludeFromAAD: new Set([
Expand All @@ -29,5 +22,16 @@ export function setupSavedObjects(
'mutedInstanceIds',
'updatedBy',
]),
};

// Encrypted attributes
encryptedSavedObjects.registerType(encryptedType);

savedObjects.registerType({
name: 'alert',
hidden: true,
namespaceType: 'single',
migrations: getMigrations(encryptedSavedObjects, encryptedType),
mappings: mappings.alert,
});
}
114 changes: 114 additions & 0 deletions x-pack/plugins/alerts/server/saved_objects/migrations.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import uuid from 'uuid';
import { getMigrations } from './migrations';
import { RawAlert } from '../types';
import { SavedObjectUnsanitizedDoc } from 'kibana/server';
import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/server/mocks';
import { migrationMocks } from 'src/core/server/mocks';

const { log } = migrationMocks.createContext();
const encryptedSavedObjectsSetup = encryptedSavedObjectsMock.createSetup();

const encryptedType = {
type: 'alert',
attributesToEncrypt: new Set(['apiKey']),
attributesToExcludeFromAAD: new Set([
'scheduledTaskId',
'muteAll',
'mutedInstanceIds',
'updatedBy',
]),
};

describe('7.9.0', () => {
beforeEach(() => {
jest.resetAllMocks();
encryptedSavedObjectsSetup.createMigration.mockImplementation(
(shouldMigrateWhenPredicate, migration) => migration
);
});

test('changes nothing on alerts by other plugins', () => {
const migration790 = getMigrations(encryptedSavedObjectsSetup, encryptedType)['7.9.0'];
const alert = getMockData({});
expect(migration790(alert, { log })).toMatchObject(alert);

expect(encryptedSavedObjectsSetup.createMigration).toHaveBeenCalledWith(
expect.any(Function),
expect.any(Function),
encryptedType,
encryptedType
);
});

test('migrates the consumer for alerting', () => {
const migration790 = getMigrations(encryptedSavedObjectsSetup, encryptedType)['7.9.0'];
const alert = getMockData({
consumer: 'alerting',
});
expect(migration790(alert, { log })).toMatchObject({
...alert,
attributes: {
...alert.attributes,
consumer: 'alerts',
},
});
});

test('migrates the consumer for metrics', () => {
const migration790 = getMigrations(encryptedSavedObjectsSetup, encryptedType)['7.9.0'];
const alert = getMockData({
consumer: 'metrics',
});
expect(migration790(alert, { log })).toMatchObject({
...alert,
attributes: {
...alert.attributes,
consumer: 'infrastructure',
},
});
});
});

function getMockData(
overwrites: Record<string, unknown> = {}
): SavedObjectUnsanitizedDoc<RawAlert> {
return {
attributes: {
enabled: true,
name: 'abc',
tags: ['foo'],
alertTypeId: '123',
consumer: 'bar',
apiKey: '',
apiKeyOwner: '',
schedule: { interval: '10s' },
throttle: null,
params: {
bar: true,
},
muteAll: false,
mutedInstanceIds: [],
createdBy: new Date().toISOString(),
updatedBy: new Date().toISOString(),
createdAt: new Date().toISOString(),
actions: [
{
group: 'default',
actionRef: '1',
actionTypeId: '1',
params: {
foo: true,
},
},
],
...overwrites,
},
id: uuid.v4(),
type: 'alert',
};
}
60 changes: 60 additions & 0 deletions x-pack/plugins/alerts/server/saved_objects/migrations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/
import {
SavedObjectMigrationMap,
SavedObjectUnsanitizedDoc,
SavedObjectMigrationFn,
} from '../../../../../src/core/server';
import { RawAlert } from '../types';
import {
EncryptedSavedObjectsPluginSetup,
EncryptedSavedObjectTypeRegistration,
} from '../../../encrypted_saved_objects/server';

export function getMigrations(
encryptedSavedObjects: EncryptedSavedObjectsPluginSetup,
currentType: EncryptedSavedObjectTypeRegistration
): SavedObjectMigrationMap {
return {
'7.9.0': changeAlertingConsumer(encryptedSavedObjects, currentType),
};
}

/**
* In v7.9 we made a couple of changes:
* 1. We changed the Alerting plugin so it uses the `consumer` value of `alerts`
* Prior to that we were using `alerting` and we need to keep these in sync for RBAC
* 2. We aligned the metrics alerts with the feature that needs to grant them privileges
* so their consumer field has changed from `metrics` to `infrastructure`
*/
function changeAlertingConsumer(
encryptedSavedObjects: EncryptedSavedObjectsPluginSetup,
currentType: EncryptedSavedObjectTypeRegistration
): SavedObjectMigrationFn<RawAlert, RawAlert> {
const consumerMigration = new Map<string, string>();
consumerMigration.set('alerting', 'alerts');
consumerMigration.set('metrics', 'infrastructure');

return encryptedSavedObjects.createMigration<RawAlert, RawAlert>(
function shouldbeMigrated(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> {
return consumerMigration.has(doc.attributes.consumer);
},
(doc: SavedObjectUnsanitizedDoc<RawAlert>): SavedObjectUnsanitizedDoc<RawAlert> => {
const {
attributes: { consumer },
} = doc;
return {
...doc,
attributes: {
...doc.attributes,
consumer: consumerMigration.get(consumer) ?? consumer,
},
};
},
// type hasn't changed as the field we're updating is not an encrupted one
currentType
);
}
Loading

0 comments on commit 6ded0a8

Please sign in to comment.