Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions x-pack/plugins/alerting/server/saved_objects/migrations.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1029,6 +1029,55 @@ describe('7.13.0', () => {
});
});

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

test('security solution author field is migrated to array if it is undefined', () => {
const migration7141 = getMigrations(encryptedSavedObjectsSetup)['7.14.1'];
const alert = getMockData({
alertTypeId: 'siem.signals',
params: {},
});

expect(migration7141(alert, migrationContext)).toEqual({
...alert,
attributes: {
...alert.attributes,
params: {
author: [],
},
},
});
});

test('security solution author field does not override existing values if they exist', () => {
const migration7141 = getMigrations(encryptedSavedObjectsSetup)['7.14.1'];
const alert = getMockData({
alertTypeId: 'siem.signals',
params: {
note: 'some note',
author: ['author 1'],
},
});

expect(migration7141(alert, migrationContext)).toEqual({
...alert,
attributes: {
...alert.attributes,
params: {
note: 'some note',
author: ['author 1'],
},
},
});
});
});

function getUpdatedAt(): string {
const updatedAt = new Date();
updatedAt.setHours(updatedAt.getHours() + 2);
Expand Down
34 changes: 34 additions & 0 deletions x-pack/plugins/alerting/server/saved_objects/migrations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,17 @@ export function getMigrations(
pipeMigrations(removeNullsFromSecurityRules)
);

const migrationSecurityRules714 = encryptedSavedObjects.createMigration<RawAlert, RawAlert>(
(doc): doc is SavedObjectUnsanitizedDoc<RawAlert> => isSecuritySolutionRule(doc),
pipeMigrations(removeNullAuthorFromSecurityRules)
);

return {
'7.10.0': executeMigrationWithErrorHandling(migrationWhenRBACWasIntroduced, '7.10.0'),
'7.11.0': executeMigrationWithErrorHandling(migrationAlertUpdatedAtAndNotifyWhen, '7.11.0'),
'7.11.2': executeMigrationWithErrorHandling(migrationActions7112, '7.11.2'),
'7.13.0': executeMigrationWithErrorHandling(migrationSecurityRules713, '7.13.0'),
'7.14.1': executeMigrationWithErrorHandling(migrationSecurityRules714, '7.14.1'),
};
}

Expand Down Expand Up @@ -420,6 +426,34 @@ function removeNullsFromSecurityRules(
};
}

/**
* The author field was introduced later and was not part of the original rules. We overlooked
* the filling in the author field as an empty array in an earlier upgrade routine from
* 'removeNullsFromSecurityRules' during the 7.13.0 upgrade. Since we don't change earlier migrations,
* but rather only move forward with the "arrow of time" we are going to upgrade and fix
* it if it is missing for anyone in 7.14.0 and above release. Earlier releases if we want to fix them,
* would have to be modified as a "7.13.1", etc... if we want to fix it there.
* @param doc The document that is not migrated and contains a "null" or "undefined" author field
* @returns The document with the author field fleshed in.
*/
function removeNullAuthorFromSecurityRules(
doc: SavedObjectUnsanitizedDoc<RawAlert>
): SavedObjectUnsanitizedDoc<RawAlert> {
const {
attributes: { params },
} = doc;
return {
...doc,
attributes: {
...doc.attributes,
params: {
...params,
author: params.author != null ? params.author : [],
},
},
};
}

function pipeMigrations(...migrations: AlertMigration[]): AlertMigration {
return (doc: SavedObjectUnsanitizedDoc<RawAlert>) =>
migrations.reduce((migratedDoc, nextMigration) => nextMigration(migratedDoc), doc);
Expand Down