mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 17:59:23 -04:00
[Telemetry][Security Solution] Enrich endpoint alerts with license info (#188760)
This commit is contained in:
parent
47842f9c43
commit
aa6aa26866
5 changed files with 43 additions and 11 deletions
|
@ -22,8 +22,8 @@ const asyncUnlink = Util.promisify(Fs.unlink);
|
|||
*/
|
||||
export async function eventually<T>(
|
||||
cb: () => Promise<T>,
|
||||
duration: number = 60000,
|
||||
interval: number = 1000
|
||||
duration: number = 120000,
|
||||
interval: number = 3000
|
||||
) {
|
||||
let elapsed = 0;
|
||||
|
||||
|
|
|
@ -148,8 +148,7 @@ describe('telemetry tasks', () => {
|
|||
});
|
||||
});
|
||||
|
||||
// FLAKY: https://github.com/elastic/kibana/issues/187719
|
||||
describe.skip('detection-rules', () => {
|
||||
describe('detection-rules', () => {
|
||||
it('should execute when scheduled', async () => {
|
||||
await mockAndScheduleDetectionRulesTask();
|
||||
|
||||
|
@ -263,7 +262,7 @@ describe('telemetry tasks', () => {
|
|||
// wait until the events are sent to the telemetry server
|
||||
const body = await eventually(async () => {
|
||||
const found = mockedAxiosPost.mock.calls.find(([url]) => {
|
||||
return url.startsWith(ENDPOINT_STAGING) && url.endsWith('alerts-endpoint');
|
||||
return url.startsWith(ENDPOINT_STAGING) && url.endsWith(TelemetryChannel.ENDPOINT_ALERTS);
|
||||
});
|
||||
|
||||
expect(found).not.toBeFalsy();
|
||||
|
@ -274,6 +273,25 @@ describe('telemetry tasks', () => {
|
|||
expect(body).not.toBeFalsy();
|
||||
expect(body.Endpoint).not.toBeFalsy();
|
||||
});
|
||||
|
||||
it('should enrich with license info', async () => {
|
||||
await mockAndScheduleEndpointDiagnosticsTask();
|
||||
|
||||
// wait until the events are sent to the telemetry server
|
||||
const body = await eventually(async () => {
|
||||
const found = mockedAxiosPost.mock.calls.find(([url]) => {
|
||||
return url.startsWith(ENDPOINT_STAGING) && url.endsWith(TelemetryChannel.ENDPOINT_ALERTS);
|
||||
});
|
||||
|
||||
expect(found).not.toBeFalsy();
|
||||
|
||||
return JSON.parse((found ? found[1] : '{}') as string);
|
||||
});
|
||||
|
||||
expect(body).not.toBeFalsy();
|
||||
expect(body.license).not.toBeFalsy();
|
||||
expect(body.license.status).not.toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('endpoint-meta-telemetry', () => {
|
||||
|
@ -680,8 +698,7 @@ describe('telemetry tasks', () => {
|
|||
expect(body.file).toStrictEqual(alertsDetectionsRequest.file);
|
||||
});
|
||||
|
||||
// Flaky: https://github.com/elastic/kibana/issues/188234
|
||||
it.skip('should manage runtime errors searching endpoint metrics', async () => {
|
||||
it('should manage runtime errors searching endpoint metrics', async () => {
|
||||
const errorMessage = 'Something went wront';
|
||||
|
||||
async function* mockedGenerator(
|
||||
|
|
|
@ -21,7 +21,7 @@ import { TelemetryChannel, TelemetryCounter } from './types';
|
|||
import * as collections from './collections_helpers';
|
||||
import { CachedSubject, retryOnError$ } from './rxjs_helpers';
|
||||
import { SenderUtils } from './sender_helpers';
|
||||
import { newTelemetryLogger } from './helpers';
|
||||
import { copyLicenseFields, newTelemetryLogger } from './helpers';
|
||||
import { type TelemetryLogger } from './telemetry_logger';
|
||||
|
||||
export const DEFAULT_QUEUE_CONFIG: QueueConfig = {
|
||||
|
@ -291,6 +291,14 @@ export class AsyncTelemetryEventsSender implements IAsyncTelemetryEventsSender {
|
|||
};
|
||||
}
|
||||
|
||||
if (event.channel === TelemetryChannel.ENDPOINT_ALERTS) {
|
||||
const licenseInfo = this.telemetryReceiver?.getLicenseInfo();
|
||||
additional = {
|
||||
...additional,
|
||||
...(licenseInfo ? { license: copyLicenseFields(licenseInfo) } : {}),
|
||||
};
|
||||
}
|
||||
|
||||
event.payload = {
|
||||
...event.payload,
|
||||
...additional,
|
||||
|
|
|
@ -102,6 +102,8 @@ export interface ITelemetryReceiver {
|
|||
|
||||
fetchClusterInfo(): Promise<ESClusterInfo>;
|
||||
|
||||
getLicenseInfo(): Nullable<ESLicense>;
|
||||
|
||||
fetchLicenseInfo(): Promise<Nullable<ESLicense>>;
|
||||
|
||||
closePointInTime(pitId: string): Promise<void>;
|
||||
|
@ -248,6 +250,7 @@ export class TelemetryReceiver implements ITelemetryReceiver {
|
|||
private getIndexForType?: (type: string) => string;
|
||||
private alertsIndex?: string;
|
||||
private clusterInfo?: ESClusterInfo;
|
||||
private licenseInfo?: Nullable<ESLicense>;
|
||||
private processTreeFetcher?: Fetcher;
|
||||
private packageService?: PackageService;
|
||||
private experimentalFeatures: ExperimentalFeatures | undefined;
|
||||
|
@ -280,6 +283,7 @@ export class TelemetryReceiver implements ITelemetryReceiver {
|
|||
this.soClient =
|
||||
core?.savedObjects.createInternalRepository() as unknown as SavedObjectsClientContract;
|
||||
this.clusterInfo = await this.fetchClusterInfo();
|
||||
this.licenseInfo = await this.fetchLicenseInfo();
|
||||
this.experimentalFeatures = endpointContextService?.experimentalFeatures;
|
||||
const elasticsearch = core?.elasticsearch.client as unknown as IScopedClusterClient;
|
||||
this.processTreeFetcher = new Fetcher(elasticsearch);
|
||||
|
@ -291,6 +295,10 @@ export class TelemetryReceiver implements ITelemetryReceiver {
|
|||
return this.clusterInfo;
|
||||
}
|
||||
|
||||
public getLicenseInfo(): Nullable<ESLicense> {
|
||||
return this.licenseInfo;
|
||||
}
|
||||
|
||||
public getAlertsIndex(): string | undefined {
|
||||
return this.alertsIndex;
|
||||
}
|
||||
|
|
|
@ -8,11 +8,10 @@
|
|||
import type { Logger } from '@kbn/core/server';
|
||||
import { newTelemetryLogger, getPreviousDiagTaskTimestamp } from '../helpers';
|
||||
import type { ITelemetryEventsSender } from '../sender';
|
||||
import type { TelemetryEvent } from '../types';
|
||||
import { TelemetryChannel, type TelemetryEvent } from '../types';
|
||||
import type { ITelemetryReceiver } from '../receiver';
|
||||
import type { TaskExecutionPeriod } from '../task';
|
||||
import type { ITaskMetricsService } from '../task_metrics.types';
|
||||
import { TELEMETRY_CHANNEL_ENDPOINT_ALERTS } from '../constants';
|
||||
import { copyAllowlistedFields, filterList } from '../filterlists';
|
||||
|
||||
export function createTelemetryDiagnosticsTaskConfig() {
|
||||
|
@ -65,7 +64,7 @@ export function createTelemetryDiagnosticsTaskConfig() {
|
|||
log.l('Sending diagnostic alerts', {
|
||||
alerts_count: alerts.length,
|
||||
});
|
||||
await sender.sendOnDemand(TELEMETRY_CHANNEL_ENDPOINT_ALERTS, processedAlerts);
|
||||
sender.sendAsync(TelemetryChannel.ENDPOINT_ALERTS, processedAlerts);
|
||||
}
|
||||
|
||||
await taskMetricsService.end(trace);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue