Skip to content

Commit

Permalink
[8.x] [Automatic Import] Reject CEF logs in Auto Import until it is s…
Browse files Browse the repository at this point in the history
…upported (#201792) (#202444)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Automatic Import] Reject CEF logs in Auto Import until it is
supported (#201792)](#201792)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Bharat
Pasupula","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-12-02T11:46:04Z","message":"[Automatic
Import] Reject CEF logs in Auto Import until it is supported
(#201792)\n\n## Release Note\r\n\r\nRestrict and Reject CEF logs in
Automatic Import and redirect to CEF\r\nintegration instead.\r\n\r\n##
Summary\r\n\r\nCurrently Automatic Import does not handle CEF logs
properly and gives\r\nwierd errors.\r\n\r\nThis PR identifies the CEF
logs and sends an error popup to\r\nalternatively go for CEF integration
instead.\r\n\r\n<img width=\"1229\"
alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/59037dd4-323a-476a-9747-950fbc6e384d\">\r\n\r\n##
Testing\r\n\r\nTested this with different types of CEF
logs\r\n\r\n```\r\n<14>Nov 22 16:19:13 ABQ-ZTA-VRNS-3 CEF:0|Varonis
Inc.|DatAdvantage|8.6.51|6000|Folder permissions added|3|rt=Nov 22 2024
16:19:09 cat=Alert cs2=Permissions granted to Global Access Groups
cs2Label=RuleName cn1=132 cn1Label=RuleID end=Nov 22 2024 16:19:05
duser=zta.local\\\\Dani Lulli (ADMIN) dhost=10.100.20.12
filePath=E:\\\\Share\\\\Share\\\\Finance fname=Finance act=Folder
permissions added dvchost= outcome=Success msg=Read & Execute
permissions for This folder, subfolders and files (not inherited) was
added to Everyone on E:\\\\Share\\\\Share\\\\Finance cs3=
cs3Label=AttachmentName cs4= cs4Label=ClientAccessType
deviceCustomDate1= fileType= cs1= cs1Label=MailRecipient suser= cs5=
cs5Label=MailboxAccessType cnt= cs6=Read & Execute
cs6Label=ChangedPermissions oldFilePermission=None filePermission=Read &
Execute dpriv=Everyone start=\r\n<14>Nov 22 16:44:31 ABQ-ZTA-VRNS-3
CEF:0|Varonis Inc.|DatAdvantage|8.6.51|1|File opened|2|rt=Nov 22 2024
16:44:31 cat=Alert cs2=Dani Test - access of credentials
cs2Label=RuleName cn1=184 cn1Label=RuleID end=Nov 22 2024 16:34:33
duser=zta.local\\\\Dani Lulli (ADMIN) dhost=10.100.20.12
filePath=E:\\\\Share\\\\Share\\\\B4\\\\Project mgmt\\\\U3
projects11.txt:Zone.Identifier fname=U3 projects11.txt:Zone.Identifier
act=File opened dvchost= outcome=Success msg= cs3=
cs3Label=AttachmentName cs4= cs4Label=ClientAccessType
deviceCustomDate1= fileType= cs1= cs1Label=MailRecipient suser= cs5=
cs5Label=MailboxAccessType cnt= cs6=None cs6Label=ChangedPermissions
oldFilePermission=None filePermission=None dpriv=
start=\r\n```\r\n\r\n```\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|eventId=3457 requestMethod=POST slat=38.915 slong=-77.511
proto=TCP sourceServiceName=httpd requestContext=https://www.google.com
src=89.160.20.156 spt=33876 dst=192.168.10.1 dpt=443
request=https://www.example.com/cart\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|eventId=123
src=89.160.20.156 spt=33876 dst=89.160.20.156 dpt=443 duser=alice
suser=bob destinationTranslatedAddress=10.10.10.10
fileHash=bc8bbe52f041fd17318f08a0f73762ce
oldFileHash=a9796280592f86b74b27e370662d41eb\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|spriv=user
dpriv=root\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|message=This
event is padded with whitespace dst=192.168.1.2
src=192.168.3.4\r\n```\r\n\r\n```\r\n<163>Apr 1 05:14:15 192.0.2.1
CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc3164\r\nApr 1 05:14:15 192.0.2.1
CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc3164\r\n<164>1 2021-04-01T05:14:15.000003-05:00
192.0.2.1 rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n2021-04-01T05:14:15.000003-05:00 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n<165>1 2021-04-01T05:14:15.000003Z 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n2021-04-01T05:14:15.000003Z 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n```\r\n\r\n### Checklist\r\n\r\nCheck the PR
satisfies following conditions. \r\n\r\nReviewers should verify this PR
satisfies this list as well.\r\n\r\n- [x] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] The PR
description includes the appropriate Release Notes section,\r\nand the
correct `release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"f6fa94f4768f8a2623fceaaf242ead24a3667ad6","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:fix","v9.0.0","backport:prev-minor","Team:Security-Scalability","Feature:AutomaticImport"],"title":"[Automatic
Import] Reject CEF logs in Auto Import until it is
supported","number":201792,"url":"https://github.com/elastic/kibana/pull/201792","mergeCommit":{"message":"[Automatic
Import] Reject CEF logs in Auto Import until it is supported
(#201792)\n\n## Release Note\r\n\r\nRestrict and Reject CEF logs in
Automatic Import and redirect to CEF\r\nintegration instead.\r\n\r\n##
Summary\r\n\r\nCurrently Automatic Import does not handle CEF logs
properly and gives\r\nwierd errors.\r\n\r\nThis PR identifies the CEF
logs and sends an error popup to\r\nalternatively go for CEF integration
instead.\r\n\r\n<img width=\"1229\"
alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/59037dd4-323a-476a-9747-950fbc6e384d\">\r\n\r\n##
Testing\r\n\r\nTested this with different types of CEF
logs\r\n\r\n```\r\n<14>Nov 22 16:19:13 ABQ-ZTA-VRNS-3 CEF:0|Varonis
Inc.|DatAdvantage|8.6.51|6000|Folder permissions added|3|rt=Nov 22 2024
16:19:09 cat=Alert cs2=Permissions granted to Global Access Groups
cs2Label=RuleName cn1=132 cn1Label=RuleID end=Nov 22 2024 16:19:05
duser=zta.local\\\\Dani Lulli (ADMIN) dhost=10.100.20.12
filePath=E:\\\\Share\\\\Share\\\\Finance fname=Finance act=Folder
permissions added dvchost= outcome=Success msg=Read & Execute
permissions for This folder, subfolders and files (not inherited) was
added to Everyone on E:\\\\Share\\\\Share\\\\Finance cs3=
cs3Label=AttachmentName cs4= cs4Label=ClientAccessType
deviceCustomDate1= fileType= cs1= cs1Label=MailRecipient suser= cs5=
cs5Label=MailboxAccessType cnt= cs6=Read & Execute
cs6Label=ChangedPermissions oldFilePermission=None filePermission=Read &
Execute dpriv=Everyone start=\r\n<14>Nov 22 16:44:31 ABQ-ZTA-VRNS-3
CEF:0|Varonis Inc.|DatAdvantage|8.6.51|1|File opened|2|rt=Nov 22 2024
16:44:31 cat=Alert cs2=Dani Test - access of credentials
cs2Label=RuleName cn1=184 cn1Label=RuleID end=Nov 22 2024 16:34:33
duser=zta.local\\\\Dani Lulli (ADMIN) dhost=10.100.20.12
filePath=E:\\\\Share\\\\Share\\\\B4\\\\Project mgmt\\\\U3
projects11.txt:Zone.Identifier fname=U3 projects11.txt:Zone.Identifier
act=File opened dvchost= outcome=Success msg= cs3=
cs3Label=AttachmentName cs4= cs4Label=ClientAccessType
deviceCustomDate1= fileType= cs1= cs1Label=MailRecipient suser= cs5=
cs5Label=MailboxAccessType cnt= cs6=None cs6Label=ChangedPermissions
oldFilePermission=None filePermission=None dpriv=
start=\r\n```\r\n\r\n```\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|eventId=3457 requestMethod=POST slat=38.915 slong=-77.511
proto=TCP sourceServiceName=httpd requestContext=https://www.google.com
src=89.160.20.156 spt=33876 dst=192.168.10.1 dpt=443
request=https://www.example.com/cart\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|eventId=123
src=89.160.20.156 spt=33876 dst=89.160.20.156 dpt=443 duser=alice
suser=bob destinationTranslatedAddress=10.10.10.10
fileHash=bc8bbe52f041fd17318f08a0f73762ce
oldFileHash=a9796280592f86b74b27e370662d41eb\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|spriv=user
dpriv=root\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|message=This
event is padded with whitespace dst=192.168.1.2
src=192.168.3.4\r\n```\r\n\r\n```\r\n<163>Apr 1 05:14:15 192.0.2.1
CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc3164\r\nApr 1 05:14:15 192.0.2.1
CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc3164\r\n<164>1 2021-04-01T05:14:15.000003-05:00
192.0.2.1 rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n2021-04-01T05:14:15.000003-05:00 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n<165>1 2021-04-01T05:14:15.000003Z 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n2021-04-01T05:14:15.000003Z 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n```\r\n\r\n### Checklist\r\n\r\nCheck the PR
satisfies following conditions. \r\n\r\nReviewers should verify this PR
satisfies this list as well.\r\n\r\n- [x] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] The PR
description includes the appropriate Release Notes section,\r\nand the
correct `release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"f6fa94f4768f8a2623fceaaf242ead24a3667ad6"}},"sourceBranch":"main","suggestedTargetBranches":[],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201792","number":201792,"mergeCommit":{"message":"[Automatic
Import] Reject CEF logs in Auto Import until it is supported
(#201792)\n\n## Release Note\r\n\r\nRestrict and Reject CEF logs in
Automatic Import and redirect to CEF\r\nintegration instead.\r\n\r\n##
Summary\r\n\r\nCurrently Automatic Import does not handle CEF logs
properly and gives\r\nwierd errors.\r\n\r\nThis PR identifies the CEF
logs and sends an error popup to\r\nalternatively go for CEF integration
instead.\r\n\r\n<img width=\"1229\"
alt=\"image\"\r\nsrc=\"https://github.com/user-attachments/assets/59037dd4-323a-476a-9747-950fbc6e384d\">\r\n\r\n##
Testing\r\n\r\nTested this with different types of CEF
logs\r\n\r\n```\r\n<14>Nov 22 16:19:13 ABQ-ZTA-VRNS-3 CEF:0|Varonis
Inc.|DatAdvantage|8.6.51|6000|Folder permissions added|3|rt=Nov 22 2024
16:19:09 cat=Alert cs2=Permissions granted to Global Access Groups
cs2Label=RuleName cn1=132 cn1Label=RuleID end=Nov 22 2024 16:19:05
duser=zta.local\\\\Dani Lulli (ADMIN) dhost=10.100.20.12
filePath=E:\\\\Share\\\\Share\\\\Finance fname=Finance act=Folder
permissions added dvchost= outcome=Success msg=Read & Execute
permissions for This folder, subfolders and files (not inherited) was
added to Everyone on E:\\\\Share\\\\Share\\\\Finance cs3=
cs3Label=AttachmentName cs4= cs4Label=ClientAccessType
deviceCustomDate1= fileType= cs1= cs1Label=MailRecipient suser= cs5=
cs5Label=MailboxAccessType cnt= cs6=Read & Execute
cs6Label=ChangedPermissions oldFilePermission=None filePermission=Read &
Execute dpriv=Everyone start=\r\n<14>Nov 22 16:44:31 ABQ-ZTA-VRNS-3
CEF:0|Varonis Inc.|DatAdvantage|8.6.51|1|File opened|2|rt=Nov 22 2024
16:44:31 cat=Alert cs2=Dani Test - access of credentials
cs2Label=RuleName cn1=184 cn1Label=RuleID end=Nov 22 2024 16:34:33
duser=zta.local\\\\Dani Lulli (ADMIN) dhost=10.100.20.12
filePath=E:\\\\Share\\\\Share\\\\B4\\\\Project mgmt\\\\U3
projects11.txt:Zone.Identifier fname=U3 projects11.txt:Zone.Identifier
act=File opened dvchost= outcome=Success msg= cs3=
cs3Label=AttachmentName cs4= cs4Label=ClientAccessType
deviceCustomDate1= fileType= cs1= cs1Label=MailRecipient suser= cs5=
cs5Label=MailboxAccessType cnt= cs6=None cs6Label=ChangedPermissions
oldFilePermission=None filePermission=None dpriv=
start=\r\n```\r\n\r\n```\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|eventId=3457 requestMethod=POST slat=38.915 slong=-77.511
proto=TCP sourceServiceName=httpd requestContext=https://www.google.com
src=89.160.20.156 spt=33876 dst=192.168.10.1 dpt=443
request=https://www.example.com/cart\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|eventId=123
src=89.160.20.156 spt=33876 dst=89.160.20.156 dpt=443 duser=alice
suser=bob destinationTranslatedAddress=10.10.10.10
fileHash=bc8bbe52f041fd17318f08a0f73762ce
oldFileHash=a9796280592f86b74b27e370662d41eb\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|spriv=user
dpriv=root\r\nCEF:0|Elastic|Vaporware|1.0.0-alpha|18|Authentication|low|message=This
event is padded with whitespace dst=192.168.1.2
src=192.168.3.4\r\n```\r\n\r\n```\r\n<163>Apr 1 05:14:15 192.0.2.1
CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc3164\r\nApr 1 05:14:15 192.0.2.1
CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc3164\r\n<164>1 2021-04-01T05:14:15.000003-05:00
192.0.2.1 rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n2021-04-01T05:14:15.000003-05:00 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n<165>1 2021-04-01T05:14:15.000003Z 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n2021-04-01T05:14:15.000003Z 192.0.2.1
rfc5424App 8710 - - CEF:0|Elastic|Vaporware|1.0.0-alpha|18|Web
request|low|msg=rfc5424\r\n```\r\n\r\n### Checklist\r\n\r\nCheck the PR
satisfies following conditions. \r\n\r\nReviewers should verify this PR
satisfies this list as well.\r\n\r\n- [x] Any text added follows [EUI's
writing\r\nguidelines](https://elastic.github.io/eui/#/guidelines/writing),
uses\r\nsentence case text and includes
[i18n\r\nsupport](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md)\r\n-
[
]\r\n[Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html)\r\nwas
added for features that require explanation or tutorials\r\n- [x] [Unit
or
functional\r\ntests](https://www.elastic.co/guide/en/kibana/master/development-tests.html)\r\nwere
updated or added to match the most common scenarios\r\n- [x] The PR
description includes the appropriate Release Notes section,\r\nand the
correct `release_note:*` label is applied per
the\r\n[guidelines](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process)\r\n\r\n---------\r\n\r\nCo-authored-by:
Elastic Machine
<[email protected]>","sha":"f6fa94f4768f8a2623fceaaf242ead24a3667ad6"}}]}]
BACKPORT-->

Co-authored-by: Bharat Pasupula <[email protected]>
  • Loading branch information
kibanamachine and bhapas authored Dec 2, 2024
1 parent 9728176 commit a1cb4c2
Show file tree
Hide file tree
Showing 13 changed files with 258 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { GenerationErrorCode } from '../constants';
import { isGenerationErrorBody } from './generation_error';
import type { GenerationErrorBody } from './generation_error';

describe('isGenerationErrorBody', () => {
it('should return true for a valid GenerationErrorBody object', () => {
const validErrorBody: GenerationErrorBody = {
message: 'An error occurred',
attributes: {
errorCode: GenerationErrorCode.CEF_ERROR,
underlyingMessages: ['Error message 1', 'Error message 2'],
},
};

expect(isGenerationErrorBody(validErrorBody)).toBe(true);
});

it('should return false for an object without a message', () => {
const invalidErrorBody = {
attributes: {
errorCode: 'ERROR_CODE',
underlyingMessages: ['Error message 1', 'Error message 2'],
},
};

expect(isGenerationErrorBody(invalidErrorBody)).toBe(false);
});

it('should return false for an object without attributes', () => {
const invalidErrorBody = {
message: 'An error occurred',
};

expect(isGenerationErrorBody(invalidErrorBody)).toBe(false);
});

it('should return false for an object with invalid attributes', () => {
const invalidErrorBody = {
message: 'An error occurred',
attributes: {
errorCode: 123, // errorCode should be a string
underlyingMessages: 'Error message', // underlyingMessages should be an array
},
};

expect(isGenerationErrorBody(invalidErrorBody)).toBe(false);
});

it('should return false for a non-object value', () => {
expect(isGenerationErrorBody(null)).toBe(false);
expect(isGenerationErrorBody(undefined)).toBe(false);
expect(isGenerationErrorBody('string')).toBe(false);
expect(isGenerationErrorBody(123)).toBe(false);
expect(isGenerationErrorBody(true)).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ export interface GenerationErrorBody {
attributes: GenerationErrorAttributes;
}

export interface ErrorMessageWithLink {
link: string;
linkText: string;
errorMessage: string;
}

export function isGenerationErrorBody(obj: unknown | undefined): obj is GenerationErrorBody {
return (
typeof obj === 'object' &&
Expand All @@ -27,7 +33,8 @@ export function isGenerationErrorBody(obj: unknown | undefined): obj is Generati

export interface GenerationErrorAttributes {
errorCode: GenerationErrorCode;
underlyingMessages: string[] | undefined;
underlyingMessages?: string[] | undefined;
errorMessageWithLink?: ErrorMessageWithLink | undefined;
}

export function isGenerationErrorAttributes(obj: unknown): obj is GenerationErrorAttributes {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ export const SamplesFormatName = z.enum([
'structured',
'unstructured',
'unsupported',
'cef',
]);
export type SamplesFormatNameEnum = typeof SamplesFormatName.enum;
export const SamplesFormatNameEnum = SamplesFormatName.enum;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ components:
- structured
- unstructured
- unsupported
- cef

SamplesFormat:
type: object
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/integration_assistant/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ export enum GenerationErrorCode {
RECURSION_LIMIT_ANALYZE_LOGS = 'recursion-limit-analyze-logs',
UNSUPPORTED_LOG_SAMPLES_FORMAT = 'unsupported-log-samples-format',
UNPARSEABLE_CSV_DATA = 'unparseable-csv-data',
CEF_ERROR = 'cef-not-supported',
}

// Size limits
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { render } from '@testing-library/react';
import { ErrorMessage, isErrorMessageWithLink, MessageLink } from './error_with_link';

describe('isErrorMessageWithLink', () => {
it('should return true when error is an ErrorMessageWithLink', () => {
const error = {
link: 'http://example.com',
errorMessage: 'An error occurred',
linkText: 'decode_cef',
};
expect(isErrorMessageWithLink(error)).toBe(true);
});

it('should return false when error is a string', () => {
const error = 'An error occurred';
expect(isErrorMessageWithLink(error)).toBe(false);
});

describe('MessageLink', () => {
it('should render link with correct href and text', () => {
const { getByText } = render(<MessageLink link="http://example.com" linkText="decode_cef" />);
const linkElement = getByText('decode_cef');
expect(linkElement).toBeInTheDocument();
expect(linkElement).toHaveAttribute('href', 'http://example.com');
});
});

describe('ErrorMessage', () => {
it('should render error message when error is a string', () => {
const error = 'An error occurred';
const { getByText } = render(<ErrorMessage error={error} />);
expect(getByText('An error occurred')).toBeInTheDocument();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { FormattedMessage } from '@kbn/i18n-react';
import { EuiLink } from '@elastic/eui';
import type { ErrorMessageWithLink } from '../../../../../../common/api/generation_error';

interface ErrorMessageProps {
error: string | null | ErrorMessageWithLink;
}

interface MessageLinkProps {
link: string;
linkText: string;
}

export const isErrorMessageWithLink = (
error: string | ErrorMessageWithLink | null
): error is ErrorMessageWithLink => {
return (
(error as ErrorMessageWithLink).link !== undefined &&
(error as ErrorMessageWithLink).linkText !== undefined &&
(error as ErrorMessageWithLink).errorMessage !== undefined
);
};

export const MessageLink = React.memo<MessageLinkProps>(({ link, linkText }) => {
return (
<EuiLink href={link} target="_blank">
{linkText}
</EuiLink>
);
});
MessageLink.displayName = 'MessageLink';

export const ErrorMessage = React.memo<ErrorMessageProps>(({ error }) => {
return (
<>
{isErrorMessageWithLink(error) ? (
<FormattedMessage
id="xpack.integrationAssistant.createIntegration.generateErrorWithLink"
defaultMessage="{errorMessage} {link}"
values={{
errorMessage: error.errorMessage,
link: <MessageLink link={error.link} linkText={error.linkText} />,
}}
/>
) : typeof error === 'string' ? (
<>{error}</>
) : null}
</>
);
});
ErrorMessage.displayName = 'ErrorMessage';
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import * as i18n from './translations';

import type { OnComplete, ProgressItem } from './use_generation';
import { ProgressOrder, useGeneration } from './use_generation';
import { ErrorMessage } from './error_with_link';

const progressText: Record<ProgressItem, string> = {
analyzeLogs: i18n.PROGRESS_ANALYZE_LOGS,
Expand Down Expand Up @@ -87,7 +88,7 @@ export const GenerationModal = React.memo<GenerationModalProps>(
iconType="alert"
data-test-subj="generationErrorCallout"
>
{error}
<ErrorMessage error={error} />
</EuiCallOut>
</EuiFlexItem>
) : (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,13 @@ export const RETRY = i18n.translate('xpack.integrationAssistant.step.dataStream.
defaultMessage: 'Retry',
});

export const DECODE_CEF_LINK = i18n.translate(
'xpack.integrationAssistant.errors.cefFormat.decodeLink',
{
defaultMessage: 'CEF format not supported yet. Instead please use CEF Integration:',
}
);

export const GENERATION_ERROR_TRANSLATION: Record<
GenerationErrorCode,
string | ((attributes: GenerationErrorAttributes) => string)
Expand All @@ -211,6 +218,11 @@ export const GENERATION_ERROR_TRANSLATION: Record<
defaultMessage: 'Unsupported log format in the samples.',
}
),
[GenerationErrorCode.CEF_ERROR]: i18n.translate('xpack.integrationAssistant.errors.cefError', {
// This is a default error message if the linking does not work.
defaultMessage:
'CEF format detected. Please decode the CEF logs into JSON format using filebeat decode_cef processor.',
}),
[GenerationErrorCode.UNPARSEABLE_CSV_DATA]: (attributes) => {
if (
attributes.underlyingMessages !== undefined &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import type { State } from '../../state';
import * as i18n from './translations';
import { useTelemetry } from '../../../telemetry';
import type { AIConnector, IntegrationSettings } from '../../types';
import type { ErrorMessageWithLink } from '../../../../../../common/api/generation_error';
import { GenerationErrorCode } from '../../../../../../common/constants';

export type OnComplete = (result: State['result']) => void;
export const ProgressOrder = ['analyzeLogs', 'ecs', 'categorization', 'related'] as const;
Expand All @@ -48,12 +50,23 @@ interface RunGenerationProps {

// If the result is classified as a generation error, produce an error message
// as defined in the i18n file. Otherwise, return undefined.
function generationErrorMessage(body: unknown | undefined): string | undefined {
function generationErrorMessage(
body: unknown | undefined
): string | ErrorMessageWithLink | undefined {
if (!isGenerationErrorBody(body)) {
return;
}

const errorCode = body.attributes.errorCode;
if (errorCode === GenerationErrorCode.CEF_ERROR) {
if (body.attributes.errorMessageWithLink !== undefined) {
return {
link: body.attributes.errorMessageWithLink.link,
errorMessage: i18n.DECODE_CEF_LINK,
linkText: body.attributes.errorMessageWithLink.linkText,
};
}
}
const translation = i18n.GENERATION_ERROR_TRANSLATION[errorCode];
return typeof translation === 'function' ? translation(body.attributes) : translation;
}
Expand All @@ -72,7 +85,7 @@ export const useGeneration = ({
const { reportGenerationComplete } = useTelemetry();
const { http, notifications } = useKibana().services;
const [progress, setProgress] = useState<ProgressItem>();
const [error, setError] = useState<null | string>(null);
const [error, setError] = useState<null | string | ErrorMessageWithLink>(null);
const [isRequesting, setIsRequesting] = useState<boolean>(true);

useEffect(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ Follow these steps to do this:
b. If there is no csv header then set "header: false" and try to find good names for the columns in the "columns" array by looking into the values of data in those columns. For each column, if you are unable to find good name candidate for it then output an empty string, like in the example.
* 'structured': If the log samples have structured message body with key-value pairs then classify it as "name: structured". Look for a flat list of key-value pairs, often separated by some delimiters. Consider variations in formatting, such as quotes around values ("key=value", key="value"), special characters in keys or values, or escape sequences.
* 'unstructured': If the log samples have unstructured body like a free-form text then classify it as "name: unstructured".
* 'cef': If the log samples have Common Event Format (CEF) then classify it as "name: cef".
* 'unsupported': If you cannot put the format into any of the above categories then classify it with "name: unsupported".
2. Header: for structured and unstructured format:
- if the samples have any or all of priority, timestamp, loglevel, hostname, ipAddress, messageId in the beginning information then set "header: true".
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { KibanaResponseFactory } from '@kbn/core/server';
import {
GenerationErrorAttributes,
GenerationErrorBody,
} from '../../../common/api/generation_error';
import { ErrorThatHandlesItsOwnResponse } from './types';
import { GenerationErrorCode } from '../../../common/constants';

export class CefError extends Error implements ErrorThatHandlesItsOwnResponse {
private readonly errorCode: GenerationErrorCode = GenerationErrorCode.CEF_ERROR;
attributes: GenerationErrorAttributes;

constructor(message: string) {
super(message);
this.attributes = {
errorCode: this.errorCode,
errorMessageWithLink: {
linkText: 'cef-integration',
link: 'https://www.elastic.co/docs/current/integrations/cef',
errorMessage: '', // Will be set using translation in the UI.
},
};
}

public sendResponse(res: KibanaResponseFactory) {
const body: GenerationErrorBody = {
message: this.errorCode,
attributes: this.attributes,
};
return res.customError({
statusCode: 501,
body,
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { withAvailability } from './with_availability';
import { isErrorThatHandlesItsOwnResponse, UnsupportedLogFormatError } from '../lib/errors';
import { handleCustomErrors } from './routes_util';
import { GenerationErrorCode } from '../../common/constants';
import { CefError } from '../lib/errors/cef_error';

export function registerAnalyzeLogsRoutes(
router: IRouter<IntegrationAssistantRouteHandlerContext>
Expand Down Expand Up @@ -102,9 +103,16 @@ export function registerAnalyzeLogsRoutes(
.withConfig({ runName: 'Log Format' })
.invoke(logFormatParameters, options);
const graphLogFormat = graphResults.results.samplesFormat.name;
if (graphLogFormat === 'unsupported') {
throw new UnsupportedLogFormatError(GenerationErrorCode.UNSUPPORTED_LOG_SAMPLES_FORMAT);

switch (graphLogFormat) {
case 'unsupported':
throw new UnsupportedLogFormatError(
GenerationErrorCode.UNSUPPORTED_LOG_SAMPLES_FORMAT
);
case 'cef':
throw new CefError(GenerationErrorCode.CEF_ERROR);
}

return res.ok({ body: AnalyzeLogsResponse.parse(graphResults) });
} catch (err) {
try {
Expand Down

0 comments on commit a1cb4c2

Please sign in to comment.