Skip to content

Commit

Permalink
use alertsclient in task runner
Browse files Browse the repository at this point in the history
  • Loading branch information
gmmorris committed Jul 2, 2020
1 parent e454e59 commit b3ed832
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 140 deletions.
2 changes: 1 addition & 1 deletion x-pack/plugins/alerts/server/alerts_client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1886,7 +1886,7 @@ describe('get()', () => {
references: [],
});
await expect(alertsClient.get({ id: '1' })).rejects.toThrowErrorMatchingInlineSnapshot(
`"Reference action_0 not found"`
`"Action reference \\"action_0\\" not found in alert id: 1"`
);
});

Expand Down
5 changes: 3 additions & 2 deletions x-pack/plugins/alerts/server/alerts_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -719,13 +719,14 @@ export class AlertsClient {
}

private injectReferencesIntoActions(
alertId: string,
actions: RawAlert['actions'],
references: SavedObjectReference[]
) {
return actions.map((action) => {
const reference = references.find((ref) => ref.name === action.actionRef);
if (!reference) {
throw new Error(`Reference ${action.actionRef} not found`);
throw new Error(`Action reference "${action.actionRef}" not found in alert id: ${alertId}`);
}
return {
...omit(action, 'actionRef'),
Expand Down Expand Up @@ -759,7 +760,7 @@ export class AlertsClient {
// Once we support additional types, this type signature will likely change
schedule: rawAlert.schedule as IntervalSchedule,
actions: rawAlert.actions
? this.injectReferencesIntoActions(rawAlert.actions, references || [])
? this.injectReferencesIntoActions(id, rawAlert.actions, references || [])
: [],
...(updatedAt ? { updatedAt: new Date(updatedAt) } : {}),
...(createdAt ? { createdAt: new Date(createdAt) } : {}),
Expand Down
20 changes: 11 additions & 9 deletions x-pack/plugins/alerts/server/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,9 +222,19 @@ export class AlertingPlugin {
features: plugins.features,
});

const getAlertsClientWithRequest = (request: KibanaRequest) => {
if (isESOUsingEphemeralEncryptionKey === true) {
throw new Error(
`Unable to create alerts client due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml`
);
}
return alertsClientFactory!.create(request, core.savedObjects);
};

taskRunnerFactory.initialize({
logger,
getServices: this.getServicesFactory(core.savedObjects, core.elasticsearch),
getAlertsClientWithRequest,
spaceIdToNamespace: this.spaceIdToNamespace,
actionsPlugin: plugins.actions,
encryptedSavedObjectsClient,
Expand All @@ -236,15 +246,7 @@ export class AlertingPlugin {

return {
listTypes: alertTypeRegistry!.list.bind(this.alertTypeRegistry!),
// Ability to get an alerts client from legacy code
getAlertsClientWithRequest: (request: KibanaRequest) => {
if (isESOUsingEphemeralEncryptionKey === true) {
throw new Error(
`Unable to create alerts client due to the Encrypted Saved Objects plugin using an ephemeral encryption key. Please set xpack.encryptedSavedObjects.encryptionKey in kibana.yml`
);
}
return alertsClientFactory!.create(request, core.savedObjects);
},
getAlertsClientWithRequest,
};
}

Expand Down
112 changes: 40 additions & 72 deletions x-pack/plugins/alerts/server/task_runner/task_runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import { encryptedSavedObjectsMock } from '../../../encrypted_saved_objects/serv
import { loggingSystemMock } from '../../../../../src/core/server/mocks';
import { PluginStartContract as ActionsPluginStart } from '../../../actions/server';
import { actionsMock, actionsClientMock } from '../../../actions/server/mocks';
import { alertsMock } from '../mocks';
import { alertsMock, alertsClientMock } from '../mocks';
import { eventLoggerMock } from '../../../event_log/server/event_logger.mock';
import { IEventLogger } from '../../../event_log/server';
import { SavedObjectsErrorHelpers } from '../../../../../src/core/server';
Expand Down Expand Up @@ -56,15 +56,16 @@ describe('Task Runner', () => {

const encryptedSavedObjectsClient = encryptedSavedObjectsMock.createClient();
const services = alertsMock.createAlertServices();
const savedObjectsClient = services.savedObjectsClient;
const actionsClient = actionsClientMock.create();
const alertsClient = alertsClientMock.create();

const taskRunnerFactoryInitializerParams: jest.Mocked<TaskRunnerContext> & {
actionsPlugin: jest.Mocked<ActionsPluginStart>;
eventLogger: jest.Mocked<IEventLogger>;
} = {
getServices: jest.fn().mockReturnValue(services),
actionsPlugin: actionsMock.createStart(),
getAlertsClientWithRequest: jest.fn().mockReturnValue(alertsClient),
encryptedSavedObjectsClient,
logger: loggingSystemMock.create().get(),
spaceIdToNamespace: jest.fn().mockReturnValue(undefined),
Expand All @@ -74,41 +75,39 @@ describe('Task Runner', () => {

const mockedAlertTypeSavedObject = {
id: '1',
type: 'alert',
attributes: {
enabled: true,
alertTypeId: '123',
schedule: { interval: '10s' },
name: 'alert-name',
tags: ['alert-', '-tags'],
createdBy: 'alert-creator',
updatedBy: 'alert-updater',
mutedInstanceIds: [],
params: {
bar: true,
},
actions: [
{
group: 'default',
actionRef: 'action_0',
params: {
foo: true,
},
},
],
consumer: 'bar',
createdAt: new Date('2019-02-12T21:01:22.479Z'),
updatedAt: new Date('2019-02-12T21:01:22.479Z'),
throttle: null,
muteAll: false,
enabled: true,
alertTypeId: '123',
apiKeyOwner: 'elastic',
schedule: { interval: '10s' },
name: 'alert-name',
tags: ['alert-', '-tags'],
createdBy: 'alert-creator',
updatedBy: 'alert-updater',
mutedInstanceIds: [],
params: {
bar: true,
},
references: [
actions: [
{
name: 'action_0',
type: 'action',
group: 'default',
id: '1',
actionTypeId: 'action',
params: {
foo: true,
},
},
],
};

beforeEach(() => {
jest.resetAllMocks();
taskRunnerFactoryInitializerParams.getServices.mockReturnValue(services);
taskRunnerFactoryInitializerParams.getAlertsClientWithRequest.mockReturnValue(alertsClient);
taskRunnerFactoryInitializerParams.actionsPlugin.getActionsClientWithRequest.mockResolvedValue(
actionsClient
);
Expand All @@ -126,7 +125,7 @@ describe('Task Runner', () => {
},
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand Down Expand Up @@ -200,7 +199,7 @@ describe('Task Runner', () => {
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand Down Expand Up @@ -285,7 +284,7 @@ describe('Task Runner', () => {
],
},
message:
"alert: test:1: 'alert-name' instanceId: '1' scheduled actionGroup: 'default' action: undefined:1",
"alert: test:1: 'alert-name' instanceId: '1' scheduled actionGroup: 'default' action: action:1",
});
});

Expand All @@ -302,7 +301,7 @@ describe('Task Runner', () => {
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand Down Expand Up @@ -412,7 +411,7 @@ describe('Task Runner', () => {
},
],
},
"message": "alert: test:1: 'alert-name' instanceId: '1' scheduled actionGroup: 'default' action: undefined:1",
"message": "alert: test:1: 'alert-name' instanceId: '1' scheduled actionGroup: 'default' action: action:1",
},
],
]
Expand All @@ -439,7 +438,7 @@ describe('Task Runner', () => {
},
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand Down Expand Up @@ -526,7 +525,7 @@ describe('Task Runner', () => {
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand All @@ -548,44 +547,13 @@ describe('Task Runner', () => {
);
});

test('throws error if reference not found', async () => {
const taskRunner = new TaskRunner(
alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce({
...mockedAlertTypeSavedObject,
references: [],
});
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
attributes: {
apiKey: Buffer.from('123:abc').toString('base64'),
},
references: [],
});
expect(await taskRunner.run()).toMatchInlineSnapshot(`
Object {
"runAt": 1970-01-01T00:00:10.000Z,
"state": Object {
"previousStartedAt": 1970-01-01T00:00:00.000Z,
},
}
`);
expect(taskRunnerFactoryInitializerParams.logger.error).toHaveBeenCalledWith(
`Executing Alert \"1\" has resulted in Error: Action reference \"action_0\" not found in alert id: 1`
);
});

test('uses API key when provided', async () => {
const taskRunner = new TaskRunner(
alertType,
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand Down Expand Up @@ -621,7 +589,7 @@ describe('Task Runner', () => {
mockedTaskInstance,
taskRunnerFactoryInitializerParams
);
savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand Down Expand Up @@ -660,7 +628,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);

savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand Down Expand Up @@ -722,7 +690,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);

savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);

const runnerResult = await taskRunner.run();

Expand All @@ -747,7 +715,7 @@ describe('Task Runner', () => {
taskRunnerFactoryInitializerParams
);

savedObjectsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
alertsClient.get.mockResolvedValueOnce(mockedAlertTypeSavedObject);
encryptedSavedObjectsClient.getDecryptedAsInternalUser.mockResolvedValueOnce({
id: '1',
type: 'alert',
Expand All @@ -770,7 +738,7 @@ describe('Task Runner', () => {
});

test('recovers gracefully when the Alert Task Runner throws an exception when fetching attributes', async () => {
savedObjectsClient.get.mockImplementation(() => {
alertsClient.get.mockImplementation(() => {
throw new Error('OMG');
});

Expand Down Expand Up @@ -802,7 +770,7 @@ describe('Task Runner', () => {
});

test('avoids rescheduling a failed Alert Task Runner when it throws due to failing to fetch the alert', async () => {
savedObjectsClient.get.mockImplementation(() => {
alertsClient.get.mockImplementation(() => {
throw SavedObjectsErrorHelpers.createGenericNotFoundError('task', '1');
});

Expand Down
Loading

0 comments on commit b3ed832

Please sign in to comment.