Skip to content

Commit

Permalink
[Event log][7.x] Updated event log client to search across legacy IDs (
Browse files Browse the repository at this point in the history
…#109365)

* [Event log][7.x] Updated event log client to search across legacy IDs

* fixed tests

* extended kibana null version check

* added logic to alerting plugin

* fixed typechecks

* fixed typechecks

* Revert "fixed typechecks"

This reverts commit 6f6770f.

* removed legacyId for routes

* fixed typechecks

* fixed position

* fixed query

* fixed query

* fixed tests

* fixed types place

* fixed due to comments

* fixed due to comments

* fixed eslint

* fixed due to comments

* splitted test data

* fixed test data

* increased the delay time to await the search

* removed version for 7.9 docs

* Update x-pack/plugins/event_log/server/es/cluster_client_adapter.ts

Co-authored-by: Mike Côté <mikecote@users.noreply.github.com>

* fixed unit test

* fixed test data

Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
Co-authored-by: Mike Côté <mikecote@users.noreply.github.com>
  • Loading branch information
3 people authored Sep 3, 2021
1 parent 9c165a1 commit d421c4d
Show file tree
Hide file tree
Showing 16 changed files with 1,539 additions and 284 deletions.
63 changes: 46 additions & 17 deletions x-pack/plugins/alerting/server/rules_client/rules_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ import {
AlertNotifyWhenType,
AlertTypeParams,
ResolvedSanitizedRule,
AlertWithLegacyId,
SanitizedAlertWithLegacyId,
PartialAlertWithLegacyId,
} from '../types';
import {
validateAlertTypeParams,
Expand Down Expand Up @@ -383,9 +386,11 @@ export class RulesClient {

public async get<Params extends AlertTypeParams = never>({
id,
includeLegacyId = false,
}: {
id: string;
}): Promise<SanitizedAlert<Params>> {
includeLegacyId?: boolean;
}): Promise<SanitizedAlert<Params> | SanitizedAlertWithLegacyId<Params>> {
const result = await this.unsecuredSavedObjectsClient.get<RawAlert>('alert', id);
try {
await this.authorization.ensureAuthorized({
Expand Down Expand Up @@ -414,7 +419,8 @@ export class RulesClient {
result.id,
result.attributes.alertTypeId,
result.attributes,
result.references
result.references,
includeLegacyId
);
}

Expand Down Expand Up @@ -486,7 +492,8 @@ export class RulesClient {
dateStart,
}: GetAlertInstanceSummaryParams): Promise<AlertInstanceSummary> {
this.logger.debug(`getAlertInstanceSummary(): getting alert ${id}`);
const alert = await this.get({ id });
const alert = (await this.get({ id, includeLegacyId: true })) as SanitizedAlertWithLegacyId;

await this.authorization.ensureAuthorized({
ruleTypeId: alert.alertTypeId,
consumer: alert.consumer,
Expand All @@ -505,13 +512,18 @@ export class RulesClient {
this.logger.debug(`getAlertInstanceSummary(): search the event log for alert ${id}`);
let events: IEvent[];
try {
const queryResults = await eventLogClient.findEventsBySavedObjectIds('alert', [id], {
page: 1,
per_page: 10000,
start: parsedDateStart.toISOString(),
end: dateNow.toISOString(),
sort_order: 'desc',
});
const queryResults = await eventLogClient.findEventsBySavedObjectIds(
'alert',
[id],
{
page: 1,
per_page: 10000,
start: parsedDateStart.toISOString(),
end: dateNow.toISOString(),
sort_order: 'desc',
},
alert.legacyId !== null ? [alert.legacyId] : undefined
);
events = queryResults.data;
} catch (err) {
this.logger.debug(
Expand Down Expand Up @@ -1533,13 +1545,26 @@ export class RulesClient {
id: string,
ruleTypeId: string,
rawAlert: RawAlert,
references: SavedObjectReference[] | undefined
): Alert {
references: SavedObjectReference[] | undefined,
includeLegacyId: boolean = false
): Alert | AlertWithLegacyId {
const ruleType = this.ruleTypeRegistry.get(ruleTypeId);
// In order to support the partial update API of Saved Objects we have to support
// partial updates of an Alert, but when we receive an actual RawAlert, it is safe
// to cast the result to an Alert
return this.getPartialAlertFromRaw<Params>(id, ruleType, rawAlert, references) as Alert;
const res = this.getPartialAlertFromRaw<Params>(
id,
ruleType,
rawAlert,
references,
includeLegacyId
);
// include to result because it is for internal rules client usage
if (includeLegacyId) {
return res as AlertWithLegacyId;
}
// exclude from result because it is an internal variable
return omit(res, ['legacyId']) as Alert;
}

private getPartialAlertFromRaw<Params extends AlertTypeParams>(
Expand All @@ -1550,17 +1575,18 @@ export class RulesClient {
updatedAt,
meta,
notifyWhen,
legacyId,
scheduledTaskId,
params,
legacyId, // exclude from result because it is an internal variable
executionStatus,
schedule,
actions,
...partialRawAlert
}: Partial<RawAlert>,
references: SavedObjectReference[] | undefined
): PartialAlert<Params> {
return {
references: SavedObjectReference[] | undefined,
includeLegacyId: boolean = false
): PartialAlert<Params> | PartialAlertWithLegacyId<Params> {
const rule = {
id,
notifyWhen,
...partialRawAlert,
Expand All @@ -1576,6 +1602,9 @@ export class RulesClient {
? { executionStatus: alertExecutionStatusFromRaw(this.logger, id, executionStatus) }
: {}),
};
return includeLegacyId
? ({ ...rule, legacyId } as PartialAlertWithLegacyId<Params>)
: (rule as PartialAlert<Params>);
}

private async validateActions(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ describe('getAlertInstanceSummary()', () => {
"sort_order": "desc",
"start": "2019-02-12T21:00:22.479Z",
},
undefined,
]
`);
// calculate the expected start/end date for one test
Expand All @@ -225,6 +226,38 @@ describe('getAlertInstanceSummary()', () => {
expect(endMillis - startMillis).toBeLessThan(expectedDuration + 2);
});

test('calls event log client with legacy ids param', async () => {
unsecuredSavedObjectsClient.get.mockResolvedValueOnce(
getAlertInstanceSummarySavedObject({ legacyId: '99999' })
);
eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(
AlertInstanceSummaryFindEventsResult
);

await rulesClient.getAlertInstanceSummary({ id: '1' });

expect(unsecuredSavedObjectsClient.get).toHaveBeenCalledTimes(1);
expect(eventLogClient.findEventsBySavedObjectIds).toHaveBeenCalledTimes(1);
expect(eventLogClient.findEventsBySavedObjectIds.mock.calls[0]).toMatchInlineSnapshot(`
Array [
"alert",
Array [
"1",
],
Object {
"end": "2019-02-12T21:01:22.479Z",
"page": 1,
"per_page": 10000,
"sort_order": "desc",
"start": "2019-02-12T21:00:22.479Z",
},
Array [
"99999",
],
]
`);
});

test('calls event log client with start date', async () => {
unsecuredSavedObjectsClient.get.mockResolvedValueOnce(getAlertInstanceSummarySavedObject());
eventLogClient.findEventsBySavedObjectIds.mockResolvedValueOnce(
Expand Down
15 changes: 15 additions & 0 deletions x-pack/plugins/alerting/server/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,21 @@ export interface RawAlertExecutionStatus extends SavedObjectAttributes {
export type PartialAlert<Params extends AlertTypeParams = never> = Pick<Alert<Params>, 'id'> &
Partial<Omit<Alert<Params>, 'id'>>;

export interface AlertWithLegacyId<Params extends AlertTypeParams = never> extends Alert<Params> {
legacyId: string | null;
}

export type SanitizedAlertWithLegacyId<Params extends AlertTypeParams = never> = Omit<
AlertWithLegacyId<Params>,
'apiKey'
>;

export type PartialAlertWithLegacyId<Params extends AlertTypeParams = never> = Pick<
AlertWithLegacyId<Params>,
'id'
> &
Partial<Omit<AlertWithLegacyId<Params>, 'id'>>;

export interface RawAlert extends SavedObjectAttributes {
enabled: boolean;
name: string;
Expand Down
7 changes: 5 additions & 2 deletions x-pack/plugins/event_log/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ Request Body:
|Property|Description|Type|
|---|---|---|
|ids|The array ids of the saved object.|string array|
|legacyIds|The array legacy ids of the saved object. This filter applies to the rules creted in Kibana versions before 8.0.0.|string array|

Response body:

Expand All @@ -284,7 +285,8 @@ interface EventLogClient {
findEventsBySavedObjectIds(
type: string,
ids: string[],
options?: Partial<FindOptionsType>
options?: Partial<FindOptionsType>,
legacyIds?: string[]
): Promise<QueryEventsBySavedObjectResult>;
}

Expand Down Expand Up @@ -404,7 +406,8 @@ export interface IEventLogClient {
findEventsBySavedObjectIds(
type: string,
ids: string[],
options?: Partial<FindOptionsType>
options?: Partial<FindOptionsType>,
legacyIds?: string[]
): Promise<QueryEventsBySavedObjectResult>;
}
```
Expand Down
Loading

0 comments on commit d421c4d

Please sign in to comment.