From 0db3ab0c1909ca587f897bd0b3be0e58ef3a089f Mon Sep 17 00:00:00 2001 From: JD Kurma Date: Fri, 18 Nov 2022 14:40:57 -0500 Subject: [PATCH] [Security Solution] Parse Snapshot Versions for Kibana Artifacts (#145626) ## Summary There are instances where the cluster info comes with a snapshot version such as "8.6.0-SNAPSHOT". This version string is used to construct the manifest url needed to retrieve kibana artifacts; however, those artifacts are categorized under non-snapshot versions(e.g. "8.6.0"). Hence, to properly retrieve the respective kibana artifacts, I am splitting the version string at '-' to get the applicable kibana artifact version. Similar methods of splitting are seen [here](https://github.com/elastic/kibana/blob/main/x-pack/plugins/monitoring/server/plugin.ts#L58) Also for additional reference: here is a [discussion](https://elastic.slack.com/archives/C5TQ33ND8/p1594726063167100) from #kibana-core slack channel on splitting at '-' for the version ### Checklist - [x] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com> --- .../server/lib/telemetry/artifact.test.ts | 32 ++++++++++++++++++- .../server/lib/telemetry/artifact.ts | 17 ++++++++-- .../lib/telemetry/tasks/configuration.ts | 1 + .../server/lib/telemetry/tasks/filterlists.ts | 1 + 4 files changed, 47 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/artifact.test.ts b/x-pack/plugins/security_solution/server/lib/telemetry/artifact.test.ts index b624336be51bf..a4e8d38875b8f 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/artifact.test.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/artifact.test.ts @@ -14,11 +14,41 @@ jest.mock('axios'); const mockedAxios = axios as jest.Mocked; describe('telemetry artifact test', () => { - test('start should retrieve cluster information', async () => { + test('start should set manifest url for snapshot version', async () => { + const expectedManifestUrl = + 'https://artifacts.security.elastic.co/downloads/kibana/manifest/artifacts-8.0.0.zip'; const mockTelemetryReceiver = createMockTelemetryReceiver(); const artifact = new Artifact(); await artifact.start(mockTelemetryReceiver); expect(mockTelemetryReceiver.fetchClusterInfo).toHaveBeenCalled(); + expect(artifact.getManifestUrl()).toEqual(expectedManifestUrl); + }); + + test('start should set manifest url for non-snapshot version', async () => { + const expectedManifestUrl = + 'https://artifacts.security.elastic.co/downloads/kibana/manifest/artifacts-8.0.0.zip'; + const mockTelemetryReceiver = createMockTelemetryReceiver(); + const stubClusterInfo = { + name: 'Stub-MacBook-Pro.local', + cluster_name: 'elasticsearch', + cluster_uuid: '5Pr5PXRQQpGJUTn0czAvKQ', + version: { + number: '8.0.0', + build_type: 'tar', + build_hash: '38537ab4a726b42ce8f034aad78d8fca4d4f3e51', + build_date: new Date().toISOString(), + build_snapshot: true, + lucene_version: '9.2.0', + minimum_wire_compatibility_version: '7.17.0', + minimum_index_compatibility_version: '7.0.0', + }, + tagline: 'You Know, for Search', + }; + mockTelemetryReceiver.fetchClusterInfo = jest.fn().mockReturnValue(stubClusterInfo); + const artifact = new Artifact(); + await artifact.start(mockTelemetryReceiver); + expect(mockTelemetryReceiver.fetchClusterInfo).toHaveBeenCalled(); + expect(artifact.getManifestUrl()).toEqual(expectedManifestUrl); }); test('getArtifact should throw an error if manifest url is null', async () => { diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/artifact.ts b/x-pack/plugins/security_solution/server/lib/telemetry/artifact.ts index f531db6a5d6d7..8d4cd82ebb152 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/artifact.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/artifact.ts @@ -13,6 +13,7 @@ import type { ESClusterInfo } from './types'; export interface IArtifact { start(receiver: ITelemetryReceiver): Promise; getArtifact(name: string): Promise; + getManifestUrl(): string | undefined; } export class Artifact implements IArtifact { @@ -25,8 +26,14 @@ export class Artifact implements IArtifact { public async start(receiver: ITelemetryReceiver) { this.receiver = receiver; this.esClusterInfo = await this.receiver.fetchClusterInfo(); - const version = this.esClusterInfo?.version?.number; - this.manifestUrl = `${this.CDN_URL}/downloads/kibana/manifest/artifacts-${version}.zip`; + if (this.esClusterInfo?.version?.number) { + const version = + this.esClusterInfo.version.number.substring( + 0, + this.esClusterInfo.version.number.indexOf('-') + ) || this.esClusterInfo.version.number; + this.manifestUrl = `${this.CDN_URL}/downloads/kibana/manifest/artifacts-${version}.zip`; + } } public async getArtifact(name: string): Promise { @@ -47,9 +54,13 @@ export class Artifact implements IArtifact { throw Error(`No artifact for name ${name}`); } } else { - throw Error('No manifest url'); + throw Error(`No manifest url for version ${this.esClusterInfo?.version?.number}`); } } + + public getManifestUrl() { + return this.manifestUrl; + } } export const artifactService = new Artifact(); diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/configuration.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/configuration.ts index 71e96e4c82c3f..75c7a9080b3b8 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/configuration.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/configuration.ts @@ -36,6 +36,7 @@ export function createTelemetryConfigurationTaskConfig() { const configArtifact = (await artifactService.getArtifact( artifactName )) as unknown as TelemetryConfiguration; + tlog(logger, `New telemetry configuration artifact: ${JSON.stringify(configArtifact)}`); telemetryConfiguration.max_detection_alerts_batch = configArtifact.max_detection_alerts_batch; telemetryConfiguration.telemetry_max_buffer_size = configArtifact.telemetry_max_buffer_size; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/filterlists.ts b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/filterlists.ts index 3919f3c8c7f4c..50bf10c964e08 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/tasks/filterlists.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/tasks/filterlists.ts @@ -36,6 +36,7 @@ export function createTelemetryFilterListArtifactTaskConfig() { const artifact = (await artifactService.getArtifact( artifactName )) as unknown as TelemetryFilterListArtifact; + tlog(logger, `New filterlist artifact: ${JSON.stringify(artifact)}`); filterList.endpointAlerts = artifact.endpoint_alerts; filterList.exceptionLists = artifact.exception_lists; filterList.prebuiltRulesAlerts = artifact.prebuilt_rules_alerts;