mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 01:38:56 -04:00
[7.3] [SIEM] Fixes infinite loop when machine learning's create job API returns an error (#42228) (#42466)
## Summary Fixes infinite loop when machine learning create job returns an error https://github.com/elastic/ingest-dev/issues/616 This now will show an error toaster pop up which acts as a circuit breaker and does not continuously hit the back end if you have create job errors such as this one: <img width="791" alt="Screen Shot 2019-07-29 at 11 22 39 PM" src="https://user-images.githubusercontent.com/1151048/62103608-293a5400-b25a-11e9-9a9d-a5af42f7e128.png"> ### Checklist Use ~~strikethroughs~~ to remove checklist items you don't feel are applicable to this PR. ~~- [ ] This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility)~~ - [x] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md) ~~- [ ] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials~~ - [x] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios ~~- [ ] This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist)~~ ### For maintainers ~~- [ ] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~~ - [x] This includes a feature addition or change that requires a release note and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)
This commit is contained in:
parent
db2d3141c5
commit
390683329a
5 changed files with 306 additions and 7 deletions
|
@ -14,7 +14,9 @@ import {
|
|||
throwIfErrorAttached,
|
||||
isMlStartJobError,
|
||||
ToasterErrors,
|
||||
throwIfErrorAttachedToSetup,
|
||||
} from './throw_if_not_ok';
|
||||
import { SetupMlResponse } from '../../ml_popover/types';
|
||||
|
||||
describe('throw_if_not_ok', () => {
|
||||
afterEach(() => {
|
||||
|
@ -242,4 +244,249 @@ describe('throw_if_not_ok', () => {
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('#throwIfErrorAttachedToSetup', () => {
|
||||
test('It throws an error if setupJob has multiple errors', async () => {
|
||||
const json: SetupMlResponse = {
|
||||
jobs: [
|
||||
{
|
||||
id: 'siem-api-suspicious_login_activity_ecs',
|
||||
success: false,
|
||||
error: {
|
||||
msg:
|
||||
'[status_exception] This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index',
|
||||
path: '/_ml/anomaly_detectors/siem-api-suspicious_login_activity_ecs',
|
||||
query: {},
|
||||
body:
|
||||
'{"job_type":"anomaly_detector","description":"SIEM Auditbeat: Detect unusually high number of authentication attempts (beta)","groups":["siem"],"analysis_config":{"bucket_span":"15m","detectors":[{"detector_description":"high number of authentication attempts","function":"high_non_zero_count","partition_field_name":"host.name"}],"influencers":["host.name","user.name","source.ip"]},"analysis_limits":{"model_memory_limit":"256mb"},"data_description":{"time_field":"@timestamp","time_format":"epoch_ms"},"custom_settings":{"created_by":"ml-module-siem-auditbeat","custom_urls":[{"url_name":"IP Address Details","url_value":"siem#/ml-network/ip/$source.ip$?_g=()&kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"}]}}',
|
||||
statusCode: 400,
|
||||
response:
|
||||
'{"error":{"root_cause":[{"type":"status_exception","reason":"This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index"}],"type":"status_exception","reason":"This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index","caused_by":{"type":"illegal_argument_exception","reason":"mapper [multi_bucket_impact] of different type, current_type [keyword], merged_type [double]"}},"status":400}',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'siem-api-rare_process_linux_ecs',
|
||||
success: false,
|
||||
error: {
|
||||
msg:
|
||||
'[status_exception] This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index',
|
||||
path: '/_ml/anomaly_detectors/siem-api-rare_process_linux_ecs',
|
||||
query: {},
|
||||
body:
|
||||
'{"job_type":"anomaly_detector","description":"SIEM Auditbeat: Detect unusually rare processes on Linux (beta)","groups":["siem"],"analysis_config":{"bucket_span":"15m","detectors":[{"detector_description":"rare process executions on Linux","function":"rare","by_field_name":"process.name","partition_field_name":"host.name"}],"influencers":["host.name","process.name","user.name"]},"analysis_limits":{"model_memory_limit":"256mb"},"data_description":{"time_field":"@timestamp","time_format":"epoch_ms"},"custom_settings":{"created_by":"ml-module-siem-auditbeat","custom_urls":[{"url_name":"Host Details by process name","url_value":"siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:(expression:\'process.name%20:%20%22$process.name$%22\',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"},{"url_name":"Host Details by user name","url_value":"siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:(expression:\'user.name%20:%20%22$user.name$%22\',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"},{"url_name":"Hosts Overview by process name","url_value":"siem#/ml-hosts?_g=()&kqlQuery=(filterQuery:(expression:\'process.name%20:%20%22$process.name$%22\',kind:kuery),queryLocation:hosts.page,type:page)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"},{"url_name":"Hosts Overview by user name","url_value":"siem#/ml-hosts?_g=()&kqlQuery=(filterQuery:(expression:\'user.name%20:%20%22$user.name$%22\',kind:kuery),queryLocation:hosts.page,type:page)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"}]}}',
|
||||
statusCode: 400,
|
||||
response:
|
||||
'{"error":{"root_cause":[{"type":"status_exception","reason":"This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index"}],"type":"status_exception","reason":"This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index","caused_by":{"type":"illegal_argument_exception","reason":"mapper [multi_bucket_impact] of different type, current_type [keyword], merged_type [double]"}},"status":400}',
|
||||
},
|
||||
},
|
||||
],
|
||||
datafeeds: [
|
||||
{
|
||||
id: 'datafeed-siem-api-rare_process_linux_ecs',
|
||||
success: false,
|
||||
started: false,
|
||||
error: {
|
||||
msg:
|
||||
"[resource_not_found_exception] No known job with id 'siem-api-rare_process_linux_ecs'",
|
||||
path: '/_ml/datafeeds/datafeed-siem-api-rare_process_linux_ecs',
|
||||
query: {},
|
||||
body:
|
||||
'{"job_id":"siem-api-rare_process_linux_ecs","indexes":["auditbeat-*"],"query":{"bool":{"filter":[{"terms":{"event.action":["process_started","executed"]}}]}}}',
|
||||
statusCode: 404,
|
||||
response:
|
||||
'{"error":{"root_cause":[{"type":"resource_not_found_exception","reason":"No known job with id \'siem-api-rare_process_linux_ecs\'"}],"type":"resource_not_found_exception","reason":"No known job with id \'siem-api-rare_process_linux_ecs\'"},"status":404}',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'datafeed-siem-api-suspicious_login_activity_ecs',
|
||||
success: false,
|
||||
started: false,
|
||||
error: {
|
||||
msg:
|
||||
"[resource_not_found_exception] No known job with id 'siem-api-suspicious_login_activity_ecs'",
|
||||
path: '/_ml/datafeeds/datafeed-siem-api-suspicious_login_activity_ecs',
|
||||
query: {},
|
||||
body:
|
||||
'{"job_id":"siem-api-suspicious_login_activity_ecs","indexes":["auditbeat-*"],"query":{"bool":{"filter":{"term":{"event.category":"authentication"}}}}}',
|
||||
statusCode: 404,
|
||||
response:
|
||||
'{"error":{"root_cause":[{"type":"resource_not_found_exception","reason":"No known job with id \'siem-api-suspicious_login_activity_ecs\'"}],"type":"resource_not_found_exception","reason":"No known job with id \'siem-api-suspicious_login_activity_ecs\'"},"status":404}',
|
||||
},
|
||||
},
|
||||
],
|
||||
kibana: {},
|
||||
};
|
||||
try {
|
||||
throwIfErrorAttachedToSetup(json);
|
||||
} catch (error) {
|
||||
expect(error.messages).toEqual([
|
||||
'[status_exception] This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index',
|
||||
'{\n "error": {\n "root_cause": [\n {\n "type": "status_exception",\n "reason": "This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index"\n }\n ],\n "type": "status_exception",\n "reason": "This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index",\n "caused_by": {\n "type": "illegal_argument_exception",\n "reason": "mapper [multi_bucket_impact] of different type, current_type [keyword], merged_type [double]"\n }\n },\n "status": 400\n}',
|
||||
'Status Code: 400',
|
||||
'[status_exception] This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index',
|
||||
'{\n "error": {\n "root_cause": [\n {\n "type": "status_exception",\n "reason": "This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index"\n }\n ],\n "type": "status_exception",\n "reason": "This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index",\n "caused_by": {\n "type": "illegal_argument_exception",\n "reason": "mapper [multi_bucket_impact] of different type, current_type [keyword], merged_type [double]"\n }\n },\n "status": 400\n}',
|
||||
'Status Code: 400',
|
||||
"[resource_not_found_exception] No known job with id 'siem-api-rare_process_linux_ecs'",
|
||||
'{\n "error": {\n "root_cause": [\n {\n "type": "resource_not_found_exception",\n "reason": "No known job with id \'siem-api-rare_process_linux_ecs\'"\n }\n ],\n "type": "resource_not_found_exception",\n "reason": "No known job with id \'siem-api-rare_process_linux_ecs\'"\n },\n "status": 404\n}',
|
||||
'Status Code: 404',
|
||||
"[resource_not_found_exception] No known job with id 'siem-api-suspicious_login_activity_ecs'",
|
||||
'{\n "error": {\n "root_cause": [\n {\n "type": "resource_not_found_exception",\n "reason": "No known job with id \'siem-api-suspicious_login_activity_ecs\'"\n }\n ],\n "type": "resource_not_found_exception",\n "reason": "No known job with id \'siem-api-suspicious_login_activity_ecs\'"\n },\n "status": 404\n}',
|
||||
'Status Code: 404',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test('It throws an error if only jobs has errors', async () => {
|
||||
const json: SetupMlResponse = {
|
||||
jobs: [
|
||||
{
|
||||
id: 'siem-api-suspicious_login_activity_ecs',
|
||||
success: false,
|
||||
error: {
|
||||
msg:
|
||||
'[status_exception] This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index',
|
||||
path: '/_ml/anomaly_detectors/siem-api-suspicious_login_activity_ecs',
|
||||
query: {},
|
||||
body:
|
||||
'{"job_type":"anomaly_detector","description":"SIEM Auditbeat: Detect unusually high number of authentication attempts (beta)","groups":["siem"],"analysis_config":{"bucket_span":"15m","detectors":[{"detector_description":"high number of authentication attempts","function":"high_non_zero_count","partition_field_name":"host.name"}],"influencers":["host.name","user.name","source.ip"]},"analysis_limits":{"model_memory_limit":"256mb"},"data_description":{"time_field":"@timestamp","time_format":"epoch_ms"},"custom_settings":{"created_by":"ml-module-siem-auditbeat","custom_urls":[{"url_name":"IP Address Details","url_value":"siem#/ml-network/ip/$source.ip$?_g=()&kqlQuery=(filterQuery:!n,queryLocation:network.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"}]}}',
|
||||
statusCode: 400,
|
||||
response:
|
||||
'{"error":{"root_cause":[{"type":"status_exception","reason":"This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index"}],"type":"status_exception","reason":"This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index","caused_by":{"type":"illegal_argument_exception","reason":"mapper [multi_bucket_impact] of different type, current_type [keyword], merged_type [double]"}},"status":400}',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'siem-api-rare_process_linux_ecs',
|
||||
success: false,
|
||||
error: {
|
||||
msg:
|
||||
'[status_exception] This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index',
|
||||
path: '/_ml/anomaly_detectors/siem-api-rare_process_linux_ecs',
|
||||
query: {},
|
||||
body:
|
||||
'{"job_type":"anomaly_detector","description":"SIEM Auditbeat: Detect unusually rare processes on Linux (beta)","groups":["siem"],"analysis_config":{"bucket_span":"15m","detectors":[{"detector_description":"rare process executions on Linux","function":"rare","by_field_name":"process.name","partition_field_name":"host.name"}],"influencers":["host.name","process.name","user.name"]},"analysis_limits":{"model_memory_limit":"256mb"},"data_description":{"time_field":"@timestamp","time_format":"epoch_ms"},"custom_settings":{"created_by":"ml-module-siem-auditbeat","custom_urls":[{"url_name":"Host Details by process name","url_value":"siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:(expression:\'process.name%20:%20%22$process.name$%22\',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"},{"url_name":"Host Details by user name","url_value":"siem#/ml-hosts/$host.name$?_g=()&kqlQuery=(filterQuery:(expression:\'user.name%20:%20%22$user.name$%22\',kind:kuery),queryLocation:hosts.details,type:details)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"},{"url_name":"Hosts Overview by process name","url_value":"siem#/ml-hosts?_g=()&kqlQuery=(filterQuery:(expression:\'process.name%20:%20%22$process.name$%22\',kind:kuery),queryLocation:hosts.page,type:page)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"},{"url_name":"Hosts Overview by user name","url_value":"siem#/ml-hosts?_g=()&kqlQuery=(filterQuery:(expression:\'user.name%20:%20%22$user.name$%22\',kind:kuery),queryLocation:hosts.page,type:page)&timerange=(global:(linkTo:!(timeline),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')),timeline:(linkTo:!(global),timerange:(from:\'$earliest$\',kind:absolute,to:\'$latest$\')))"}]}}',
|
||||
statusCode: 400,
|
||||
response:
|
||||
'{"error":{"root_cause":[{"type":"status_exception","reason":"This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index"}],"type":"status_exception","reason":"This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index","caused_by":{"type":"illegal_argument_exception","reason":"mapper [multi_bucket_impact] of different type, current_type [keyword], merged_type [double]"}},"status":400}',
|
||||
},
|
||||
},
|
||||
],
|
||||
datafeeds: [
|
||||
{
|
||||
id: 'datafeed-siem-api-rare_process_linux_ecs',
|
||||
success: false,
|
||||
started: true,
|
||||
},
|
||||
{
|
||||
id: 'datafeed-siem-api-suspicious_login_activity_ecs',
|
||||
success: false,
|
||||
started: true,
|
||||
},
|
||||
],
|
||||
kibana: {},
|
||||
};
|
||||
try {
|
||||
throwIfErrorAttachedToSetup(json);
|
||||
} catch (error) {
|
||||
expect(error.messages).toEqual([
|
||||
'[status_exception] This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index',
|
||||
'{\n "error": {\n "root_cause": [\n {\n "type": "status_exception",\n "reason": "This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index"\n }\n ],\n "type": "status_exception",\n "reason": "This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index",\n "caused_by": {\n "type": "illegal_argument_exception",\n "reason": "mapper [multi_bucket_impact] of different type, current_type [keyword], merged_type [double]"\n }\n },\n "status": 400\n}',
|
||||
'Status Code: 400',
|
||||
'[status_exception] This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index',
|
||||
'{\n "error": {\n "root_cause": [\n {\n "type": "status_exception",\n "reason": "This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index"\n }\n ],\n "type": "status_exception",\n "reason": "This job would cause a mapping clash with existing field [multi_bucket_impact] - avoid the clash by assigning a dedicated results index",\n "caused_by": {\n "type": "illegal_argument_exception",\n "reason": "mapper [multi_bucket_impact] of different type, current_type [keyword], merged_type [double]"\n }\n },\n "status": 400\n}',
|
||||
'Status Code: 400',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test('It throws an error if only dataFeeds has errors', async () => {
|
||||
const json: SetupMlResponse = {
|
||||
jobs: [
|
||||
{
|
||||
id: 'siem-api-suspicious_login_activity_ecs',
|
||||
success: false,
|
||||
},
|
||||
{
|
||||
id: 'siem-api-rare_process_linux_ecs',
|
||||
success: false,
|
||||
},
|
||||
],
|
||||
datafeeds: [
|
||||
{
|
||||
id: 'datafeed-siem-api-rare_process_linux_ecs',
|
||||
success: false,
|
||||
started: false,
|
||||
error: {
|
||||
msg:
|
||||
"[resource_not_found_exception] No known job with id 'siem-api-rare_process_linux_ecs'",
|
||||
path: '/_ml/datafeeds/datafeed-siem-api-rare_process_linux_ecs',
|
||||
query: {},
|
||||
body:
|
||||
'{"job_id":"siem-api-rare_process_linux_ecs","indexes":["auditbeat-*"],"query":{"bool":{"filter":[{"terms":{"event.action":["process_started","executed"]}}]}}}',
|
||||
statusCode: 404,
|
||||
response:
|
||||
'{"error":{"root_cause":[{"type":"resource_not_found_exception","reason":"No known job with id \'siem-api-rare_process_linux_ecs\'"}],"type":"resource_not_found_exception","reason":"No known job with id \'siem-api-rare_process_linux_ecs\'"},"status":404}',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'datafeed-siem-api-suspicious_login_activity_ecs',
|
||||
success: false,
|
||||
started: false,
|
||||
error: {
|
||||
msg:
|
||||
"[resource_not_found_exception] No known job with id 'siem-api-suspicious_login_activity_ecs'",
|
||||
path: '/_ml/datafeeds/datafeed-siem-api-suspicious_login_activity_ecs',
|
||||
query: {},
|
||||
body:
|
||||
'{"job_id":"siem-api-suspicious_login_activity_ecs","indexes":["auditbeat-*"],"query":{"bool":{"filter":{"term":{"event.category":"authentication"}}}}}',
|
||||
statusCode: 404,
|
||||
response:
|
||||
'{"error":{"root_cause":[{"type":"resource_not_found_exception","reason":"No known job with id \'siem-api-suspicious_login_activity_ecs\'"}],"type":"resource_not_found_exception","reason":"No known job with id \'siem-api-suspicious_login_activity_ecs\'"},"status":404}',
|
||||
},
|
||||
},
|
||||
],
|
||||
kibana: {},
|
||||
};
|
||||
try {
|
||||
throwIfErrorAttachedToSetup(json);
|
||||
} catch (error) {
|
||||
expect(error.messages).toEqual([
|
||||
"[resource_not_found_exception] No known job with id 'siem-api-rare_process_linux_ecs'",
|
||||
'{\n "error": {\n "root_cause": [\n {\n "type": "resource_not_found_exception",\n "reason": "No known job with id \'siem-api-rare_process_linux_ecs\'"\n }\n ],\n "type": "resource_not_found_exception",\n "reason": "No known job with id \'siem-api-rare_process_linux_ecs\'"\n },\n "status": 404\n}',
|
||||
'Status Code: 404',
|
||||
"[resource_not_found_exception] No known job with id 'siem-api-suspicious_login_activity_ecs'",
|
||||
'{\n "error": {\n "root_cause": [\n {\n "type": "resource_not_found_exception",\n "reason": "No known job with id \'siem-api-suspicious_login_activity_ecs\'"\n }\n ],\n "type": "resource_not_found_exception",\n "reason": "No known job with id \'siem-api-suspicious_login_activity_ecs\'"\n },\n "status": 404\n}',
|
||||
'Status Code: 404',
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
||||
test('It does not throw an error if it has no errors', async () => {
|
||||
const json: SetupMlResponse = {
|
||||
jobs: [
|
||||
{
|
||||
id: 'siem-api-suspicious_login_activity_ecs',
|
||||
success: false,
|
||||
},
|
||||
{
|
||||
id: 'siem-api-rare_process_linux_ecs',
|
||||
success: false,
|
||||
},
|
||||
],
|
||||
datafeeds: [
|
||||
{
|
||||
id: 'datafeed-siem-api-rare_process_linux_ecs',
|
||||
success: false,
|
||||
started: false,
|
||||
},
|
||||
{
|
||||
id: 'datafeed-siem-api-suspicious_login_activity_ecs',
|
||||
success: false,
|
||||
started: false,
|
||||
},
|
||||
],
|
||||
kibana: {},
|
||||
};
|
||||
expect(() => throwIfErrorAttachedToSetup(json)).not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
import { has } from 'lodash/fp';
|
||||
|
||||
import * as i18n from './translations';
|
||||
import { MlError } from '../types';
|
||||
import { SetupMlResponse } from '../../ml_popover/types';
|
||||
|
||||
export interface MessageBody {
|
||||
error?: string;
|
||||
|
@ -15,11 +17,7 @@ export interface MessageBody {
|
|||
}
|
||||
|
||||
export interface MlStartJobError {
|
||||
error: {
|
||||
msg: string;
|
||||
response: string;
|
||||
statusCode: number;
|
||||
};
|
||||
error: MlError;
|
||||
started: boolean;
|
||||
}
|
||||
|
||||
|
@ -69,6 +67,41 @@ export const tryParseResponse = (response: string): string => {
|
|||
}
|
||||
};
|
||||
|
||||
export const throwIfErrorAttachedToSetup = (setupResponse: SetupMlResponse): void => {
|
||||
const jobErrors = setupResponse.jobs.reduce<string[]>((accum, job) => {
|
||||
if (job.error != null) {
|
||||
accum = [
|
||||
...accum,
|
||||
job.error.msg,
|
||||
tryParseResponse(job.error.response),
|
||||
`${i18n.STATUS_CODE} ${job.error.statusCode}`,
|
||||
];
|
||||
return accum;
|
||||
} else {
|
||||
return accum;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const dataFeedErrors = setupResponse.datafeeds.reduce<string[]>((accum, dataFeed) => {
|
||||
if (dataFeed.error != null) {
|
||||
accum = [
|
||||
...accum,
|
||||
dataFeed.error.msg,
|
||||
tryParseResponse(dataFeed.error.response),
|
||||
`${i18n.STATUS_CODE} ${dataFeed.error.statusCode}`,
|
||||
];
|
||||
return accum;
|
||||
} else {
|
||||
return accum;
|
||||
}
|
||||
}, []);
|
||||
|
||||
const errors = [...jobErrors, ...dataFeedErrors];
|
||||
if (errors.length > 0) {
|
||||
throw new ToasterErrors(errors);
|
||||
}
|
||||
};
|
||||
|
||||
export const throwIfErrorAttached = (
|
||||
json: Record<string, Record<string, unknown>>,
|
||||
dataFeedIds: string[]
|
||||
|
|
|
@ -135,3 +135,12 @@ const sourceOrDestination = ['source.ip', 'destination.ip'];
|
|||
|
||||
export const isDestinationOrSource = (value: string | null): value is DestinationOrSource =>
|
||||
value != null && sourceOrDestination.includes(value);
|
||||
|
||||
export interface MlError {
|
||||
msg: string;
|
||||
response: string;
|
||||
statusCode: number;
|
||||
path?: string;
|
||||
query?: {};
|
||||
body?: string;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,11 @@ import {
|
|||
StartDatafeedResponse,
|
||||
StopDatafeedResponse,
|
||||
} from './types';
|
||||
import { throwIfNotOk, throwIfErrorAttached } from '../ml/api/throw_if_not_ok';
|
||||
import {
|
||||
throwIfNotOk,
|
||||
throwIfErrorAttached,
|
||||
throwIfErrorAttachedToSetup,
|
||||
} from '../ml/api/throw_if_not_ok';
|
||||
|
||||
const emptyIndexPattern: string = '';
|
||||
|
||||
|
@ -73,7 +77,9 @@ export const setupMlJob = async ({
|
|||
},
|
||||
});
|
||||
await throwIfNotOk(response);
|
||||
return await response.json();
|
||||
const json = await response.json();
|
||||
throwIfErrorAttachedToSetup(json);
|
||||
return json;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { MlError } from '../ml/types';
|
||||
|
||||
export interface Group {
|
||||
id: string;
|
||||
jobIds: string[];
|
||||
|
@ -44,12 +46,14 @@ export interface Job {
|
|||
export interface SetupMlResponseJob {
|
||||
id: string;
|
||||
success: boolean;
|
||||
error?: MlError;
|
||||
}
|
||||
|
||||
export interface SetupMlResponseDatafeed {
|
||||
id: string;
|
||||
success: boolean;
|
||||
started: boolean;
|
||||
error?: MlError;
|
||||
}
|
||||
|
||||
export interface SetupMlResponse {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue