From 4d3644030afce4a3463b0d390e32293337382889 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Mon, 25 Oct 2021 10:34:36 +0300 Subject: [PATCH 01/66] [Connectors] Check connector's responses (#115797) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../builtin_action_types/jira/service.test.ts | 918 ++++++++++-------- .../builtin_action_types/jira/service.ts | 66 +- .../lib/axios_utils.test.ts | 88 +- .../builtin_action_types/lib/axios_utils.ts | 68 ++ .../resilient/service.test.ts | 388 +++++--- .../builtin_action_types/resilient/service.ts | 32 +- .../swimlane/service.test.ts | 64 +- .../builtin_action_types/swimlane/service.ts | 13 +- .../server/jira_simulation.ts | 19 +- 9 files changed, 1053 insertions(+), 603 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts index 2300143925b1ef..1254d86e99066a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts @@ -8,7 +8,7 @@ import axios from 'axios'; import { createExternalService } from './service'; -import * as utils from '../lib/axios_utils'; +import { request, createAxiosResponse } from '../lib/axios_utils'; import { ExternalService } from './types'; import { Logger } from '../../../../../../src/core/server'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; @@ -29,10 +29,10 @@ jest.mock('../lib/axios_utils', () => { }); axios.create = jest.fn(() => axios); -const requestMock = utils.request as jest.Mock; +const requestMock = request as jest.Mock; const configurationUtilities = actionsConfigMock.create(); -const issueTypesResponse = { +const issueTypesResponse = createAxiosResponse({ data: { projects: [ { @@ -49,9 +49,9 @@ const issueTypesResponse = { }, ], }, -}; +}); -const fieldsResponse = { +const fieldsResponse = createAxiosResponse({ data: { projects: [ { @@ -98,7 +98,7 @@ const fieldsResponse = { }, ], }, -}; +}); const issueResponse = { id: '10267', @@ -108,6 +108,31 @@ const issueResponse = { const issuesResponse = [issueResponse]; +const mockNewAPI = () => + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, + }, + }) + ); + +const mockOldAPI = () => + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, + }, + }) + ); + describe('Jira service', () => { let service: ExternalService; @@ -183,18 +208,34 @@ describe('Jira service', () => { }); describe('getIncident', () => { + const axiosRes = { + data: { + id: '1', + key: 'CK-1', + fields: { + summary: 'title', + description: 'description', + created: '2021-10-20T19:41:02.754+0300', + updated: '2021-10-20T19:41:02.754+0300', + }, + }, + }; + test('it returns the incident correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { id: '1', key: 'CK-1', fields: { summary: 'title', description: 'description' } }, - })); + requestMock.mockImplementation(() => createAxiosResponse(axiosRes)); const res = await service.getIncident('1'); - expect(res).toEqual({ id: '1', key: 'CK-1', summary: 'title', description: 'description' }); + expect(res).toEqual({ + id: '1', + key: 'CK-1', + summary: 'title', + description: 'description', + created: '2021-10-20T19:41:02.754+0300', + updated: '2021-10-20T19:41:02.754+0300', + }); }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { id: '1', key: 'CK-1' }, - })); + requestMock.mockImplementation(() => createAxiosResponse(axiosRes)); await service.getIncident('1'); expect(requestMock).toHaveBeenCalledWith({ @@ -215,9 +256,38 @@ describe('Jira service', () => { '[Action][Jira]: Unable to get incident with id 1. Error: An error has occurred Reason: Required field' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ ...axiosRes, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getIncident('1')).rejects.toThrow( + '[Action][Jira]: Unable to get incident with id 1. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json Reason: unknown: errorResponse was null' + ); + }); + + test('it should throw if the required attributes are not there', async () => { + requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); + + await expect(service.getIncident('1')).rejects.toThrow( + '[Action][Jira]: Unable to get incident with id 1. Error: Response is missing at least one of the expected fields: id,key Reason: unknown: errorResponse was null' + ); + }); }); describe('createIncident', () => { + const incident = { + incident: { + summary: 'title', + description: 'desc', + labels: [], + issueType: '10006', + priority: 'High', + parent: 'RJ-107', + }, + }; + test('it creates the incident correctly', async () => { /* The response from Jira when creating an issue contains only the key and the id. The function makes the following calls when creating an issue: @@ -225,24 +295,19 @@ describe('Jira service', () => { 2. Create the issue. 3. Get the created issue with all the necessary fields. */ - requestMock.mockImplementationOnce(() => ({ - data: { id: '1', key: 'CK-1', fields: { summary: 'title', description: 'description' } }, - })); + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { id: '1', key: 'CK-1', fields: { summary: 'title', description: 'description' } }, + }) + ); - requestMock.mockImplementationOnce(() => ({ - data: { id: '1', key: 'CK-1', fields: { created: '2020-04-27T10:59:46.202Z' } }, - })); + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { id: '1', key: 'CK-1', fields: { created: '2020-04-27T10:59:46.202Z' } }, + }) + ); - const res = await service.createIncident({ - incident: { - summary: 'title', - description: 'desc', - labels: [], - issueType: '10006', - priority: 'High', - parent: null, - }, - }); + const res = await service.createIncident(incident); expect(res).toEqual({ title: 'CK-1', @@ -260,24 +325,30 @@ describe('Jira service', () => { 3. Get the created issue with all the necessary fields. */ // getIssueType mocks - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, }, - }, - })); + }) + ); // getIssueType mocks requestMock.mockImplementationOnce(() => issueTypesResponse); - requestMock.mockImplementationOnce(() => ({ - data: { id: '1', key: 'CK-1', fields: { summary: 'title', description: 'description' } }, - })); + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { id: '1', key: 'CK-1', fields: { summary: 'title', description: 'description' } }, + }) + ); - requestMock.mockImplementationOnce(() => ({ - data: { id: '1', key: 'CK-1', fields: { created: '2020-04-27T10:59:46.202Z' } }, - })); + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { id: '1', key: 'CK-1', fields: { created: '2020-04-27T10:59:46.202Z' } }, + }) + ); const res = await service.createIncident({ incident: { @@ -317,25 +388,31 @@ describe('Jira service', () => { }); test('removes newline characters and trialing spaces from summary', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + capabilities: { + navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', + }, }, - }, - })); + }) + ); // getIssueType mocks requestMock.mockImplementationOnce(() => issueTypesResponse); // getIssueType mocks - requestMock.mockImplementationOnce(() => ({ - data: { id: '1', key: 'CK-1', fields: { summary: 'test', description: 'description' } }, - })); + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { id: '1', key: 'CK-1', fields: { summary: 'test', description: 'description' } }, + }) + ); - requestMock.mockImplementationOnce(() => ({ - data: { id: '1', key: 'CK-1', fields: { created: '2020-04-27T10:59:46.202Z' } }, - })); + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { id: '1', key: 'CK-1', fields: { created: '2020-04-27T10:59:46.202Z' } }, + }) + ); await service.createIncident({ incident: { @@ -368,24 +445,17 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - key: 'CK-1', - fields: { created: '2020-04-27T10:59:46.202Z' }, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + key: 'CK-1', + fields: { created: '2020-04-27T10:59:46.202Z' }, + }, + }) + ); - await service.createIncident({ - incident: { - summary: 'title', - description: 'desc', - labels: [], - issueType: '10006', - priority: 'High', - parent: 'RJ-107', - }, - }); + await service.createIncident(incident); expect(requestMock).toHaveBeenCalledWith({ axios, @@ -414,44 +484,55 @@ describe('Jira service', () => { throw error; }); - await expect( - service.createIncident({ - incident: { - summary: 'title', - description: 'desc', - labels: [], - issueType: '10006', - priority: 'High', - parent: null, - }, - }) - ).rejects.toThrow( + await expect(service.createIncident(incident)).rejects.toThrow( '[Action][Jira]: Unable to create incident. Error: An error has occurred. Reason: Required field' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.createIncident(incident)).rejects.toThrow( + '[Action][Jira]: Unable to create incident. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); + + test('it should throw if the required attributes are not there', async () => { + requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); + + await expect(service.createIncident(incident)).rejects.toThrow( + '[Action][Jira]: Unable to create incident. Error: Response is missing at least one of the expected fields: id. Reason: unknown: errorResponse was null' + ); + }); }); describe('updateIncident', () => { + const incident = { + incidentId: '1', + incident: { + summary: 'title', + description: 'desc', + labels: [], + issueType: '10006', + priority: 'High', + parent: 'RJ-107', + }, + }; + test('it updates the incident correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - key: 'CK-1', - fields: { updated: '2020-04-27T10:59:46.202Z' }, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + key: 'CK-1', + fields: { updated: '2020-04-27T10:59:46.202Z' }, + }, + }) + ); - const res = await service.updateIncident({ - incidentId: '1', - incident: { - summary: 'title', - description: 'desc', - labels: [], - issueType: '10006', - priority: 'High', - parent: null, - }, - }); + const res = await service.updateIncident(incident); expect(res).toEqual({ title: 'CK-1', @@ -462,25 +543,17 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - key: 'CK-1', - fields: { updated: '2020-04-27T10:59:46.202Z' }, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + key: 'CK-1', + fields: { updated: '2020-04-27T10:59:46.202Z' }, + }, + }) + ); - await service.updateIncident({ - incidentId: '1', - incident: { - summary: 'title', - description: 'desc', - labels: [], - issueType: '10006', - priority: 'High', - parent: 'RJ-107', - }, - }); + await service.updateIncident(incident); expect(requestMock).toHaveBeenCalledWith({ axios, @@ -509,41 +582,42 @@ describe('Jira service', () => { throw error; }); - await expect( - service.updateIncident({ - incidentId: '1', - incident: { - summary: 'title', - description: 'desc', - labels: [], - issueType: '10006', - priority: 'High', - parent: null, - }, - }) - ).rejects.toThrow( + await expect(service.updateIncident(incident)).rejects.toThrow( '[Action][Jira]: Unable to update incident with id 1. Error: An error has occurred. Reason: Required field' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.updateIncident(incident)).rejects.toThrow( + '[Action][Jira]: Unable to update incident with id 1. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); }); describe('createComment', () => { + const commentReq = { + incidentId: '1', + comment: { + comment: 'comment', + commentId: 'comment-1', + }, + }; test('it creates the comment correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - key: 'CK-1', - created: '2020-04-27T10:59:46.202Z', - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + key: 'CK-1', + created: '2020-04-27T10:59:46.202Z', + }, + }) + ); - const res = await service.createComment({ - incidentId: '1', - comment: { - comment: 'comment', - commentId: 'comment-1', - }, - }); + const res = await service.createComment(commentReq); expect(res).toEqual({ commentId: 'comment-1', @@ -553,21 +627,17 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - key: 'CK-1', - created: '2020-04-27T10:59:46.202Z', - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + key: 'CK-1', + created: '2020-04-27T10:59:46.202Z', + }, + }) + ); - await service.createComment({ - incidentId: '1', - comment: { - comment: 'comment', - commentId: 'comment-1', - }, - }); + await service.createComment(commentReq); expect(requestMock).toHaveBeenCalledWith({ axios, @@ -586,29 +656,33 @@ describe('Jira service', () => { throw error; }); - await expect( - service.createComment({ - incidentId: '1', - comment: { - comment: 'comment', - commentId: 'comment-1', - }, - }) - ).rejects.toThrow( + await expect(service.createComment(commentReq)).rejects.toThrow( '[Action][Jira]: Unable to create comment at incident with id 1. Error: An error has occurred. Reason: Required field' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.createComment(commentReq)).rejects.toThrow( + '[Action][Jira]: Unable to create comment at incident with id 1. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); + + test('it should throw if the required attributes are not there', async () => { + requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); + + await expect(service.createComment(commentReq)).rejects.toThrow( + '[Action][Jira]: Unable to create comment at incident with id 1. Error: Response is missing at least one of the expected fields: id,created. Reason: unknown: errorResponse was null' + ); + }); }); describe('getCapabilities', () => { test('it should return the capabilities', async () => { - requestMock.mockImplementation(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', - }, - }, - })); + mockOldAPI(); const res = await service.getCapabilities(); expect(res).toEqual({ capabilities: { @@ -618,13 +692,7 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', - }, - }, - })); + mockOldAPI(); await service.getCapabilities(); @@ -649,16 +717,34 @@ describe('Jira service', () => { ); }); - test('it should throw an auth error', async () => { + test('it should return unknown if the error is a string', async () => { requestMock.mockImplementation(() => { const error = new Error('An error has occurred'); - // @ts-ignore this can happen! + // @ts-ignore error.response = { data: 'Unauthorized' }; throw error; }); await expect(service.getCapabilities()).rejects.toThrow( - '[Action][Jira]: Unable to get capabilities. Error: An error has occurred. Reason: Unauthorized' + '[Action][Jira]: Unable to get capabilities. Error: An error has occurred. Reason: unknown: errorResponse.errors was null' + ); + }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getCapabilities()).rejects.toThrow( + '[Action][Jira]: Unable to get capabilities. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); + + test('it should throw if the required attributes are not there', async () => { + requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); + + await expect(service.getCapabilities()).rejects.toThrow( + '[Action][Jira]: Unable to get capabilities. Error: Response is missing at least one of the expected fields: capabilities. Reason: unknown: errorResponse was null' ); }); }); @@ -666,13 +752,7 @@ describe('Jira service', () => { describe('getIssueTypes', () => { describe('Old API', () => { test('it should return the issue types', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', - }, - }, - })); + mockOldAPI(); requestMock.mockImplementationOnce(() => issueTypesResponse); @@ -691,13 +771,7 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', - }, - }, - })); + mockOldAPI(); requestMock.mockImplementationOnce(() => issueTypesResponse); @@ -713,13 +787,7 @@ describe('Jira service', () => { }); test('it should throw an error', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', - }, - }, - })); + mockOldAPI(); requestMock.mockImplementation(() => { const error: ResponseError = new Error('An error has occurred'); @@ -731,25 +799,30 @@ describe('Jira service', () => { '[Action][Jira]: Unable to get issue types. Error: An error has occurred. Reason: Could not get issue types' ); }); + + test('it should throw if the request is not a JSON', async () => { + mockOldAPI(); + + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getIssueTypes()).rejects.toThrow( + '[Action][Jira]: Unable to get issue types. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); }); describe('New API', () => { test('it should return the issue types', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', - }, - }, - })); + mockNewAPI(); - requestMock.mockImplementationOnce(() => ({ - data: { - values: issueTypesResponse.data.projects[0].issuetypes, - }, - })); + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + values: issueTypesResponse.data.projects[0].issuetypes, + }, + }) + ); const res = await service.getIssueTypes(); @@ -766,22 +839,15 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', - }, - }, - })); + mockNewAPI(); - requestMock.mockImplementationOnce(() => ({ - data: { - values: issueTypesResponse.data.projects[0].issuetypes, - }, - })); + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + values: issueTypesResponse.data.projects[0].issuetypes, + }, + }) + ); await service.getIssueTypes(); @@ -795,16 +861,7 @@ describe('Jira service', () => { }); test('it should throw an error', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', - }, - }, - })); + mockNewAPI(); requestMock.mockImplementation(() => { const error: ResponseError = new Error('An error has occurred'); @@ -816,19 +873,25 @@ describe('Jira service', () => { '[Action][Jira]: Unable to get issue types. Error: An error has occurred. Reason: Could not get issue types' ); }); + + test('it should throw if the request is not a JSON', async () => { + mockNewAPI(); + + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getIssueTypes()).rejects.toThrow( + '[Action][Jira]: Unable to get issue types. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); }); }); describe('getFieldsByIssueType', () => { describe('Old API', () => { test('it should return the fields', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', - }, - }, - })); + mockOldAPI(); requestMock.mockImplementationOnce(() => fieldsResponse); @@ -857,13 +920,7 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', - }, - }, - })); + mockOldAPI(); requestMock.mockImplementationOnce(() => fieldsResponse); @@ -879,13 +936,7 @@ describe('Jira service', () => { }); test('it should throw an error', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - navigation: 'https://siem-kibana.atlassian.net/rest/capabilities/navigation', - }, - }, - })); + mockOldAPI(); requestMock.mockImplementation(() => { const error: ResponseError = new Error('An error has occurred'); @@ -897,43 +948,48 @@ describe('Jira service', () => { '[Action][Jira]: Unable to get fields. Error: An error has occurred. Reason: Could not get fields' ); }); + + test('it should throw if the request is not a JSON', async () => { + mockOldAPI(); + + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getFieldsByIssueType('10006')).rejects.toThrow( + '[Action][Jira]: Unable to get fields. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); }); describe('New API', () => { test('it should return the fields', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', - }, - }, - })); - - requestMock.mockImplementationOnce(() => ({ - data: { - values: [ - { required: true, schema: { type: 'string' }, fieldId: 'summary' }, - { - required: false, - schema: { type: 'string' }, - fieldId: 'priority', - allowedValues: [ - { + mockNewAPI(); + + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + values: [ + { required: true, schema: { type: 'string' }, fieldId: 'summary' }, + { + required: false, + schema: { type: 'string' }, + fieldId: 'priority', + allowedValues: [ + { + name: 'Medium', + id: '3', + }, + ], + defaultValue: { name: 'Medium', id: '3', }, - ], - defaultValue: { - name: 'Medium', - id: '3', }, - }, - ], - }, - })); + ], + }, + }) + ); const res = await service.getFieldsByIssueType('10006'); @@ -954,39 +1010,32 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', - }, - }, - })); - - requestMock.mockImplementationOnce(() => ({ - data: { - values: [ - { required: true, schema: { type: 'string' }, fieldId: 'summary' }, - { - required: true, - schema: { type: 'string' }, - fieldId: 'priority', - allowedValues: [ - { + mockNewAPI(); + + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + values: [ + { required: true, schema: { type: 'string' }, fieldId: 'summary' }, + { + required: true, + schema: { type: 'string' }, + fieldId: 'priority', + allowedValues: [ + { + name: 'Medium', + id: '3', + }, + ], + defaultValue: { name: 'Medium', id: '3', }, - ], - defaultValue: { - name: 'Medium', - id: '3', }, - }, - ], - }, - })); + ], + }, + }) + ); await service.getFieldsByIssueType('10006'); @@ -1000,16 +1049,7 @@ describe('Jira service', () => { }); test('it should throw an error', async () => { - requestMock.mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', - }, - }, - })); + mockNewAPI(); requestMock.mockImplementation(() => { const error: ResponseError = new Error('An error has occurred'); @@ -1021,16 +1061,30 @@ describe('Jira service', () => { '[Action][Jira]: Unable to get fields. Error: An error has occurred. Reason: Could not get issue types' ); }); + + test('it should throw if the request is not a JSON', async () => { + mockNewAPI(); + + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getFieldsByIssueType('10006')).rejects.toThrow( + '[Action][Jira]: Unable to get fields. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); }); }); describe('getIssues', () => { test('it should return the issues', async () => { - requestMock.mockImplementation(() => ({ - data: { - issues: issuesResponse, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + issues: issuesResponse, + }, + }) + ); const res = await service.getIssues('Test title'); @@ -1044,11 +1098,13 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { - issues: issuesResponse, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + issues: issuesResponse, + }, + }) + ); await service.getIssues('Test title'); expect(requestMock).toHaveBeenLastCalledWith({ @@ -1071,13 +1127,25 @@ describe('Jira service', () => { '[Action][Jira]: Unable to get issues. Error: An error has occurred. Reason: Could not get issue types' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getIssues('Test title')).rejects.toThrow( + '[Action][Jira]: Unable to get issues. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); }); describe('getIssue', () => { test('it should return a single issue', async () => { - requestMock.mockImplementation(() => ({ - data: issueResponse, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: issueResponse, + }) + ); const res = await service.getIssue('RJ-107'); @@ -1089,11 +1157,13 @@ describe('Jira service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { - issues: issuesResponse, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + issues: issuesResponse, + }, + }) + ); await service.getIssue('RJ-107'); expect(requestMock).toHaveBeenLastCalledWith({ @@ -1116,81 +1186,105 @@ describe('Jira service', () => { '[Action][Jira]: Unable to get issue with id RJ-107. Error: An error has occurred. Reason: Could not get issue types' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getIssue('Test title')).rejects.toThrow( + '[Action][Jira]: Unable to get issue with id Test title. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown: errorResponse was null' + ); + }); }); describe('getFields', () => { const callMocks = () => { requestMock - .mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + .mockImplementationOnce(() => + createAxiosResponse({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, }, - }, - })) - .mockImplementationOnce(() => ({ - data: { - values: issueTypesResponse.data.projects[0].issuetypes, - }, - })) - .mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }) + ) + .mockImplementationOnce(() => + createAxiosResponse({ + data: { + values: issueTypesResponse.data.projects[0].issuetypes, }, - }, - })) - .mockImplementationOnce(() => ({ - data: { - capabilities: { - 'list-project-issuetypes': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', - 'list-issuetype-fields': - 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }) + ) + .mockImplementationOnce(() => + createAxiosResponse({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, }, - }, - })) - .mockImplementationOnce(() => ({ - data: { - values: [ - { required: true, schema: { type: 'string' }, fieldId: 'summary' }, - { required: true, schema: { type: 'string' }, fieldId: 'description' }, - { - required: false, - schema: { type: 'string' }, - fieldId: 'priority', - allowedValues: [ - { + }) + ) + .mockImplementationOnce(() => + createAxiosResponse({ + data: { + capabilities: { + 'list-project-issuetypes': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-project-issuetypes', + 'list-issuetype-fields': + 'https://siem-kibana.atlassian.net/rest/capabilities/list-issuetype-fields', + }, + }, + }) + ) + .mockImplementationOnce(() => + createAxiosResponse({ + data: { + values: [ + { required: true, schema: { type: 'string' }, fieldId: 'summary' }, + { required: true, schema: { type: 'string' }, fieldId: 'description' }, + { + required: false, + schema: { type: 'string' }, + fieldId: 'priority', + allowedValues: [ + { + name: 'Medium', + id: '3', + }, + ], + defaultValue: { name: 'Medium', id: '3', }, - ], - defaultValue: { - name: 'Medium', - id: '3', }, - }, - ], - }, - })) - .mockImplementationOnce(() => ({ - data: { - values: [ - { required: true, schema: { type: 'string' }, fieldId: 'summary' }, - { required: true, schema: { type: 'string' }, fieldId: 'description' }, - ], - }, - })); + ], + }, + }) + ) + .mockImplementationOnce(() => + createAxiosResponse({ + data: { + values: [ + { required: true, schema: { type: 'string' }, fieldId: 'summary' }, + { required: true, schema: { type: 'string' }, fieldId: 'description' }, + ], + }, + }) + ); }; + beforeEach(() => { jest.resetAllMocks(); }); + test('it should call request with correct arguments', async () => { callMocks(); await service.getFields(); diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts index be0240e705a653..a3262a526e2f4f 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts @@ -27,7 +27,7 @@ import { } from './types'; import * as i18n from './translations'; -import { request, getErrorMessage } from '../lib/axios_utils'; +import { request, getErrorMessage, throwIfResponseIsNotValid } from '../lib/axios_utils'; import { ActionsConfigurationUtilities } from '../../actions_config'; const VERSION = '2'; @@ -111,19 +111,15 @@ export const createExternalService = ( .filter((item) => !isEmpty(item)) .join(', '); - const createErrorMessage = (errorResponse: ResponseError | string | null | undefined): string => { + const createErrorMessage = (errorResponse: ResponseError | null | undefined): string => { if (errorResponse == null) { - return ''; - } - if (typeof errorResponse === 'string') { - // Jira error.response.data can be string!! - return errorResponse; + return 'unknown: errorResponse was null'; } const { errorMessages, errors } = errorResponse; if (errors == null) { - return ''; + return 'unknown: errorResponse.errors was null'; } if (Array.isArray(errorMessages) && errorMessages.length > 0) { @@ -185,9 +181,14 @@ export const createExternalService = ( configurationUtilities, }); - const { fields, ...rest } = res.data; + throwIfResponseIsNotValid({ + res, + requiredAttributesToBeInTheResponse: ['id', 'key'], + }); + + const { fields, id: incidentId, key } = res.data; - return { ...rest, ...fields }; + return { id: incidentId, key, created: fields.created, updated: fields.updated, ...fields }; } catch (error) { throw new Error( getErrorMessage( @@ -234,6 +235,11 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + requiredAttributesToBeInTheResponse: ['id'], + }); + const updatedIncident = await getIncident(res.data.id); return { @@ -266,7 +272,7 @@ export const createExternalService = ( const fields = createFields(projectKey, incidentWithoutNullValues); try { - await request({ + const res = await request({ axios: axiosInstance, method: 'put', url: `${incidentUrl}/${incidentId}`, @@ -275,6 +281,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + const updatedIncident = await getIncident(incidentId as string); return { @@ -309,6 +319,11 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + requiredAttributesToBeInTheResponse: ['id', 'created'], + }); + return { commentId: comment.commentId, externalCommentId: res.data.id, @@ -336,6 +351,11 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + requiredAttributesToBeInTheResponse: ['capabilities'], + }); + return { ...res.data }; } catch (error) { throw new Error( @@ -362,6 +382,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + const issueTypes = res.data.projects[0]?.issuetypes ?? []; return normalizeIssueTypes(issueTypes); } else { @@ -373,6 +397,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + const issueTypes = res.data.values; return normalizeIssueTypes(issueTypes); } @@ -401,6 +429,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + const fields = res.data.projects[0]?.issuetypes[0]?.fields || {}; return normalizeFields(fields); } else { @@ -412,6 +444,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + const fields = res.data.values.reduce( (acc: { [x: string]: {} }, value: { fieldId: string }) => ({ ...acc, @@ -471,6 +507,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + return normalizeSearchResults(res.data?.issues ?? []); } catch (error) { throw new Error( @@ -495,6 +535,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + return normalizeIssue(res.data ?? {}); } catch (error) { throw new Error( diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts index 287f74c6bc703d..d0177e0e5a8a2f 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts @@ -10,7 +10,14 @@ import { Agent as HttpsAgent } from 'https'; import HttpProxyAgent from 'http-proxy-agent'; import { HttpsProxyAgent } from 'https-proxy-agent'; import { Logger } from '../../../../../../src/core/server'; -import { addTimeZoneToDate, request, patch, getErrorMessage } from './axios_utils'; +import { + addTimeZoneToDate, + request, + patch, + getErrorMessage, + throwIfResponseIsNotValid, + createAxiosResponse, +} from './axios_utils'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; import { actionsConfigMock } from '../../actions_config.mock'; import { getCustomAgents } from './get_custom_agents'; @@ -292,3 +299,82 @@ describe('getErrorMessage', () => { expect(msg).toBe('[Action][My connector name]: An error has occurred'); }); }); + +describe('throwIfResponseIsNotValid', () => { + const res = createAxiosResponse({ + headers: { ['content-type']: 'application/json' }, + data: { incident: { id: '1' } }, + }); + + test('it does NOT throw if the request is valid', () => { + expect(() => throwIfResponseIsNotValid({ res })).not.toThrow(); + }); + + test('it does throw if the content-type is not json', () => { + expect(() => + throwIfResponseIsNotValid({ + res: { ...res, headers: { ['content-type']: 'text/html' } }, + }) + ).toThrow( + 'Unsupported content type: text/html in GET https://example.com. Supported content types: application/json' + ); + }); + + test('it does throw if the content-type is undefined', () => { + expect(() => + throwIfResponseIsNotValid({ + res: { ...res, headers: {} }, + }) + ).toThrow( + 'Unsupported content type: undefined in GET https://example.com. Supported content types: application/json' + ); + }); + + test('it does throw if the data is not an object or array', () => { + expect(() => + throwIfResponseIsNotValid({ + res: { ...res, data: 'string' }, + }) + ).toThrow('Response is not a valid JSON'); + }); + + test('it does NOT throw if the data is an array', () => { + expect(() => + throwIfResponseIsNotValid({ + res: { ...res, data: ['test'] }, + }) + ).not.toThrow(); + }); + + test.each(['', [], {}])('it does NOT throw if the data is %p', (data) => { + expect(() => + throwIfResponseIsNotValid({ + res: { ...res, data }, + }) + ).not.toThrow(); + }); + + test('it does throw if the required attribute is not in the response', () => { + expect(() => + throwIfResponseIsNotValid({ res, requiredAttributesToBeInTheResponse: ['not-exist'] }) + ).toThrow('Response is missing at least one of the expected fields: not-exist'); + }); + + test('it does throw if the required attribute are defined and the data is an array', () => { + expect(() => + throwIfResponseIsNotValid({ + res: { ...res, data: ['test'] }, + requiredAttributesToBeInTheResponse: ['not-exist'], + }) + ).toThrow('Response is missing at least one of the expected fields: not-exist'); + }); + + test('it does NOT throw if the value of the required attribute is null', () => { + expect(() => + throwIfResponseIsNotValid({ + res: { ...res, data: { id: null } }, + requiredAttributesToBeInTheResponse: ['id'], + }) + ).not.toThrow(); + }); +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts index af353e1d1da5aa..43c9d276e65747 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { isObjectLike, isEmpty } from 'lodash'; import { AxiosInstance, Method, AxiosResponse, AxiosBasicCredentials } from 'axios'; import { Logger } from '../../../../../../src/core/server'; import { getCustomAgents } from './get_custom_agents'; @@ -76,3 +77,70 @@ export const addTimeZoneToDate = (date: string, timezone = 'GMT'): string => { export const getErrorMessage = (connector: string, msg: string) => { return `[Action][${connector}]: ${msg}`; }; + +export const throwIfResponseIsNotValid = ({ + res, + requiredAttributesToBeInTheResponse = [], +}: { + res: AxiosResponse; + requiredAttributesToBeInTheResponse?: string[]; +}) => { + const requiredContentType = 'application/json'; + const contentType = res.headers['content-type'] ?? 'undefined'; + const data = res.data; + + /** + * Check that the content-type of the response is application/json. + * Then includes is added because the header can be application/json;charset=UTF-8. + */ + if (!contentType.includes(requiredContentType)) { + throw new Error( + `Unsupported content type: ${contentType} in ${res.config.method} ${res.config.url}. Supported content types: ${requiredContentType}` + ); + } + + /** + * Check if the response is a JS object (data != null && typeof data === 'object') + * in case the content type is application/json but for some reason the response is not. + * Empty responses (204 No content) are ignored because the typeof data will be string and + * isObjectLike will fail. + * Axios converts automatically JSON to JS objects. + */ + if (!isEmpty(data) && !isObjectLike(data)) { + throw new Error('Response is not a valid JSON'); + } + + if (requiredAttributesToBeInTheResponse.length > 0) { + const requiredAttributesError = new Error( + `Response is missing at least one of the expected fields: ${requiredAttributesToBeInTheResponse.join( + ',' + )}` + ); + + /** + * If the response is an array and requiredAttributesToBeInTheResponse + * are not empty then we thrown an error assuming that the consumer + * expects an object response and not an array. + */ + + if (Array.isArray(data)) { + throw requiredAttributesError; + } + + requiredAttributesToBeInTheResponse.forEach((attr) => { + // Check only for undefined as null is a valid value + if (data[attr] === undefined) { + throw requiredAttributesError; + } + }); + } +}; + +export const createAxiosResponse = (res: Partial): AxiosResponse => ({ + data: {}, + status: 200, + statusText: 'OK', + headers: { ['content-type']: 'application/json' }, + config: { method: 'GET', url: 'https://example.com' }, + ...res, +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/resilient/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/resilient/service.test.ts index ba555433862258..094b8150850df1 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/resilient/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/resilient/service.test.ts @@ -8,7 +8,7 @@ import axios from 'axios'; import { createExternalService, getValueTextContent, formatUpdateRequest } from './service'; -import * as utils from '../lib/axios_utils'; +import { request, createAxiosResponse } from '../lib/axios_utils'; import { ExternalService } from './types'; import { Logger } from '../../../../../../src/core/server'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; @@ -27,7 +27,7 @@ jest.mock('../lib/axios_utils', () => { }); axios.create = jest.fn(() => axios); -const requestMock = utils.request as jest.Mock; +const requestMock = request as jest.Mock; const now = Date.now; const TIMESTAMP = 1589391874472; const configurationUtilities = actionsConfigMock.create(); @@ -38,44 +38,50 @@ const configurationUtilities = actionsConfigMock.create(); // b) Update the incident // c) Get the updated incident const mockIncidentUpdate = (withUpdateError = false) => { - requestMock.mockImplementationOnce(() => ({ - data: { - id: '1', - name: 'title', - description: { - format: 'html', - content: 'description', + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + id: '1', + name: 'title', + description: { + format: 'html', + content: 'description', + }, + incident_type_ids: [1001, 16, 12], + severity_code: 6, }, - incident_type_ids: [1001, 16, 12], - severity_code: 6, - }, - })); + }) + ); if (withUpdateError) { requestMock.mockImplementationOnce(() => { throw new Error('An error has occurred'); }); } else { - requestMock.mockImplementationOnce(() => ({ + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + success: true, + id: '1', + inc_last_modified_date: 1589391874472, + }, + }) + ); + } + + requestMock.mockImplementationOnce(() => + createAxiosResponse({ data: { - success: true, id: '1', + name: 'title_updated', + description: { + format: 'html', + content: 'desc_updated', + }, inc_last_modified_date: 1589391874472, }, - })); - } - - requestMock.mockImplementationOnce(() => ({ - data: { - id: '1', - name: 'title_updated', - description: { - format: 'html', - content: 'desc_updated', - }, - inc_last_modified_date: 1589391874472, - }, - })); + }) + ); }; describe('IBM Resilient service', () => { @@ -207,24 +213,28 @@ describe('IBM Resilient service', () => { describe('getIncident', () => { test('it returns the incident correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - name: '1', - description: { - format: 'html', - content: 'description', + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + name: '1', + description: { + format: 'html', + content: 'description', + }, }, - }, - })); + }) + ); const res = await service.getIncident('1'); expect(res).toEqual({ id: '1', name: '1', description: 'description' }); }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { id: '1' }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { id: '1' }, + }) + ); await service.getIncident('1'); expect(requestMock).toHaveBeenCalledWith({ @@ -246,28 +256,42 @@ describe('IBM Resilient service', () => { 'Unable to get incident with id 1. Error: An error has occurred' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getIncident('1')).rejects.toThrow( + '[Action][IBM Resilient]: Unable to get incident with id 1. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json.' + ); + }); }); describe('createIncident', () => { + const incident = { + incident: { + name: 'title', + description: 'desc', + incidentTypes: [1001], + severityCode: 6, + }, + }; + test('it creates the incident correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - name: 'title', - description: 'description', - discovered_date: 1589391874472, - create_date: 1589391874472, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + name: 'title', + description: 'description', + discovered_date: 1589391874472, + create_date: 1589391874472, + }, + }) + ); - const res = await service.createIncident({ - incident: { - name: 'title', - description: 'desc', - incidentTypes: [1001], - severityCode: 6, - }, - }); + const res = await service.createIncident(incident); expect(res).toEqual({ title: '1', @@ -278,24 +302,19 @@ describe('IBM Resilient service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - name: 'title', - description: 'description', - discovered_date: 1589391874472, - create_date: 1589391874472, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + name: 'title', + description: 'description', + discovered_date: 1589391874472, + create_date: 1589391874472, + }, + }) + ); - await service.createIncident({ - incident: { - name: 'title', - description: 'desc', - incidentTypes: [1001], - severityCode: 6, - }, - }); + await service.createIncident(incident); expect(requestMock).toHaveBeenCalledWith({ axios, @@ -334,20 +353,39 @@ describe('IBM Resilient service', () => { '[Action][IBM Resilient]: Unable to create incident. Error: An error has occurred' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.createIncident(incident)).rejects.toThrow( + '[Action][IBM Resilient]: Unable to create incident. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json.' + ); + }); + + test('it should throw if the required attributes are not there', async () => { + requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); + + await expect(service.createIncident(incident)).rejects.toThrow( + '[Action][IBM Resilient]: Unable to create incident. Error: Response is missing at least one of the expected fields: id,create_date.' + ); + }); }); describe('updateIncident', () => { + const req = { + incidentId: '1', + incident: { + name: 'title', + description: 'desc', + incidentTypes: [1001], + severityCode: 6, + }, + }; test('it updates the incident correctly', async () => { mockIncidentUpdate(); - const res = await service.updateIncident({ - incidentId: '1', - incident: { - name: 'title', - description: 'desc', - incidentTypes: [1001], - severityCode: 6, - }, - }); + const res = await service.updateIncident(req); expect(res).toEqual({ title: '1', @@ -430,38 +468,59 @@ describe('IBM Resilient service', () => { test('it should throw an error', async () => { mockIncidentUpdate(true); - await expect( - service.updateIncident({ - incidentId: '1', - incident: { + await expect(service.updateIncident(req)).rejects.toThrow( + '[Action][IBM Resilient]: Unable to update incident with id 1. Error: An error has occurred' + ); + }); + + test('it should throw if the request is not a JSON', async () => { + // get incident request + requestMock.mockImplementationOnce(() => + createAxiosResponse({ + data: { + id: '1', name: 'title', - description: 'desc', - incidentTypes: [1001], - severityCode: 5, + description: { + format: 'html', + content: 'description', + }, + incident_type_ids: [1001, 16, 12], + severity_code: 6, }, }) - ).rejects.toThrow( - '[Action][IBM Resilient]: Unable to update incident with id 1. Error: An error has occurred' + ); + + // update incident request + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.updateIncident(req)).rejects.toThrow( + '[Action][IBM Resilient]: Unable to update incident with id 1. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json' ); }); }); describe('createComment', () => { + const req = { + incidentId: '1', + comment: { + comment: 'comment', + commentId: 'comment-1', + }, + }; + test('it creates the comment correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - create_date: 1589391874472, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + create_date: 1589391874472, + }, + }) + ); - const res = await service.createComment({ - incidentId: '1', - comment: { - comment: 'comment', - commentId: 'comment-1', - }, - }); + const res = await service.createComment(req); expect(res).toEqual({ commentId: 'comment-1', @@ -471,20 +530,16 @@ describe('IBM Resilient service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: { - id: '1', - create_date: 1589391874472, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + id: '1', + create_date: 1589391874472, + }, + }) + ); - await service.createComment({ - incidentId: '1', - comment: { - comment: 'comment', - commentId: 'comment-1', - }, - }); + await service.createComment(req); expect(requestMock).toHaveBeenCalledWith({ axios, @@ -506,27 +561,31 @@ describe('IBM Resilient service', () => { throw new Error('An error has occurred'); }); - await expect( - service.createComment({ - incidentId: '1', - comment: { - comment: 'comment', - commentId: 'comment-1', - }, - }) - ).rejects.toThrow( + await expect(service.createComment(req)).rejects.toThrow( '[Action][IBM Resilient]: Unable to create comment at incident with id 1. Error: An error has occurred' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.createComment(req)).rejects.toThrow( + '[Action][IBM Resilient]: Unable to create comment at incident with id 1. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json.' + ); + }); }); describe('getIncidentTypes', () => { test('it creates the incident correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { - values: incidentTypes, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + values: incidentTypes, + }, + }) + ); const res = await service.getIncidentTypes(); @@ -545,15 +604,27 @@ describe('IBM Resilient service', () => { '[Action][IBM Resilient]: Unable to get incident types. Error: An error has occurred.' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getIncidentTypes()).rejects.toThrow( + '[Action][IBM Resilient]: Unable to get incident types. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json.' + ); + }); }); describe('getSeverity', () => { test('it creates the incident correctly', async () => { - requestMock.mockImplementation(() => ({ - data: { - values: severity, - }, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: { + values: severity, + }, + }) + ); const res = await service.getSeverity(); @@ -578,17 +649,29 @@ describe('IBM Resilient service', () => { throw new Error('An error has occurred'); }); - await expect(service.getIncidentTypes()).rejects.toThrow( - '[Action][IBM Resilient]: Unable to get incident types. Error: An error has occurred.' + await expect(service.getSeverity()).rejects.toThrow( + '[Action][IBM Resilient]: Unable to get severity. Error: An error has occurred.' + ); + }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getSeverity()).rejects.toThrow( + '[Action][IBM Resilient]: Unable to get severity. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json.' ); }); }); describe('getFields', () => { test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data: resilientFields, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: resilientFields, + }) + ); await service.getFields(); expect(requestMock).toHaveBeenCalledWith({ @@ -598,10 +681,13 @@ describe('IBM Resilient service', () => { url: 'https://resilient.elastic.co/rest/orgs/201/types/incident/fields', }); }); + test('it returns common fields correctly', async () => { - requestMock.mockImplementation(() => ({ - data: resilientFields, - })); + requestMock.mockImplementation(() => + createAxiosResponse({ + data: resilientFields, + }) + ); const res = await service.getFields(); expect(res).toEqual(resilientFields); }); @@ -614,5 +700,15 @@ describe('IBM Resilient service', () => { 'Unable to get fields. Error: An error has occurred' ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data: { id: '1' }, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.getFields()).rejects.toThrow( + '[Action][IBM Resilient]: Unable to get fields. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json.' + ); + }); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/resilient/service.ts b/x-pack/plugins/actions/server/builtin_action_types/resilient/service.ts index 2f385315e43923..a469c631fac37a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/resilient/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/resilient/service.ts @@ -24,7 +24,7 @@ import { } from './types'; import * as i18n from './translations'; -import { getErrorMessage, request } from '../lib/axios_utils'; +import { getErrorMessage, request, throwIfResponseIsNotValid } from '../lib/axios_utils'; import { ActionsConfigurationUtilities } from '../../actions_config'; const VIEW_INCIDENT_URL = `#incidents`; @@ -134,6 +134,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + return { ...res.data, description: res.data.description?.content ?? '' }; } catch (error) { throw new Error( @@ -182,6 +186,11 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + requiredAttributesToBeInTheResponse: ['id', 'create_date'], + }); + return { title: `${res.data.id}`, id: `${res.data.id}`, @@ -212,6 +221,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + if (!res.data.success) { throw new Error(res.data.message); } @@ -245,6 +258,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + return { commentId: comment.commentId, externalCommentId: res.data.id, @@ -270,6 +287,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + const incidentTypes = res.data?.values ?? []; return incidentTypes.map((type: { value: string; label: string }) => ({ id: type.value, @@ -292,6 +313,10 @@ export const createExternalService = ( configurationUtilities, }); + throwIfResponseIsNotValid({ + res, + }); + const incidentTypes = res.data?.values ?? []; return incidentTypes.map((type: { value: string; label: string }) => ({ id: type.value, @@ -312,6 +337,11 @@ export const createExternalService = ( logger, configurationUtilities, }); + + throwIfResponseIsNotValid({ + res, + }); + return res.data ?? []; } catch (error) { throw new Error(getErrorMessage(i18n.NAME, `Unable to get fields. Error: ${error.message}.`)); diff --git a/x-pack/plugins/actions/server/builtin_action_types/swimlane/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/swimlane/service.test.ts index 7b3f310a99e0e7..21bc4894c5717b 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/swimlane/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/swimlane/service.test.ts @@ -10,7 +10,7 @@ import axios from 'axios'; import { loggingSystemMock } from '../../../../../../src/core/server/mocks'; import { Logger } from '../../../../../../src/core/server'; import { actionsConfigMock } from '../../actions_config.mock'; -import * as utils from '../lib/axios_utils'; +import { request, createAxiosResponse } from '../lib/axios_utils'; import { createExternalService } from './service'; import { mappings } from './mocks'; import { ExternalService } from './types'; @@ -27,7 +27,7 @@ jest.mock('../lib/axios_utils', () => { }); axios.create = jest.fn(() => axios); -const requestMock = utils.request as jest.Mock; +const requestMock = request as jest.Mock; const configurationUtilities = actionsConfigMock.create(); describe('Swimlane Service', () => { @@ -152,9 +152,7 @@ describe('Swimlane Service', () => { }; test('it creates a record correctly', async () => { - requestMock.mockImplementation(() => ({ - data, - })); + requestMock.mockImplementation(() => createAxiosResponse({ data })); const res = await service.createRecord({ incident, @@ -169,9 +167,7 @@ describe('Swimlane Service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data, - })); + requestMock.mockImplementation(() => createAxiosResponse({ data })); await service.createRecord({ incident, @@ -207,6 +203,24 @@ describe('Swimlane Service', () => { `[Action][Swimlane]: Unable to create record in application with id ${config.appId}. Status: 500. Error: An error has occurred. Reason: unknown` ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.createRecord({ incident })).rejects.toThrow( + `[Action][Swimlane]: Unable to create record in application with id ${config.appId}. Status: 500. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown` + ); + }); + + test('it should throw if the required attributes are not there', async () => { + requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); + + await expect(service.createRecord({ incident })).rejects.toThrow( + `[Action][Swimlane]: Unable to create record in application with id ${config.appId}. Status: 500. Error: Response is missing at least one of the expected fields: id,name,createdDate. Reason: unknown` + ); + }); }); describe('updateRecord', () => { @@ -218,9 +232,7 @@ describe('Swimlane Service', () => { const incidentId = '123'; test('it updates a record correctly', async () => { - requestMock.mockImplementation(() => ({ - data, - })); + requestMock.mockImplementation(() => createAxiosResponse({ data })); const res = await service.updateRecord({ incident, @@ -236,9 +248,7 @@ describe('Swimlane Service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data, - })); + requestMock.mockImplementation(() => createAxiosResponse({ data })); await service.updateRecord({ incident, @@ -276,6 +286,24 @@ describe('Swimlane Service', () => { `[Action][Swimlane]: Unable to update record in application with id ${config.appId}. Status: 500. Error: An error has occurred. Reason: unknown` ); }); + + test('it should throw if the request is not a JSON', async () => { + requestMock.mockImplementation(() => + createAxiosResponse({ data, headers: { ['content-type']: 'text/html' } }) + ); + + await expect(service.updateRecord({ incident, incidentId })).rejects.toThrow( + `[Action][Swimlane]: Unable to update record in application with id ${config.appId}. Status: 500. Error: Unsupported content type: text/html in GET https://example.com. Supported content types: application/json. Reason: unknown` + ); + }); + + test('it should throw if the required attributes are not there', async () => { + requestMock.mockImplementation(() => createAxiosResponse({ data: { notRequired: 'test' } })); + + await expect(service.updateRecord({ incident, incidentId })).rejects.toThrow( + `[Action][Swimlane]: Unable to update record in application with id ${config.appId}. Status: 500. Error: Response is missing at least one of the expected fields: id,name,modifiedDate. Reason: unknown` + ); + }); }); describe('createComment', () => { @@ -289,9 +317,7 @@ describe('Swimlane Service', () => { const createdDate = '2021-06-01T17:29:51.092Z'; test('it updates a record correctly', async () => { - requestMock.mockImplementation(() => ({ - data, - })); + requestMock.mockImplementation(() => createAxiosResponse({ data })); const res = await service.createComment({ comment, @@ -306,9 +332,7 @@ describe('Swimlane Service', () => { }); test('it should call request with correct arguments', async () => { - requestMock.mockImplementation(() => ({ - data, - })); + requestMock.mockImplementation(() => createAxiosResponse({ data })); await service.createComment({ comment, diff --git a/x-pack/plugins/actions/server/builtin_action_types/swimlane/service.ts b/x-pack/plugins/actions/server/builtin_action_types/swimlane/service.ts index f68d22121dbcc9..d917d7f5677bb8 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/swimlane/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/swimlane/service.ts @@ -9,7 +9,7 @@ import { Logger } from '@kbn/logging'; import axios from 'axios'; import { ActionsConfigurationUtilities } from '../../actions_config'; -import { getErrorMessage, request } from '../lib/axios_utils'; +import { getErrorMessage, request, throwIfResponseIsNotValid } from '../lib/axios_utils'; import { getBodyForEventAction } from './helpers'; import { CreateCommentParams, @@ -89,6 +89,12 @@ export const createExternalService = ( method: 'post', url: getPostRecordUrl(appId), }); + + throwIfResponseIsNotValid({ + res, + requiredAttributesToBeInTheResponse: ['id', 'name', 'createdDate'], + }); + return { id: res.data.id, title: res.data.name, @@ -124,6 +130,11 @@ export const createExternalService = ( url: getPostRecordIdUrl(appId, params.incidentId), }); + throwIfResponseIsNotValid({ + res, + requiredAttributesToBeInTheResponse: ['id', 'name', 'modifiedDate'], + }); + return { id: res.data.id, title: res.data.name, diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/jira_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/jira_simulation.ts index 26a9c1bcadf6eb..e9e6d6732327a1 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/jira_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/jira_simulation.ts @@ -30,7 +30,6 @@ export function initPlugin(router: IRouter, path: string) { return jsonResponse(res, 200, { id: '123', key: 'CK-1', - created: '2020-04-27T14:17:45.490Z', }); } ); @@ -48,12 +47,7 @@ export function initPlugin(router: IRouter, path: string) { req: KibanaRequest, res: KibanaResponseFactory ): Promise> { - return jsonResponse(res, 200, { - id: '123', - key: 'CK-1', - created: '2020-04-27T14:17:45.490Z', - updated: '2020-04-27T14:17:45.490Z', - }); + return jsonResponse(res, 204, {}); } ); @@ -73,10 +67,12 @@ export function initPlugin(router: IRouter, path: string) { return jsonResponse(res, 200, { id: '123', key: 'CK-1', - created: '2020-04-27T14:17:45.490Z', - updated: '2020-04-27T14:17:45.490Z', - summary: 'title', - description: 'description', + fields: { + created: '2020-04-27T14:17:45.490Z', + updated: '2020-04-27T14:17:45.490Z', + summary: 'title', + description: 'description', + }, }); } ); @@ -97,6 +93,7 @@ export function initPlugin(router: IRouter, path: string) { return jsonResponse(res, 200, { id: '123', created: '2020-04-27T14:17:45.490Z', + updated: '2020-04-27T14:17:45.490Z', }); } ); From 262d0cdafd9a2a85aab989ee9c7663bc74e597a9 Mon Sep 17 00:00:00 2001 From: Uladzislau Lasitsa Date: Mon, 25 Oct 2021 12:07:50 +0300 Subject: [PATCH 02/66] [TSVB] Error when selecting * for override index_pattern field on the string mode (#114450) * Add condition so that preselect first timefield from the list if we use * as index pattern * Add default timefield for string index pattern mode * Add comment for condition * Fix lint Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/lib/vis_data/get_interval_and_timefield.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.ts b/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.ts index b7a22abd825e05..7c17f003dfbab9 100644 --- a/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.ts +++ b/src/plugins/vis_types/timeseries/server/lib/vis_data/get_interval_and_timefield.ts @@ -24,10 +24,15 @@ export function getIntervalAndTimefield( { min, max, maxBuckets }: IntervalParams, series?: Series ) { - const timeField = + let timeField = (series?.override_index_pattern ? series.series_time_field : panel.time_field) || index.indexPattern?.timeFieldName; + // should use @timestamp as default timeField for es indeces if user doesn't provide timeField + if (!panel.use_kibana_indexes && !timeField) { + timeField = '@timestamp'; + } + if (panel.use_kibana_indexes) { validateField(timeField!, index); } From 6b5b06fc038c438ea850752d7255036913f4ebf7 Mon Sep 17 00:00:00 2001 From: Giorgos Bamparopoulos Date: Mon, 25 Oct 2021 10:24:00 +0100 Subject: [PATCH 03/66] Update APM linting dev doc with instructions about how to install the pre-commit hook and a link to the Kibana guide (#115924) --- x-pack/plugins/apm/dev_docs/linting.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/x-pack/plugins/apm/dev_docs/linting.md b/x-pack/plugins/apm/dev_docs/linting.md index edf3e813a88e98..3dbd7b5b27484a 100644 --- a/x-pack/plugins/apm/dev_docs/linting.md +++ b/x-pack/plugins/apm/dev_docs/linting.md @@ -19,3 +19,12 @@ yarn prettier "./x-pack/plugins/apm/**/*.{tsx,ts,js}" --write ``` node scripts/eslint.js x-pack/plugins/apm ``` + +## Install pre-commit hook (optional) +In case you want to run a couple of checks like linting or check the file casing of the files to commit, we provide a way to install a pre-commit hook. To configure it you just need to run the following: + +`node scripts/register_git_hook` + +After the script completes the pre-commit hook will be created within the file .git/hooks/pre-commit. If you choose to not install it, don’t worry, we still run a quick CI check to provide feedback earliest as we can about the same checks. + +More information about linting can be found in the [Kibana Guide](https://www.elastic.co/guide/en/kibana/current/kibana-linting.html). \ No newline at end of file From d66abdf25ede2d096a811f9179717366c1b934f5 Mon Sep 17 00:00:00 2001 From: Phillip Burch Date: Mon, 25 Oct 2021 04:39:43 -0500 Subject: [PATCH 04/66] Fix bug with popup not closing (#115954) --- .../application/pages/logstash/pipeline.tsx | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx b/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx index 1f56ea22839e2d..cf9b5628222f4a 100644 --- a/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/logstash/pipeline.tsx @@ -46,7 +46,7 @@ export const LogStashPipelinePage: React.FC = ({ clusters }) => cluster_uuid: clusterUuid, }) as any; const [data, setData] = useState({} as any); - const [detailVertexId, setDetailVertexId] = useState(null); + const [detailVertexId, setDetailVertexId] = useState(undefined); const { updateTotalItemCount } = useTable('logstash.pipelines'); const title = i18n.translate('xpack.monitoring.logstash.pipeline.routeTitle', { @@ -128,18 +128,19 @@ export const LogStashPipelinePage: React.FC = ({ clusters }) => const timeseriesTooltipXValueFormatter = (xValue: any) => moment(xValue).format(dateFormat); const { generate: generateBreadcrumbs } = useContext(BreadcrumbContainer.Context); - const onVertexChange = useCallback( - (vertex: any) => { - if (!vertex) { - setDetailVertexId(null); - } else { - setDetailVertexId(vertex.id); - } + const onVertexChange = useCallback((vertex: any) => { + if (!vertex) { + setDetailVertexId(null); + } else { + setDetailVertexId(vertex.id); + } + }, []); + useEffect(() => { + if (detailVertexId !== undefined) { getPageData(); - }, - [getPageData] - ); + } + }, [detailVertexId, getPageData]); const onChangePipelineHash = useCallback(() => { window.location.hash = getSafeForExternalLink( From ed99e2466adc0e8f97ab79abe134200d0ad8c44b Mon Sep 17 00:00:00 2001 From: Walter Rafelsberger Date: Mon, 25 Oct 2021 11:50:35 +0200 Subject: [PATCH 05/66] [ML] Fix legend text colors for Vega based charts in dark mode. (#115911) Fixes the legend text colors for Vega based charts in dark mode. --- .../scatterplot_matrix_vega_lite_spec.ts | 5 +++++ .../classification_exploration/evaluate_panel.tsx | 6 +++++- .../get_roc_curve_chart_vega_lite_spec.tsx | 14 +++++++++----- .../classification_creation.ts | 2 +- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix_vega_lite_spec.ts b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix_vega_lite_spec.ts index 7291f7bbfa8380..861b3727cea1ba 100644 --- a/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix_vega_lite_spec.ts +++ b/x-pack/plugins/ml/public/application/components/scatterplot_matrix/scatterplot_matrix_vega_lite_spec.ts @@ -107,6 +107,11 @@ export const getScatterplotMatrixVegaLiteSpec = ( labelColor: euiTheme.euiTextSubduedColor, titleColor: euiTheme.euiTextSubduedColor, }, + legend: { + orient: 'right', + labelColor: euiTheme.euiTextSubduedColor, + titleColor: euiTheme.euiTextSubduedColor, + }, }, repeat: { column: vegaColumns, diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/evaluate_panel.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/evaluate_panel.tsx index fb103886635a9e..00a63bcf2a4145 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/evaluate_panel.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/evaluate_panel.tsx @@ -26,6 +26,7 @@ import { useMlKibana } from '../../../../../contexts/kibana'; // Separate imports for lazy loadable VegaChart and related code import { VegaChart } from '../../../../../components/vega_chart'; import { VegaChartLoading } from '../../../../../components/vega_chart/vega_chart_loading'; +import { useCurrentEuiTheme } from '../../../../../components/color_range_legend'; import { ErrorCallout } from '../error_callout'; import { getDependentVar, DataFrameAnalyticsConfig } from '../../../../common'; @@ -33,6 +34,7 @@ import { DataFrameTaskStateType } from '../../../analytics_management/components import { ResultsSearchQuery } from '../../../../common/analytics'; import { ExpandableSection, HEADER_ITEMS_LOADING } from '../expandable_section'; + import { EvaluateStat } from './evaluate_stat'; import { EvaluationQualityMetricsTable } from './evaluation_quality_metrics_table'; @@ -107,6 +109,7 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, se const { services: { docLinks }, } = useMlKibana(); + const { euiTheme } = useCurrentEuiTheme(); const [columns, setColumns] = useState([]); const [columnsData, setColumnsData] = useState([]); @@ -469,7 +472,8 @@ export const EvaluatePanel: FC = ({ jobConfig, jobStatus, se vegaSpec={getRocCurveChartVegaLiteSpec( classificationClasses, rocCurveData, - getDependentVar(jobConfig.analysis) + getDependentVar(jobConfig.analysis), + euiTheme )} /> diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/get_roc_curve_chart_vega_lite_spec.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/get_roc_curve_chart_vega_lite_spec.tsx index e9a6925476b025..ef5bcb83e871fc 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/get_roc_curve_chart_vega_lite_spec.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/classification_exploration/get_roc_curve_chart_vega_lite_spec.tsx @@ -10,6 +10,7 @@ import type { TopLevelSpec } from 'vega-lite/build/vega-lite'; import { euiPaletteColorBlind, euiPaletteGray } from '@elastic/eui'; +import euiThemeLight from '@elastic/eui/dist/eui_theme_light.json'; import { i18n } from '@kbn/i18n'; @@ -43,7 +44,8 @@ export interface RocCurveDataRow extends RocCurveItem { export const getRocCurveChartVegaLiteSpec = ( classificationClasses: string[], data: RocCurveDataRow[], - legendTitle: string + legendTitle: string, + euiTheme: typeof euiThemeLight ): TopLevelSpec => { // we append two rows which make up the data for the diagonal baseline data.push({ tpr: 0, fpr: 0, threshold: 1, class_name: BASELINE }); @@ -59,6 +61,8 @@ export const getRocCurveChartVegaLiteSpec = ( config: { legend: { orient: 'right', + labelColor: euiTheme.euiTextSubduedColor, + titleColor: euiTheme.euiTextSubduedColor, }, view: { continuousHeight: SIZE, @@ -101,9 +105,9 @@ export const getRocCurveChartVegaLiteSpec = ( type: 'quantitative', axis: { tickColor: GRAY, - labelColor: GRAY, + labelColor: euiTheme.euiTextSubduedColor, domainColor: GRAY, - titleColor: GRAY, + titleColor: euiTheme.euiTextSubduedColor, }, }, y: { @@ -114,9 +118,9 @@ export const getRocCurveChartVegaLiteSpec = ( type: 'quantitative', axis: { tickColor: GRAY, - labelColor: GRAY, + labelColor: euiTheme.euiTextSubduedColor, domainColor: GRAY, - titleColor: GRAY, + titleColor: euiTheme.euiTextSubduedColor, }, }, tooltip: [ diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts index 7e07ac82c9dcf8..a494b401480d6b 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/classification_creation.ts @@ -53,7 +53,7 @@ export default function ({ getService }: FtrProviderContext) { // tick/grid/axis { color: '#DDDDDD', percentage: 50 }, // line - { color: '#98A2B3', percentage: 30 }, + { color: '#98A2B3', percentage: 10 }, ], scatterplotMatrixColorStats: [ // marker colors From 780c43513ad49c73515ec65a725df6a7a89eb445 Mon Sep 17 00:00:00 2001 From: Angela Chuang <6295984+angorayc@users.noreply.github.com> Date: Mon, 25 Oct 2021 11:16:13 +0100 Subject: [PATCH 06/66] [Security Solution] Fix tooltip for timeline sourcerer (#115950) * fix tooltip for event picker * remove unused mock * remove unused dependency Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/sourcerer/index.test.tsx | 34 ++++- .../common/components/sourcerer/index.tsx | 103 +++++++------ .../search_or_filter/pick_events.test.tsx | 55 ++++++- .../timeline/search_or_filter/pick_events.tsx | 137 ++++++++++-------- 4 files changed, 215 insertions(+), 114 deletions(-) diff --git a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx index 352fc954478228..591cba6b193810 100644 --- a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.test.tsx @@ -7,6 +7,9 @@ import React from 'react'; import { mount } from 'enzyme'; +import { waitFor } from '@testing-library/react'; + +import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; import { SourcererScopeName } from '../../store/sourcerer/model'; import { Sourcerer } from './index'; import { DEFAULT_INDEX_PATTERN } from '../../../../common/constants'; @@ -19,8 +22,6 @@ import { TestProviders, } from '../../mock'; import { createStore, State } from '../../store'; -import { EuiComboBox, EuiComboBoxOptionOption } from '@elastic/eui'; -import { waitFor } from '@testing-library/react'; const mockDispatch = jest.fn(); jest.mock('react-redux', () => { @@ -46,6 +47,7 @@ const mockOptions = [ const defaultProps = { scope: sourcererModel.SourcererScopeName.default, }; + describe('Sourcerer component', () => { beforeEach(() => { jest.clearAllMocks(); @@ -59,6 +61,34 @@ describe('Sourcerer component', () => { store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); }); + it('renders tooltip', () => { + const wrapper = mount( + + + + ); + expect(wrapper.find('[data-test-subj="sourcerer-tooltip"]').prop('content')).toEqual( + mockOptions + .map((p) => p.label) + .sort() + .join(', ') + ); + }); + + it('renders popover button inside tooltip', () => { + const wrapper = mount( + + + + ); + + expect( + wrapper + .find('[data-test-subj="sourcerer-tooltip"] [data-test-subj="sourcerer-trigger"]') + .exists() + ).toBeTruthy(); + }); + // Using props callback instead of simulating clicks, // because EuiSelectable uses a virtualized list, which isn't easily testable via test subjects it('Mounts with all options selected', () => { diff --git a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx index 8d0bb6410651c5..3e922176f99826 100644 --- a/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/sourcerer/index.tsx @@ -169,55 +169,62 @@ export const Sourcerer = React.memo(({ scope: scopeId } [isPopoverOpen, sourcererScope.selectedPatterns] ); + const buttonWithTooptip = useMemo(() => { + return tooltipContent ? ( + + {trigger} + + ) : ( + trigger + ); + }, [trigger, tooltipContent]); + return ( - - - - - <>{i18n.SELECT_INDEX_PATTERNS} - - - {i18n.INDEX_PATTERNS_SELECTION_LABEL} - - {comboBox} - - - - - {i18n.INDEX_PATTERNS_RESET} - - - - - {i18n.SAVE_INDEX_PATTERNS} - - - - - - + + + + <>{i18n.SELECT_INDEX_PATTERNS} + + + {i18n.INDEX_PATTERNS_SELECTION_LABEL} + + {comboBox} + + + + + {i18n.INDEX_PATTERNS_RESET} + + + + + {i18n.SAVE_INDEX_PATTERNS} + + + + + ); }); Sourcerer.displayName = 'Sourcerer'; diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.test.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.test.tsx index 3c6dc68edefccb..e519cfcd204a7f 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.test.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.test.tsx @@ -5,7 +5,9 @@ * 2.0. */ -import { fireEvent, render } from '@testing-library/react'; +import { fireEvent, render, within } from '@testing-library/react'; +import { EuiToolTip } from '@elastic/eui'; + import React from 'react'; import { PickEventType } from './pick_events'; import { @@ -19,6 +21,14 @@ import { TimelineEventsType } from '../../../../../common'; import { createStore } from '../../../../common/store'; import { SourcererScopeName } from '../../../../common/store/sourcerer/model'; +jest.mock('@elastic/eui', () => { + const actual = jest.requireActual('@elastic/eui'); + return { + ...actual, + EuiToolTip: jest.fn(), + }; +}); + describe('pick_events', () => { const defaultProps = { eventType: 'all' as TimelineEventsType, @@ -53,6 +63,23 @@ describe('pick_events', () => { }, }; const store = createStore(state, SUB_PLUGINS_REDUCER, kibanaObservable, storage); + + const mockTooltip = ({ + tooltipContent, + children, + }: { + tooltipContent: string; + children: React.ReactElement; + }) => ( +
+ {tooltipContent} + {children} +
+ ); + + beforeAll(() => { + (EuiToolTip as unknown as jest.Mock).mockImplementation(mockTooltip); + }); beforeEach(() => { jest.clearAllMocks(); jest.restoreAllMocks(); @@ -68,6 +95,32 @@ describe('pick_events', () => { initialPatterns.sort().join('') ); }); + + it('renders tooltip', () => { + render( + + + + ); + + expect((EuiToolTip as unknown as jest.Mock).mock.calls[0][0].content).toEqual( + initialPatterns + .filter((p) => p != null) + .sort() + .join(', ') + ); + }); + + it('renders popover button inside tooltip', () => { + const wrapper = render( + + + + ); + const tooltip = wrapper.getByTestId('timeline-sourcerer-tooltip'); + expect(within(tooltip).getByTestId('sourcerer-timeline-trigger')).toBeTruthy(); + }); + it('correctly filters options', () => { const wrapper = render( diff --git a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.tsx b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.tsx index dbe04eccac5218..6d86d7c0f13301 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/timeline/search_or_filter/pick_events.tsx @@ -295,6 +295,20 @@ const PickEventTypeComponents: React.FC = ({ [isPopoverOpen, sourcererScope.selectedPatterns] ); + const buttonWithTooptip = useMemo(() => { + return tooltipContent ? ( + + {button} + + ) : ( + button + ); + }, [button, tooltipContent]); + const ButtonContent = useMemo( () => ( @@ -326,69 +340,66 @@ const PickEventTypeComponents: React.FC = ({ return ( - - - - - <>{i18n.SELECT_INDEX_PATTERNS} - - - {filter} - - - <> - - {comboBox} - - - {!showAdvanceSettings && ( - <> - - - {i18n.CONFIGURE_INDEX_PATTERNS} - - - )} - - - - - {i18n.DATA_SOURCES_RESET} - - - - - {i18n.SAVE_INDEX_PATTERNS} - - - - - - + + + + <>{i18n.SELECT_INDEX_PATTERNS} + + + {filter} + + + <> + + {comboBox} + + + {!showAdvanceSettings && ( + <> + + + {i18n.CONFIGURE_INDEX_PATTERNS} + + + )} + + + + + {i18n.DATA_SOURCES_RESET} + + + + + {i18n.SAVE_INDEX_PATTERNS} + + + + + ); }; From 8f75a715f566c2b7fc1e2be490dbedb2102dc8bf Mon Sep 17 00:00:00 2001 From: Dmitry Tomashevich <39378793+Dmitriynj@users.noreply.github.com> Date: Mon, 25 Oct 2021 14:26:45 +0300 Subject: [PATCH 07/66] [Discover] Add clock icon to time field column (#114996) * [Discover] Add clock icon to time field column * [Discover] fix linting * [Discover] fix functional tests * [Discover] fix functional test * [Discover] apply suggestion * [Discover] apply wording suggestion * [Discover] fix i18n * [Discover] update unit tests * [Discover] add custom label for classic table * [Discover] color icon black * [Discover] fix unit tests Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../doc_table/components/_table_header.scss | 3 ++- .../__snapshots__/table_header.test.tsx.snap | 11 +++++++- .../components/table_header/helpers.tsx | 2 +- .../components/table_header/table_header.tsx | 2 ++ .../table_header/table_header_column.tsx | 24 ++++++++++++++++-- .../discover_grid_columns.test.tsx | 10 +++++++- .../discover_grid/discover_grid_columns.tsx | 25 ++++++++++++++----- .../apps/context/_discover_navigation.ts | 2 +- test/functional/apps/discover/_data_grid.ts | 10 ++++---- .../apps/discover/_data_grid_context.ts | 2 +- .../apps/discover/_data_grid_field_data.ts | 4 +-- test/functional/apps/discover/_field_data.ts | 4 +-- .../discover/_field_data_with_fields_api.ts | 4 +-- .../translations/translations/ja-JP.json | 1 - .../translations/translations/zh-CN.json | 1 - 15 files changed, 78 insertions(+), 27 deletions(-) diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/_table_header.scss b/src/plugins/discover/public/application/apps/main/components/doc_table/components/_table_header.scss index 3450084e19269f..3ea6fb55027647 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/_table_header.scss +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/_table_header.scss @@ -1,7 +1,8 @@ .kbnDocTableHeader { white-space: nowrap; } -.kbnDocTableHeader button { +.kbnDocTableHeader button, +.kbnDocTableHeader svg { margin-left: $euiSizeXS * .5; } .kbnDocTableHeader__move, diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap index 18b0ae8699e3e5..3f72349f3e2a01 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/__snapshots__/table_header.test.tsx.snap @@ -15,7 +15,16 @@ exports[`TableHeader with time column renders correctly 1`] = ` class="kbnDocTableHeader__actions" data-test-subj="docTableHeader-time" > - Time + time + + + diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx index d313e95c1ebb1b..f04454d33e9f2f 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx @@ -28,7 +28,7 @@ export interface ColumnProps { export function getTimeColumn(timeFieldName: string): ColumnProps { return { name: timeFieldName, - displayName: 'Time', + displayName: timeFieldName, isSortable: true, isRemoveable: false, colLeftIdx: -1, diff --git a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header.tsx b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header.tsx index f891e809ee702d..1877c014ddcbd6 100644 --- a/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header.tsx +++ b/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/table_header.tsx @@ -45,6 +45,8 @@ export function TableHeader({ void; onMoveColumn?: (name: string, idx: number) => void; @@ -54,6 +56,8 @@ export function TableHeaderColumn({ displayName, isRemoveable, isSortable, + isTimeColumn, + customLabel, name, onChangeSortOrder, onMoveColumn, @@ -65,6 +69,14 @@ export function TableHeaderColumn({ const curColSort = sortOrder.find((pair) => pair[0] === name); const curColSortDir = (curColSort && curColSort[1]) || ''; + const timeAriaLabel = i18n.translate( + 'discover.docTable.tableHeader.timeFieldIconTooltipAriaLabel', + { defaultMessage: 'Primary time field.' } + ); + const timeTooltip = i18n.translate('discover.docTable.tableHeader.timeFieldIconTooltip', { + defaultMessage: 'This field represents the time that events occurred.', + }); + // If this is the _score column, and _score is not one of the columns inside the sort, show a // warning that the _score will not be retrieved from Elasticsearch const showScoreSortWarning = name === '_score' && !curColSort; @@ -183,7 +195,15 @@ export function TableHeaderColumn({ {showScoreSortWarning && } - {displayName} + {customLabel ?? displayName} + {isTimeColumn && ( + + )} {buttons .filter((button) => button.active) .map((button, idx) => ( diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.test.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.test.tsx index 46e30dd23525bf..e5ea657032403e 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.test.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.test.tsx @@ -117,7 +117,15 @@ describe('Discover grid columns ', function () { [Function], [Function], ], - "display": "Time (timestamp)", + "display": + timestamp + + + , "id": "timestamp", "initialWidth": 190, "isSortable": true, diff --git a/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx b/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx index 2f4c0b5167df83..5eb55a8e99cdea 100644 --- a/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx +++ b/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx @@ -6,9 +6,9 @@ * Side Public License, v 1. */ -import React from 'react'; +import React, { Fragment } from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiDataGridColumn, EuiScreenReaderOnly } from '@elastic/eui'; +import { EuiDataGridColumn, EuiIconTip, EuiScreenReaderOnly } from '@elastic/eui'; import { ExpandButton } from './discover_grid_expand_button'; import { DiscoverGridSettings } from './types'; import type { IndexPattern } from '../../../../../data/common'; @@ -57,9 +57,6 @@ export function buildEuiGridColumn( defaultColumns: boolean, isSortEnabled: boolean ) { - const timeString = i18n.translate('discover.timeLabel', { - defaultMessage: 'Time', - }); const indexPatternField = indexPattern.getFieldByName(columnName); const column: EuiDataGridColumn = { id: columnName, @@ -88,7 +85,23 @@ export function buildEuiGridColumn( }; if (column.id === indexPattern.timeFieldName) { - column.display = `${timeString} (${indexPattern.timeFieldName})`; + const primaryTimeAriaLabel = i18n.translate( + 'discover.docTable.tableHeader.timeFieldIconTooltipAriaLabel', + { defaultMessage: 'Primary time field.' } + ); + const primaryTimeTooltip = i18n.translate( + 'discover.docTable.tableHeader.timeFieldIconTooltip', + { + defaultMessage: 'This field represents the time that events occurred.', + } + ); + + column.display = ( + + {indexPatternField?.customLabel ?? indexPattern.timeFieldName}{' '} + + + ); column.initialWidth = defaultTimeColumnWidth; } if (columnWidth > 0) { diff --git a/test/functional/apps/context/_discover_navigation.ts b/test/functional/apps/context/_discover_navigation.ts index 1b8300f3345b16..60745bd64b8be2 100644 --- a/test/functional/apps/context/_discover_navigation.ts +++ b/test/functional/apps/context/_discover_navigation.ts @@ -74,7 +74,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should open the context view with the same columns', async () => { const columnNames = await docTable.getHeaderFields(); - expect(columnNames).to.eql(['Time', ...TEST_COLUMN_NAMES]); + expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]); }); it('should open the context view with the filters disabled', async () => { diff --git a/test/functional/apps/discover/_data_grid.ts b/test/functional/apps/discover/_data_grid.ts index 4a343fb30384e3..198691f3b84777 100644 --- a/test/functional/apps/discover/_data_grid.ts +++ b/test/functional/apps/discover/_data_grid.ts @@ -39,19 +39,19 @@ export default function ({ const getTitles = async () => (await testSubjects.getVisibleText('dataGridHeader')).replace(/\s|\r?\n|\r/g, ' '); - expect(await getTitles()).to.be('Time (@timestamp) Document'); + expect(await getTitles()).to.be('@timestamp Document'); await PageObjects.discover.clickFieldListItemAdd('bytes'); - expect(await getTitles()).to.be('Time (@timestamp) bytes'); + expect(await getTitles()).to.be('@timestamp bytes'); await PageObjects.discover.clickFieldListItemAdd('agent'); - expect(await getTitles()).to.be('Time (@timestamp) bytes agent'); + expect(await getTitles()).to.be('@timestamp bytes agent'); await PageObjects.discover.clickFieldListItemRemove('bytes'); - expect(await getTitles()).to.be('Time (@timestamp) agent'); + expect(await getTitles()).to.be('@timestamp agent'); await PageObjects.discover.clickFieldListItemRemove('agent'); - expect(await getTitles()).to.be('Time (@timestamp) Document'); + expect(await getTitles()).to.be('@timestamp Document'); }); }); } diff --git a/test/functional/apps/discover/_data_grid_context.ts b/test/functional/apps/discover/_data_grid_context.ts index 3d9e01e1dee19d..d12ada2070cff9 100644 --- a/test/functional/apps/discover/_data_grid_context.ts +++ b/test/functional/apps/discover/_data_grid_context.ts @@ -76,7 +76,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should open the context view with the same columns', async () => { const columnNames = await dataGrid.getHeaderFields(); - expect(columnNames).to.eql(['Time (@timestamp)', ...TEST_COLUMN_NAMES]); + expect(columnNames).to.eql(['@timestamp', ...TEST_COLUMN_NAMES]); }); it('should open the context view with the filters disabled', async () => { diff --git a/test/functional/apps/discover/_data_grid_field_data.ts b/test/functional/apps/discover/_data_grid_field_data.ts index 94e8e942f86ba2..91c2d5914732d9 100644 --- a/test/functional/apps/discover/_data_grid_field_data.ts +++ b/test/functional/apps/discover/_data_grid_field_data.ts @@ -59,8 +59,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); - it('doc view should show Time and _source columns', async function () { - const expectedHeader = 'Time (@timestamp) Document'; + it('doc view should show @timestamp and _source columns', async function () { + const expectedHeader = '@timestamp Document'; const DocHeader = await dataGrid.getHeaderFields(); expect(DocHeader.join(' ')).to.be(expectedHeader); }); diff --git a/test/functional/apps/discover/_field_data.ts b/test/functional/apps/discover/_field_data.ts index 27407e9a0bc4d8..28f147eeab55fc 100644 --- a/test/functional/apps/discover/_field_data.ts +++ b/test/functional/apps/discover/_field_data.ts @@ -107,8 +107,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { after(async function () { await kibanaServer.uiSettings.replace({}); }); - it('doc view should show Time and _source columns', async function () { - const expectedHeader = 'Time\n_source'; + it('doc view should show @timestamp and _source columns', async function () { + const expectedHeader = '@timestamp\n_source'; const docHeader = await find.byCssSelector('thead > tr:nth-child(1)'); const docHeaderText = await docHeader.getVisibleText(); expect(docHeaderText).to.be(expectedHeader); diff --git a/test/functional/apps/discover/_field_data_with_fields_api.ts b/test/functional/apps/discover/_field_data_with_fields_api.ts index 666377ae7f7942..f0dedb155fc9ba 100644 --- a/test/functional/apps/discover/_field_data_with_fields_api.ts +++ b/test/functional/apps/discover/_field_data_with_fields_api.ts @@ -64,9 +64,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); }); - it('doc view should show Time and Document columns', async function () { + it('doc view should show @timestamp and Document columns', async function () { const Docheader = await PageObjects.discover.getDocHeader(); - expect(Docheader).to.contain('Time'); + expect(Docheader).to.contain('@timestamp'); expect(Docheader).to.contain('Document'); }); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 9e4249986c6a9f..7291e946154774 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -2532,7 +2532,6 @@ "discover.sourceViewer.errorMessage": "現在データを取得できませんでした。タブを更新して、再試行してください。", "discover.sourceViewer.errorMessageTitle": "エラーが発生しました", "discover.sourceViewer.refresh": "更新", - "discover.timeLabel": "時間", "discover.toggleSidebarAriaLabel": "サイドバーを切り替える", "discover.topNav.openOptionsPopover.description": "お知らせDiscoverでは、データの並べ替え、列のドラッグアンドドロップ、ドキュメントの比較を行う方法が改善されました。詳細設定で[クラシックテーブルを使用]を切り替えて、開始します。", "discover.topNav.openSearchPanel.manageSearchesButtonLabel": "検索の管理", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index db6d19d7550a9d..2aa9cabb7866bc 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -2557,7 +2557,6 @@ "discover.sourceViewer.errorMessage": "当前无法获取数据。请刷新选项卡以重试。", "discover.sourceViewer.errorMessageTitle": "发生错误", "discover.sourceViewer.refresh": "刷新", - "discover.timeLabel": "时间", "discover.toggleSidebarAriaLabel": "切换侧边栏", "discover.topNav.openOptionsPopover.description": "好消息!Discover 有更好的方法排序数据、拖放列和比较文档。在“高级模式”中切换“使用经典表”来开始。", "discover.topNav.openSearchPanel.manageSearchesButtonLabel": "管理搜索", From 811724b003f058b88dd85fed45ce853fdc682b04 Mon Sep 17 00:00:00 2001 From: Orhan Toy Date: Mon, 25 Oct 2021 14:00:13 +0200 Subject: [PATCH 08/66] [App Search, Crawler] Link-ify domain name in table (#115735) --- .../crawler/components/domains_table.test.tsx | 12 ++++++++++++ .../components/crawler/components/domains_table.tsx | 9 +++++++++ 2 files changed, 21 insertions(+) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.test.tsx index 78049d5832e9a8..76622f9c12822b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.test.tsx @@ -87,6 +87,18 @@ describe('DomainsTable', () => { expect(tableContent).toContain('elastic.co'); }); + it('renders a clickable domain url', () => { + const basicTable = wrapper.find(EuiInMemoryTable).dive().find(EuiBasicTable).dive(); + const link = basicTable.find('[data-test-subj="CrawlerDomainURL"]').at(0); + + expect(link.dive().text()).toContain('elastic.co'); + expect(link.props()).toEqual( + expect.objectContaining({ + to: '/engines/some-engine/crawler/domains/1234', + }) + ); + }); + it('renders a last crawled column', () => { expect(tableContent).toContain('Last activity'); expect(tableContent).toContain('Jan 1, 2020'); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.tsx index 7214eace25e2d4..1f0f6be22102f4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/domains_table.tsx @@ -17,6 +17,7 @@ import { FormattedNumber } from '@kbn/i18n/react'; import { DELETE_BUTTON_LABEL, MANAGE_BUTTON_LABEL } from '../../../../shared/constants'; import { KibanaLogic } from '../../../../shared/kibana'; +import { EuiLinkTo } from '../../../../shared/react_router_helpers'; import { AppLogic } from '../../../app_logic'; import { ENGINE_CRAWLER_DOMAIN_PATH } from '../../../routes'; import { generateEnginePath } from '../../engine'; @@ -46,6 +47,14 @@ export const DomainsTable: React.FC = () => { defaultMessage: 'Domain URL', } ), + render: (_, domain: CrawlerDomain) => ( + + {domain.url} + + ), }, { field: 'lastCrawl', From 5d73e8c3f4265aed99eb349160d4157ff2a8601a Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Mon, 25 Oct 2021 14:26:12 +0200 Subject: [PATCH 09/66] [Lens] Opening advanced Intervals editor should not throw an error (#115801) * :bug: Fix issue with the first rendering * :white_check_mark: Add tests for valid and broken scenario Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../definitions/ranges/ranges.test.tsx | 48 ++++++++++++++++++- .../operations/definitions/ranges/ranges.tsx | 2 +- 2 files changed, 48 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx index b85652481d5b20..2877094ac81f88 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.test.tsx @@ -52,7 +52,7 @@ jest.mock('lodash', () => { const dataPluginMockValue = dataPluginMock.createStartContract(); // need to overwrite the formatter field first -dataPluginMockValue.fieldFormats.deserialize = jest.fn().mockImplementation(({ params }) => { +dataPluginMockValue.fieldFormats.deserialize = jest.fn().mockImplementation(({ id, params }) => { return { convert: ({ gte, lt }: { gte: string; lt: string }) => { if (params?.id === 'custom') { @@ -61,6 +61,9 @@ dataPluginMockValue.fieldFormats.deserialize = jest.fn().mockImplementation(({ p if (params?.id === 'bytes') { return `Bytes format: ${gte} - ${lt}`; } + if (!id) { + return 'Error'; + } return `${gte} - ${lt}`; }, }; @@ -476,6 +479,49 @@ describe('ranges', () => { expect(instance.find(DragDropBuckets).children).toHaveLength(1); }); + it('should use the parentFormat to create the trigger label', () => { + const updateLayerSpy = jest.fn(); + + const instance = mount( + + ); + + expect( + instance.find('[data-test-subj="indexPattern-ranges-popover-trigger"]').first().text() + ).toBe('0 - 1000'); + }); + + it('should not print error if the parentFormat is not provided', () => { + // while in the actual React implementation will print an error, here + // we intercept the formatter without an id assigned an print "Error" + const updateLayerSpy = jest.fn(); + + const instance = mount( + + ); + + expect( + instance.find('[data-test-subj="indexPattern-ranges-popover-trigger"]').first().text() + ).not.toBe('Error'); + }); + it('should add a new range', () => { const updateLayerSpy = jest.fn(); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx index 29e7de18ca4ade..6e397a926c7a0d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx @@ -196,7 +196,7 @@ export const rangeOperation: OperationDefinition Date: Mon, 25 Oct 2021 14:27:05 +0200 Subject: [PATCH 10/66] [TSVB] Show the loading spinner while loading in dashboard (#114244) * :bug: Fix metric rescale * :camera_flash: Restored old snapshots * :bug: Extend the fix to all scenarios * :camera_flash: Refresh snapshots for new fix * :lipstick: Add suspense with loading spinner while waiting for the component to be loaded * :bug: Move the styling one level deeper to avoid loading gaps * :bug: show loader since the beginning and speed up a bit embeddable load * :lipstick: Show the loader while waiting for the palette * :zap: Remove one chunk from TSVB async series * :bug: Restore previous async chunk * :ok_hand: Integrate feedback * :rotating_light: Fix linting issue Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/timeseries_visualization.tsx | 37 ++++++---- .../public/timeseries_vis_renderer.tsx | 69 +++++++++++-------- ...embeddable.ts => visualize_embeddable.tsx} | 10 +++ .../embeddable/visualize_embeddable_async.ts | 8 ++- 4 files changed, 79 insertions(+), 45 deletions(-) rename src/plugins/visualizations/public/embeddable/{visualize_embeddable.ts => visualize_embeddable.tsx} (98%) diff --git a/src/plugins/vis_types/timeseries/public/application/components/timeseries_visualization.tsx b/src/plugins/vis_types/timeseries/public/application/components/timeseries_visualization.tsx index a73f9c6a5e0923..886b569671a6b4 100644 --- a/src/plugins/vis_types/timeseries/public/application/components/timeseries_visualization.tsx +++ b/src/plugins/vis_types/timeseries/public/application/components/timeseries_visualization.tsx @@ -8,8 +8,8 @@ import './timeseries_visualization.scss'; -import React, { useCallback, useEffect } from 'react'; -import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; +import React, { Suspense, useCallback, useEffect } from 'react'; +import { EuiFlexGroup, EuiFlexItem, EuiLoadingChart } from '@elastic/eui'; import { XYChartSeriesIdentifier, GeometryValue } from '@elastic/charts'; import { IUiSettingsClient } from 'src/core/public'; import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; @@ -28,6 +28,7 @@ import { getInterval } from './lib/get_interval'; import { AUTO_INTERVAL } from '../../../common/constants'; import { TIME_RANGE_DATA_MODES, PANEL_TYPES } from '../../../common/enums'; import type { IndexPattern } from '../../../../../data/common'; +import '../index.scss'; interface TimeseriesVisualizationProps { className?: string; @@ -161,18 +162,26 @@ function TimeseriesVisualization({ )} - + + + + } + > + + ); diff --git a/src/plugins/vis_types/timeseries/public/timeseries_vis_renderer.tsx b/src/plugins/vis_types/timeseries/public/timeseries_vis_renderer.tsx index 34cc1dc347ef86..ad069a4d7e2cc4 100644 --- a/src/plugins/vis_types/timeseries/public/timeseries_vis_renderer.tsx +++ b/src/plugins/vis_types/timeseries/public/timeseries_vis_renderer.tsx @@ -13,6 +13,7 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { I18nProvider } from '@kbn/i18n/react'; import { IUiSettingsClient } from 'kibana/public'; +import { EuiLoadingChart } from '@elastic/eui'; import { fetchIndexPattern } from '../common/index_patterns_utils'; import { VisualizationContainer, PersistedState } from '../../../visualizations/public'; @@ -43,10 +44,6 @@ export const getTimeseriesVisRenderer: (deps: { name: 'timeseries_vis', reuseDomNode: true, render: async (domNode, config, handlers) => { - // Build optimization. Move app styles from main bundle - // @ts-expect-error TS error, cannot find type declaration for scss - await import('./application/index.scss'); - handlers.onDestroy(() => { unmountComponentAtNode(domNode); }); @@ -55,33 +52,49 @@ export const getTimeseriesVisRenderer: (deps: { const { indexPatterns } = getDataStart(); const showNoResult = !checkIfDataExists(visData, model); - const [palettesService, { indexPattern }] = await Promise.all([ + + let servicesLoaded; + + Promise.all([ palettes.getPalettes(), fetchIndexPattern(model.index_pattern, indexPatterns), - ]); + ]).then(([palettesService, { indexPattern }]) => { + servicesLoaded = true; - render( - - - + - - , - domNode - ); + showNoResult={showNoResult} + error={get(visData, [model.id, 'error'])} + > + + + , + domNode + ); + }); + + if (!servicesLoaded) { + render( +
+ +
, + domNode + ); + } }, }); diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx similarity index 98% rename from src/plugins/visualizations/public/embeddable/visualize_embeddable.ts rename to src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index 928cbec9c3747a..37365fd613e5a2 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -9,6 +9,9 @@ import _, { get } from 'lodash'; import { Subscription } from 'rxjs'; import { i18n } from '@kbn/i18n'; +import React from 'react'; +import { render } from 'react-dom'; +import { EuiLoadingChart } from '@elastic/eui'; import { VISUALIZE_EMBEDDABLE_TYPE } from './constants'; import { IndexPattern, @@ -299,6 +302,13 @@ export class VisualizeEmbeddable this.domNode = div; super.render(this.domNode); + render( +
+ +
, + this.domNode + ); + const expressions = getExpressions(); this.handler = await expressions.loader(this.domNode, undefined, { onRenderError: (element: HTMLElement, error: ExpressionRenderError) => { diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable_async.ts b/src/plugins/visualizations/public/embeddable/visualize_embeddable_async.ts index c7480844adbeaa..2fa22cfe8d80b1 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable_async.ts +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable_async.ts @@ -12,10 +12,12 @@ export const createVisualizeEmbeddableAsync = async ( ...args: ConstructorParameters ) => { // Build optimization. Move app styles from main bundle - // @ts-expect-error TS error, cannot find type declaration for scss - await import('./embeddables.scss'); - const { VisualizeEmbeddable } = await import('./visualize_embeddable'); + const [{ VisualizeEmbeddable }] = await Promise.all([ + import('./visualize_embeddable'), + // @ts-expect-error TS error, cannot find type declaration for scss + import('./embeddables.scss'), + ]); return new VisualizeEmbeddable(...args); }; From cf2a3f58084370ab71b60462f386a377f7d6f1d5 Mon Sep 17 00:00:00 2001 From: Marco Liberati Date: Mon, 25 Oct 2021 14:29:38 +0200 Subject: [PATCH 11/66] [Lens] Add value labels to Heatmap (#106406) * :sparkles: Add label values menu * :sparkles: Enable value labels for Heatmap * :fire: Remove removed translations * :label: Fix type issue Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../common/expressions/xy_chart/xy_args.ts | 3 +- x-pack/plugins/lens/common/types.ts | 3 + .../heatmap_visualization/chart_component.tsx | 3 + .../toolbar_component.tsx | 24 +++++- x-pack/plugins/lens/public/index.ts | 2 +- .../lens/public/shared_components/index.ts | 1 + .../value_labels_settings.test.tsx | 46 ++++++++++++ .../value_labels_settings.tsx | 75 +++++++++++++++++++ .../lens/public/xy_visualization/types.ts | 2 +- .../visual_options_popover/index.tsx | 15 ++-- .../missing_value_option.test.tsx | 53 +------------ .../missing_values_option.tsx | 66 +--------------- .../visual_options_popover.test.tsx | 10 +-- .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - .../test/functional/apps/lens/smokescreen.ts | 2 +- 16 files changed, 171 insertions(+), 138 deletions(-) create mode 100644 x-pack/plugins/lens/public/shared_components/value_labels_settings.test.tsx create mode 100644 x-pack/plugins/lens/public/shared_components/value_labels_settings.tsx diff --git a/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts b/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts index fb794eda22dbe0..f00608135820ab 100644 --- a/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts +++ b/x-pack/plugins/lens/common/expressions/xy_chart/xy_args.ts @@ -12,8 +12,7 @@ import type { LayerArgs } from './layer_config'; import type { LegendConfigResult } from './legend_config'; import type { TickLabelsConfigResult } from './tick_labels_config'; import type { LabelsOrientationConfigResult } from './labels_orientation_config'; - -export type ValueLabelConfig = 'hide' | 'inside' | 'outside'; +import type { ValueLabelConfig } from '../../types'; export type XYCurveType = 'LINEAR' | 'CURVE_MONOTONE_X'; diff --git a/x-pack/plugins/lens/common/types.ts b/x-pack/plugins/lens/common/types.ts index 38e198c01e7306..307ed856c7c666 100644 --- a/x-pack/plugins/lens/common/types.ts +++ b/x-pack/plugins/lens/common/types.ts @@ -62,3 +62,6 @@ export interface CustomPaletteParams { export type RequiredPaletteParamTypes = Required; export type LayerType = 'data' | 'referenceLine'; + +// Shared by XY Chart and Heatmap as for now +export type ValueLabelConfig = 'hide' | 'inside' | 'outside'; diff --git a/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx b/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx index 677cb9d20c25b0..c999656071ef43 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/chart_component.tsx @@ -288,6 +288,9 @@ export const HeatmapComponent: FC = ({ maxHeight: 'fill', label: { visible: args.gridConfig.isCellLabelVisible ?? false, + minFontSize: 8, + maxFontSize: 18, + useGlobalMinFontSize: true, // override the min if there's a different directive upstream }, border: { strokeWidth: 0, diff --git a/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx b/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx index 80954516f04181..88966acd226910 100644 --- a/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx +++ b/x-pack/plugins/lens/public/heatmap_visualization/toolbar_component.tsx @@ -10,7 +10,7 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import { Position } from '@elastic/charts'; import { i18n } from '@kbn/i18n'; import type { VisualizationToolbarProps } from '../types'; -import { LegendSettingsPopover } from '../shared_components'; +import { LegendSettingsPopover, ToolbarPopover, ValueLabelsSettings } from '../shared_components'; import type { HeatmapVisualizationState } from './types'; const legendOptions: Array<{ id: string; value: 'auto' | 'show' | 'hide'; label: string }> = [ @@ -37,11 +37,29 @@ export const HeatmapToolbar = memo( const legendMode = state.legend.isVisible ? 'show' : 'hide'; return ( - + + + { + setState({ + ...state, + gridConfig: { ...state.gridConfig, isCellLabelVisible: newMode === 'inside' }, + }); + }} + /> + { diff --git a/x-pack/plugins/lens/public/index.ts b/x-pack/plugins/lens/public/index.ts index 84302f25d0a023..9be07a4f44dcdf 100644 --- a/x-pack/plugins/lens/public/index.ts +++ b/x-pack/plugins/lens/public/index.ts @@ -22,11 +22,11 @@ export type { XYLayerConfig, LegendConfig, SeriesType, - ValueLabelConfig, YAxisMode, XYCurveType, YConfig, } from '../common/expressions'; +export type { ValueLabelConfig } from '../common/types'; export type { DatatableVisualizationState } from './datatable_visualization/visualization'; export type { IndexPatternPersistedState, diff --git a/x-pack/plugins/lens/public/shared_components/index.ts b/x-pack/plugins/lens/public/shared_components/index.ts index f947ce699dce4e..f268d6816910e0 100644 --- a/x-pack/plugins/lens/public/shared_components/index.ts +++ b/x-pack/plugins/lens/public/shared_components/index.ts @@ -14,4 +14,5 @@ export * from './coloring'; export { useDebouncedValue } from './debounced_value'; export * from './helpers'; export { LegendActionPopover } from './legend_action_popover'; +export { ValueLabelsSettings } from './value_labels_settings'; export * from './static_header'; diff --git a/x-pack/plugins/lens/public/shared_components/value_labels_settings.test.tsx b/x-pack/plugins/lens/public/shared_components/value_labels_settings.test.tsx new file mode 100644 index 00000000000000..ae68a40d8cea61 --- /dev/null +++ b/x-pack/plugins/lens/public/shared_components/value_labels_settings.test.tsx @@ -0,0 +1,46 @@ +/* + * 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 { shallowWithIntl as shallow } from '@kbn/test/jest'; +import { ValueLabelsSettings, VisualOptionsProps } from './value_labels_settings'; + +describe('Value labels Settings', () => { + let props: VisualOptionsProps; + beforeEach(() => { + props = { + onValueLabelChange: jest.fn(), + }; + }); + + it('should not render the component if not enabled', () => { + const component = shallow(); + expect(component.find('[data-test-subj="lens-value-labels-visibility-btn"]').length).toEqual(0); + }); + + it('should set hide as default value', () => { + const component = shallow(); + expect( + component.find('[data-test-subj="lens-value-labels-visibility-btn"]').prop('idSelected') + ).toEqual(`value_labels_hide`); + }); + + it('should have called onValueLabelChange function on ButtonGroup change', () => { + const component = shallow(); + component + .find('[data-test-subj="lens-value-labels-visibility-btn"]') + .simulate('change', 'value_labels_inside'); + expect(props.onValueLabelChange).toHaveBeenCalled(); + }); + + it('should render the passed value if given', () => { + const component = shallow(); + expect( + component.find('[data-test-subj="lens-value-labels-visibility-btn"]').prop('idSelected') + ).toEqual(`value_labels_inside`); + }); +}); diff --git a/x-pack/plugins/lens/public/shared_components/value_labels_settings.tsx b/x-pack/plugins/lens/public/shared_components/value_labels_settings.tsx new file mode 100644 index 00000000000000..64d9f5475379a1 --- /dev/null +++ b/x-pack/plugins/lens/public/shared_components/value_labels_settings.tsx @@ -0,0 +1,75 @@ +/* + * 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, { FC } from 'react'; +import { i18n } from '@kbn/i18n'; +import { EuiButtonGroup, EuiFormRow } from '@elastic/eui'; +import { ValueLabelConfig } from '../../common/types'; + +const valueLabelsOptions: Array<{ + id: string; + value: ValueLabelConfig; + label: string; + 'data-test-subj': string; +}> = [ + { + id: `value_labels_hide`, + value: 'hide', + label: i18n.translate('xpack.lens.shared.valueLabelsVisibility.auto', { + defaultMessage: 'Hide', + }), + 'data-test-subj': 'lns_valueLabels_hide', + }, + { + id: `value_labels_inside`, + value: 'inside', + label: i18n.translate('xpack.lens.shared.valueLabelsVisibility.inside', { + defaultMessage: 'Show', + }), + 'data-test-subj': 'lns_valueLabels_inside', + }, +]; + +export interface VisualOptionsProps { + isVisible?: boolean; + valueLabels?: ValueLabelConfig; + onValueLabelChange: (newMode: ValueLabelConfig) => void; +} + +export const ValueLabelsSettings: FC = ({ + isVisible = true, + valueLabels = 'hide', + onValueLabelChange, +}) => { + if (!isVisible) { + return null; + } + const label = i18n.translate('xpack.lens.shared.chartValueLabelVisibilityLabel', { + defaultMessage: 'Labels', + }); + const isSelected = + valueLabelsOptions.find(({ value }) => value === valueLabels)?.id || 'value_labels_hide'; + return ( + {label}
}> + { + const newMode = valueLabelsOptions.find(({ id }) => id === modeId); + if (newMode) { + onValueLabelChange(newMode.value); + } + }} + /> + + ); +}; diff --git a/x-pack/plugins/lens/public/xy_visualization/types.ts b/x-pack/plugins/lens/public/xy_visualization/types.ts index 4729cfb96f324f..475571b2965f64 100644 --- a/x-pack/plugins/lens/public/xy_visualization/types.ts +++ b/x-pack/plugins/lens/public/xy_visualization/types.ts @@ -20,7 +20,6 @@ import { LensIconChartLine } from '../assets/chart_line'; import type { VisualizationType } from '../types'; import type { SeriesType, - ValueLabelConfig, LegendConfig, AxisExtentConfig, XYLayerConfig, @@ -29,6 +28,7 @@ import type { FittingFunction, LabelsOrientationConfig, } from '../../common/expressions'; +import type { ValueLabelConfig } from '../../common/types'; // Persisted parts of the state export interface XYState { diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/index.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/index.tsx index 2a19897445e63c..8ea6f9ace63207 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/index.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/index.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { ToolbarPopover, TooltipWrapper } from '../../../shared_components'; +import { ToolbarPopover, TooltipWrapper, ValueLabelsSettings } from '../../../shared_components'; import { MissingValuesOptions } from './missing_values_option'; import { LineCurveOption } from './line_curve_option'; import { FillOpacityOption } from './fill_opacity_option'; @@ -102,14 +102,17 @@ export const VisualOptionsPopover: React.FC = ({ }} /> - { setState({ ...state, valueLabels: newMode }); }} + /> + + { setState({ ...state, fittingFunction: newVal }); }} diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/missing_value_option.test.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/missing_value_option.test.tsx index 851b14839d7f73..ce4e05223b5a34 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/missing_value_option.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/missing_value_option.test.tsx @@ -7,70 +7,23 @@ import React from 'react'; import { shallowWithIntl as shallow, mountWithIntl as mount } from '@kbn/test/jest'; -import { EuiSuperSelect, EuiButtonGroup } from '@elastic/eui'; +import { EuiSuperSelect } from '@elastic/eui'; import { MissingValuesOptions } from './missing_values_option'; describe('Missing values option', () => { it('should show currently selected fitting function', () => { const component = shallow( - + ); expect(component.find(EuiSuperSelect).prop('valueOfSelected')).toEqual('Carry'); }); - it('should show currently selected value labels display setting', () => { - const component = mount( - - ); - - expect(component.find(EuiButtonGroup).prop('idSelected')).toEqual('value_labels_inside'); - }); - - it('should show display field when enabled', () => { - const component = mount( - - ); - - expect(component.exists('[data-test-subj="lnsValueLabelsDisplay"]')).toEqual(true); - }); - - it('should hide in display value label option when disabled', () => { - const component = mount( - - ); - - expect(component.exists('[data-test-subj="lnsValueLabelsDisplay"]')).toEqual(false); - }); - it('should show the fitting option when enabled', () => { const component = mount( ); @@ -82,9 +35,7 @@ describe('Missing values option', () => { const component = mount( ); diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/missing_values_option.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/missing_values_option.tsx index b12e2d2f57112c..a858d1c879efe6 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/missing_values_option.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/visual_options_popover/missing_values_option.tsx @@ -7,85 +7,23 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; -import { EuiButtonGroup, EuiFormRow, EuiIconTip, EuiSuperSelect, EuiText } from '@elastic/eui'; +import { EuiFormRow, EuiIconTip, EuiSuperSelect, EuiText } from '@elastic/eui'; import { fittingFunctionDefinitions } from '../../../../common/expressions'; -import type { FittingFunction, ValueLabelConfig } from '../../../../common/expressions'; +import type { FittingFunction } from '../../../../common/expressions'; export interface MissingValuesOptionProps { - valueLabels?: ValueLabelConfig; fittingFunction?: FittingFunction; - onValueLabelChange: (newMode: ValueLabelConfig) => void; onFittingFnChange: (newMode: FittingFunction) => void; - isValueLabelsEnabled?: boolean; isFittingEnabled?: boolean; } -const valueLabelsOptions: Array<{ - id: string; - value: 'hide' | 'inside' | 'outside'; - label: string; - 'data-test-subj': string; -}> = [ - { - id: `value_labels_hide`, - value: 'hide', - label: i18n.translate('xpack.lens.xyChart.valueLabelsVisibility.auto', { - defaultMessage: 'Hide', - }), - 'data-test-subj': 'lnsXY_valueLabels_hide', - }, - { - id: `value_labels_inside`, - value: 'inside', - label: i18n.translate('xpack.lens.xyChart.valueLabelsVisibility.inside', { - defaultMessage: 'Show', - }), - 'data-test-subj': 'lnsXY_valueLabels_inside', - }, -]; - export const MissingValuesOptions: React.FC = ({ - onValueLabelChange, onFittingFnChange, - valueLabels, fittingFunction, - isValueLabelsEnabled = true, isFittingEnabled = true, }) => { - const valueLabelsVisibilityMode = valueLabels || 'hide'; - return ( <> - {isValueLabelsEnabled && ( - - {i18n.translate('xpack.lens.shared.chartValueLabelVisibilityLabel', { - defaultMessage: 'Labels', - })} -
- } - > - value === valueLabelsVisibilityMode)!.id - } - onChange={(modeId) => { - const newMode = valueLabelsOptions.find(({ id }) => id === modeId)!.value; - onValueLabelChange(newMode); - }} - /> - - )} {isFittingEnabled && ( { /> ); - expect(component.find(MissingValuesOptions).prop('isValueLabelsEnabled')).toEqual(false); + expect(component.find(ValueLabelsSettings).prop('isVisible')).toEqual(false); expect(component.find(MissingValuesOptions).prop('isFittingEnabled')).toEqual(false); }); @@ -196,7 +196,7 @@ describe('Visual options popover', () => { /> ); - expect(component.find(MissingValuesOptions).prop('isValueLabelsEnabled')).toEqual(true); + expect(component.find(ValueLabelsSettings).prop('isVisible')).toEqual(true); }); it('should hide in the popover the display option for area and line series', () => { @@ -213,7 +213,7 @@ describe('Visual options popover', () => { /> ); - expect(component.find(MissingValuesOptions).prop('isValueLabelsEnabled')).toEqual(false); + expect(component.find(ValueLabelsSettings).prop('isVisible')).toEqual(false); }); it('should keep the display option for bar series with multiple layers', () => { @@ -245,6 +245,6 @@ describe('Visual options popover', () => { /> ); - expect(component.find(MissingValuesOptions).prop('isValueLabelsEnabled')).toEqual(true); + expect(component.find(ValueLabelsSettings).prop('isVisible')).toEqual(true); }); }); diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 7291e946154774..a8d3b4a5f3e27b 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -807,8 +807,6 @@ "xpack.lens.xyChart.topAxisDisabledHelpText": "この設定は、上の軸が有効であるときにのみ適用されます。", "xpack.lens.xyChart.topAxisLabel": "上の軸", "xpack.lens.xyChart.upperBoundLabel": "上界", - "xpack.lens.xyChart.valueLabelsVisibility.auto": "非表示", - "xpack.lens.xyChart.valueLabelsVisibility.inside": "表示", "xpack.lens.xyChart.valuesHistogramDisabledHelpText": "この設定はヒストグラムで変更できません。", "xpack.lens.xyChart.valuesInLegend.help": "凡例に値を表示", "xpack.lens.xyChart.valuesPercentageDisabledHelpText": "この設定は割合エリアグラフで変更できません。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 2aa9cabb7866bc..4bd2a5907abf3c 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -817,8 +817,6 @@ "xpack.lens.xyChart.topAxisDisabledHelpText": "此设置仅在启用顶轴时应用。", "xpack.lens.xyChart.topAxisLabel": "顶轴", "xpack.lens.xyChart.upperBoundLabel": "上边界", - "xpack.lens.xyChart.valueLabelsVisibility.auto": "隐藏", - "xpack.lens.xyChart.valueLabelsVisibility.inside": "显示", "xpack.lens.xyChart.valuesHistogramDisabledHelpText": "不能在直方图上更改此设置。", "xpack.lens.xyChart.valuesInLegend.help": "在图例中显示值", "xpack.lens.xyChart.valuesPercentageDisabledHelpText": "不能在百分比面积图上更改此设置。", diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index ff5bae8aa7e616..7cacee64467239 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -256,7 +256,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { it('should show value labels on bar charts when enabled', async () => { // enable value labels await PageObjects.lens.openVisualOptions(); - await testSubjects.click('lnsXY_valueLabels_inside'); + await testSubjects.click('lns_valueLabels_inside'); await PageObjects.lens.waitForVisualization(); From 71cc3b72fe01cfd547523ce7b209d66ff04ec356 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 13:45:07 +0100 Subject: [PATCH 12/66] skip flaky suite (#115324) --- .../shared/exploratory_view/components/filter_label.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/observability/public/components/shared/exploratory_view/components/filter_label.test.tsx b/x-pack/plugins/observability/public/components/shared/exploratory_view/components/filter_label.test.tsx index 03fd23631f755e..097ea89826c386 100644 --- a/x-pack/plugins/observability/public/components/shared/exploratory_view/components/filter_label.test.tsx +++ b/x-pack/plugins/observability/public/components/shared/exploratory_view/components/filter_label.test.tsx @@ -12,7 +12,8 @@ import { FilterLabel } from './filter_label'; import * as useSeriesHook from '../hooks/use_series_filters'; import { buildFilterLabel } from '../../filter_value_label/filter_value_label'; -describe('FilterLabel', function () { +// FLAKY: https://github.com/elastic/kibana/issues/115324 +describe.skip('FilterLabel', function () { mockAppIndexPattern(); const invertFilter = jest.fn(); From b59a805fcd8176b53dc859a01306669fcb0f9ba3 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 13:47:38 +0100 Subject: [PATCH 13/66] skip flaky suite (#116033) --- test/functional/apps/visualize/_timelion.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/visualize/_timelion.ts b/test/functional/apps/visualize/_timelion.ts index bb85b6821df317..c531ada8a25737 100644 --- a/test/functional/apps/visualize/_timelion.ts +++ b/test/functional/apps/visualize/_timelion.ts @@ -257,7 +257,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { expect(value).to.eql('.es()'); }); - describe('dynamic suggestions for argument values', () => { + // FLAKY: https://github.com/elastic/kibana/issues/116033 + describe.skip('dynamic suggestions for argument values', () => { describe('.es()', () => { it('should show index pattern suggestions for index argument', async () => { await monacoEditor.setCodeEditorValue(''); From 1a2af9d7d2c5683f99fe104c21ffc5e6e804b03f Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 13:50:03 +0100 Subject: [PATCH 14/66] skip flaky suite (#116043) --- .../public/application/hooks/use_dashboard_app_state.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx index c3b4075690261e..a73967ed7117bb 100644 --- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx +++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx @@ -276,7 +276,8 @@ describe('Dashboard initial state', () => { }); }); -describe('Dashboard state sync', () => { +// FLAKY: https://github.com/elastic/kibana/issues/116043 +describe.skip('Dashboard state sync', () => { let defaultDashboardAppStateHookResult: RenderDashboardStateHookReturn; const getResult = () => defaultDashboardAppStateHookResult.renderHookResult.result.current; From 61ea89ff7da5ada75ae973ed20da92f85f48052f Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 13:54:13 +0100 Subject: [PATCH 15/66] skip flaky suite (#113080) --- .../apps/dev_tools/feature_controls/dev_tools_security.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/dev_tools/feature_controls/dev_tools_security.ts b/x-pack/test/functional/apps/dev_tools/feature_controls/dev_tools_security.ts index 5b80f6589281ad..15759486105661 100644 --- a/x-pack/test/functional/apps/dev_tools/feature_controls/dev_tools_security.ts +++ b/x-pack/test/functional/apps/dev_tools/feature_controls/dev_tools_security.ts @@ -192,7 +192,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); - describe('no dev_tools privileges', () => { + // FLAKY: https://github.com/elastic/kibana/issues/113080 + describe.skip('no dev_tools privileges', () => { before(async () => { await security.role.create('no_dev_tools_privileges_role', { kibana: [ From 35aab9e1644c3c5ad7497640fc6e1b565cf9d8af Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 13:59:07 +0100 Subject: [PATCH 16/66] skip flaky suite (#114002) --- x-pack/test/functional/apps/discover/saved_searches.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/x-pack/test/functional/apps/discover/saved_searches.ts b/x-pack/test/functional/apps/discover/saved_searches.ts index 16deecde2b0bae..f2abc6b350e5b9 100644 --- a/x-pack/test/functional/apps/discover/saved_searches.ts +++ b/x-pack/test/functional/apps/discover/saved_searches.ts @@ -31,6 +31,7 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }; // Failing: See https://github.com/elastic/kibana/issues/104578 + // FLAKY: https://github.com/elastic/kibana/issues/114002 describe.skip('Discover Saved Searches', () => { before('initialize tests', async () => { await esArchiver.load('x-pack/test/functional/es_archives/reporting/ecommerce'); From a9cd15730b71151b014175a3b5a250f1b7088510 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 14:03:17 +0100 Subject: [PATCH 17/66] skip flaky suite (#115396) --- .../public/application/sections/alert_form/alert_add.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx index 4ae570a62f7d98..ffcda22195ff59 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_add.test.tsx @@ -64,7 +64,8 @@ export const TestExpression: FunctionComponent = () => { ); }; -describe('alert_add', () => { +// FLAKY: https://github.com/elastic/kibana/issues/g +describe.skip('alert_add', () => { let wrapper: ReactWrapper; async function setup( From 1fa073f6de4f1dd31f4c064e71250b8653d20a8b Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 14:07:43 +0100 Subject: [PATCH 18/66] skip flaky suite (#116050) --- .../public/application/hooks/use_dashboard_app_state.test.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx index a73967ed7117bb..c1e46ea2edc2a1 100644 --- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx +++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx @@ -206,7 +206,8 @@ describe('Dashboard container lifecycle', () => { }); }); -describe('Dashboard initial state', () => { +// FLAKY: https://github.com/elastic/kibana/issues/116050 +describe.skip('Dashboard initial state', () => { it('Extracts state from Dashboard Saved Object', async () => { const { renderHookResult, embeddableFactoryResult } = renderDashboardAppStateHook({}); const getResult = () => renderHookResult.result.current; From de59cfe37954ea12f0c15c506de753ec882ff22f Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 14:09:51 +0100 Subject: [PATCH 19/66] skip flaky suite (#105018) --- .../public/application/hooks/use_dashboard_app_state.test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx index c1e46ea2edc2a1..3237eb106e4ec0 100644 --- a/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx +++ b/src/plugins/dashboard/public/application/hooks/use_dashboard_app_state.test.tsx @@ -207,6 +207,7 @@ describe('Dashboard container lifecycle', () => { }); // FLAKY: https://github.com/elastic/kibana/issues/116050 +// FLAKY: https://github.com/elastic/kibana/issues/105018 describe.skip('Dashboard initial state', () => { it('Extracts state from Dashboard Saved Object', async () => { const { renderHookResult, embeddableFactoryResult } = renderDashboardAppStateHook({}); From 125c5699446346b727a4649f39809457e0076445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Felix=20St=C3=BCrmer?= Date: Mon, 25 Oct 2021 15:19:59 +0200 Subject: [PATCH 20/66] [RAC] [Observability] Enable the observability alerting and cases features (#115785) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- x-pack/plugins/observability/server/index.ts | 4 ++-- x-pack/plugins/rule_registry/server/config.ts | 2 +- .../api_integration/apis/features/features/features.ts | 1 + x-pack/test/api_integration/apis/security/privileges.ts | 1 + .../api_integration/apis/security/privileges_basic.ts | 1 + .../functional/apps/apm/feature_controls/apm_security.ts | 9 ++++++++- .../infra/feature_controls/infrastructure_security.ts | 4 ++-- .../apps/infra/feature_controls/logs_security.ts | 4 ++-- .../apps/uptime/feature_controls/uptime_security.ts | 3 ++- .../observability_functional/with_rac_write.config.ts | 4 ---- 10 files changed, 20 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/observability/server/index.ts b/x-pack/plugins/observability/server/index.ts index 77595d11870939..22a469dbedbddc 100644 --- a/x-pack/plugins/observability/server/index.ts +++ b/x-pack/plugins/observability/server/index.ts @@ -32,8 +32,8 @@ export const config: PluginConfigDescriptor = { index: schema.string({ defaultValue: 'observability-annotations' }), }), unsafe: schema.object({ - alertingExperience: schema.object({ enabled: schema.boolean({ defaultValue: false }) }), - cases: schema.object({ enabled: schema.boolean({ defaultValue: false }) }), + alertingExperience: schema.object({ enabled: schema.boolean({ defaultValue: true }) }), + cases: schema.object({ enabled: schema.boolean({ defaultValue: true }) }), }), }), }; diff --git a/x-pack/plugins/rule_registry/server/config.ts b/x-pack/plugins/rule_registry/server/config.ts index 078498864f8e87..983a7504524109 100644 --- a/x-pack/plugins/rule_registry/server/config.ts +++ b/x-pack/plugins/rule_registry/server/config.ts @@ -12,7 +12,7 @@ export const config: PluginConfigDescriptor = { deprecations: ({ deprecate, unused }) => [unused('unsafe.indexUpgrade.enabled')], schema: schema.object({ write: schema.object({ - enabled: schema.boolean({ defaultValue: false }), + enabled: schema.boolean({ defaultValue: true }), }), unsafe: schema.object({ legacyMultiTenancy: schema.object({ diff --git a/x-pack/test/api_integration/apis/features/features/features.ts b/x-pack/test/api_integration/apis/features/features/features.ts index 0e9ee6cc5ea585..d5b66c4d6da97d 100644 --- a/x-pack/test/api_integration/apis/features/features/features.ts +++ b/x-pack/test/api_integration/apis/features/features/features.ts @@ -104,6 +104,7 @@ export default function ({ getService }: FtrProviderContext) { 'indexPatterns', 'graph', 'monitoring', + 'observabilityCases', 'savedObjectsManagement', 'savedObjectsTagging', 'ml', diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index f234855b84e179..4938334bb936b9 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -28,6 +28,7 @@ export default function ({ getService }: FtrProviderContext) { savedObjectsTagging: ['all', 'read'], canvas: ['all', 'read'], maps: ['all', 'read'], + observabilityCases: ['all', 'read'], fleet: ['all', 'read'], actions: ['all', 'read'], stackAlerts: ['all', 'read'], diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index ac69bfcd9d5d4c..e6fe9d87af6f34 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -30,6 +30,7 @@ export default function ({ getService }: FtrProviderContext) { savedObjectsTagging: ['all', 'read'], graph: ['all', 'read'], maps: ['all', 'read'], + observabilityCases: ['all', 'read'], canvas: ['all', 'read'], infrastructure: ['all', 'read'], logs: ['all', 'read'], diff --git a/x-pack/test/functional/apps/apm/feature_controls/apm_security.ts b/x-pack/test/functional/apps/apm/feature_controls/apm_security.ts index 7cfdf87aaf9eaf..6f6d29db1ef0ca 100644 --- a/x-pack/test/functional/apps/apm/feature_controls/apm_security.ts +++ b/x-pack/test/functional/apps/apm/feature_controls/apm_security.ts @@ -64,6 +64,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const navLinks = await appsMenu.readLinks(); expect(navLinks.map((link) => link.text)).to.eql([ 'Overview', + 'Alerts', 'APM', 'User Experience', 'Stack Management', @@ -116,7 +117,13 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows apm navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'APM', 'User Experience', 'Stack Management']); + expect(navLinks).to.eql([ + 'Overview', + 'Alerts', + 'APM', + 'User Experience', + 'Stack Management', + ]); }); it('can navigate to APM app', async () => { diff --git a/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts b/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts index 65b9019f556fde..d6e8737b72b919 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/infrastructure_security.ts @@ -62,7 +62,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows metrics navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Metrics', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Alerts', 'Metrics', 'Stack Management']); }); describe('infrastructure landing page without data', () => { @@ -159,7 +159,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows metrics navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Metrics', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Alerts', 'Metrics', 'Stack Management']); }); describe('infrastructure landing page without data', () => { diff --git a/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts b/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts index d120a6c582c7b7..d4f56ee3c9b9b0 100644 --- a/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts +++ b/x-pack/test/functional/apps/infra/feature_controls/logs_security.ts @@ -59,7 +59,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows logs navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Logs', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Alerts', 'Logs', 'Stack Management']); }); describe('logs landing page without data', () => { @@ -121,7 +121,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows logs navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Logs', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Alerts', 'Logs', 'Stack Management']); }); describe('logs landing page without data', () => { diff --git a/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts b/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts index 7867170c1801c4..977a384062f798 100644 --- a/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts +++ b/x-pack/test/functional/apps/uptime/feature_controls/uptime_security.ts @@ -68,6 +68,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { const navLinks = await appsMenu.readLinks(); expect(navLinks.map((link) => link.text)).to.eql([ 'Overview', + 'Alerts', 'Uptime', 'Stack Management', ]); @@ -121,7 +122,7 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { it('shows uptime navlink', async () => { const navLinks = (await appsMenu.readLinks()).map((link) => link.text); - expect(navLinks).to.eql(['Overview', 'Uptime', 'Stack Management']); + expect(navLinks).to.eql(['Overview', 'Alerts', 'Uptime', 'Stack Management']); }); it('can navigate to Uptime app', async () => { diff --git a/x-pack/test/observability_functional/with_rac_write.config.ts b/x-pack/test/observability_functional/with_rac_write.config.ts index 5bb7d9926af54d..dcf6b121d62584 100644 --- a/x-pack/test/observability_functional/with_rac_write.config.ts +++ b/x-pack/test/observability_functional/with_rac_write.config.ts @@ -36,10 +36,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { ...xpackFunctionalConfig.get('kbnTestServer.serverArgs'), `--elasticsearch.hosts=https://${servers.elasticsearch.hostname}:${servers.elasticsearch.port}`, `--elasticsearch.ssl.certificateAuthorities=${CA_CERT_PATH}`, - // TO DO: Remove feature flags once we're good to go - '--xpack.observability.unsafe.alertingExperience.enabled=true', - '--xpack.observability.unsafe.cases.enabled=true', - '--xpack.ruleRegistry.write.enabled=true', ], }, uiSettings: { From 1bc60b01157308504cee599a78591cb0043c859b Mon Sep 17 00:00:00 2001 From: Ahmad Bamieh Date: Mon, 25 Oct 2021 17:30:35 +0300 Subject: [PATCH 21/66] [Telemetry] add missing content-type to headers (#116120) --- src/plugins/telemetry/server/fetcher.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/telemetry/server/fetcher.ts b/src/plugins/telemetry/server/fetcher.ts index 02ac428b076679..97180f351986ee 100644 --- a/src/plugins/telemetry/server/fetcher.ts +++ b/src/plugins/telemetry/server/fetcher.ts @@ -230,6 +230,7 @@ export class FetcherTask { method: 'post', body: stats, headers: { + 'Content-Type': 'application/json', 'X-Elastic-Stack-Version': this.currentKibanaVersion, 'X-Elastic-Cluster-ID': clusterUuid, 'X-Elastic-Content-Encoding': PAYLOAD_CONTENT_ENCODING, From 1527535fcd85489f16b4d91e4888b95f8f9cf32f Mon Sep 17 00:00:00 2001 From: Pablo Machado Date: Mon, 25 Oct 2021 16:58:47 +0200 Subject: [PATCH 22/66] Update alert count table to display rules with long names (#115920) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../components/alerts_kpis/alerts_count_panel/alerts_count.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/alerts_count.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/alerts_count.tsx index f64e279fb2755b..d6b1afea985925 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/alerts_count.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_count_panel/alerts_count.tsx @@ -35,7 +35,7 @@ const getAlertsCountTableColumns = ( { field: 'key', name: selectedStackByOption, - truncateText: true, + truncateText: false, render: function DraggableStackOptionField(value: string) { return ( Date: Mon, 25 Oct 2021 16:25:44 +0100 Subject: [PATCH 23/66] skip flaky suite (#116078) --- .../apps/ml/data_frame_analytics/feature_importance.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/ml/data_frame_analytics/feature_importance.ts b/x-pack/test/functional/apps/ml/data_frame_analytics/feature_importance.ts index 8561487dff7cb8..3faee67c01a531 100644 --- a/x-pack/test/functional/apps/ml/data_frame_analytics/feature_importance.ts +++ b/x-pack/test/functional/apps/ml/data_frame_analytics/feature_importance.ts @@ -14,7 +14,8 @@ export default function ({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); const ml = getService('ml'); - describe('total feature importance panel and decision path popover', function () { + // FLAKY: https://github.com/elastic/kibana/issues/116078 + describe.skip('total feature importance panel and decision path popover', function () { const testDataList: Array<{ suiteTitle: string; archive: string; From 414a1fbf0d35513a089742f1dc494e8223b7b815 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Mon, 25 Oct 2021 17:26:45 +0200 Subject: [PATCH 24/66] [Fleet] added package upgrade info logs (#116093) * added package upgrade info logs * using log meta * logging out meta object as well --- .../server/services/package_policy.test.ts | 6 +++ .../fleet/server/services/package_policy.ts | 51 ++++++++++++++++++- 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/server/services/package_policy.test.ts b/x-pack/plugins/fleet/server/services/package_policy.test.ts index c25a1db753c73c..46747762213f19 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.test.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.test.ts @@ -578,6 +578,12 @@ describe('Package policy service', () => { }); describe('update', () => { + beforeEach(() => { + appContextService.start(createAppContextStartContractMock()); + }); + afterEach(() => { + appContextService.stop(); + }); it('should fail to update on version conflict', async () => { const savedObjectsClient = savedObjectsClientMock.create(); savedObjectsClient.get.mockResolvedValue({ diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index fa9df22eb5e8c5..c03ccfc43ebd89 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -9,7 +9,7 @@ import { omit, partition } from 'lodash'; import { i18n } from '@kbn/i18n'; import semverLte from 'semver/functions/lte'; import { getFlattenedObject } from '@kbn/std'; -import type { KibanaRequest } from 'src/core/server'; +import type { KibanaRequest, LogMeta } from 'src/core/server'; import type { ElasticsearchClient, RequestHandlerContext, @@ -84,6 +84,17 @@ export const DATA_STREAM_ALLOWED_INDEX_PRIVILEGES = new Set([ 'read_cross_cluster', ]); +interface PackagePolicyUpgradeLogMeta extends LogMeta { + package_policy_upgrade: { + package_name: string; + current_version: string; + new_version: string; + status: 'success' | 'failure'; + error?: any[]; + dryRun?: boolean; + }; +} + class PackagePolicyService { public async create( soClient: SavedObjectsClientContract, @@ -432,6 +443,23 @@ class PackagePolicyService { pkgName: packagePolicy.package.name, currentVersion: packagePolicy.package.version, }); + + const upgradeMeta: PackagePolicyUpgradeLogMeta = { + package_policy_upgrade: { + package_name: packagePolicy.package.name, + new_version: packagePolicy.package.version, + current_version: 'unknown', + status: 'success', + dryRun: false, + }, + }; + + appContextService + .getLogger() + .info( + `Package policy successfully upgraded ${JSON.stringify(upgradeMeta)}`, + upgradeMeta + ); } return newPolicy; @@ -661,6 +689,27 @@ class PackagePolicyService { const hasErrors = 'errors' in updatedPackagePolicy; + if (packagePolicy.package.version !== packageInfo.version) { + const upgradeMeta: PackagePolicyUpgradeLogMeta = { + package_policy_upgrade: { + package_name: packageInfo.name, + current_version: packagePolicy.package.version, + new_version: packageInfo.version, + status: hasErrors ? 'failure' : 'success', + error: hasErrors ? updatedPackagePolicy.errors : undefined, + dryRun: true, + }, + }; + appContextService + .getLogger() + .info( + `Package policy upgrade dry run ${ + hasErrors ? 'resulted in errors' : 'ran successfully' + } ${JSON.stringify(upgradeMeta)}`, + upgradeMeta + ); + } + return { name: updatedPackagePolicy.name, diff: [packagePolicy, updatedPackagePolicy], From 80bb1ad8dac3a7d5c28897629e8c34c14d384816 Mon Sep 17 00:00:00 2001 From: Esteban Beltran Date: Mon, 25 Oct 2021 17:48:36 +0200 Subject: [PATCH 25/66] [Security Solution] Replace badge with health indicator in endpoint details flyout (#115901) --- .../components/endpoint_details_tabs.tsx | 2 +- .../view/details/endpoint_details_content.tsx | 50 ++++++--------- .../pages/endpoint_hosts/view/index.test.tsx | 61 +++++++------------ 3 files changed, 41 insertions(+), 72 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/endpoint_details_tabs.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/endpoint_details_tabs.tsx index 8f044959f4c903..adae21b55a637f 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/endpoint_details_tabs.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/components/endpoint_details_tabs.tsx @@ -62,7 +62,7 @@ export const EndpointDetailsFlyoutTabs = memo( const selectedTab = useMemo(() => tabs.find((tab) => tab.id === show), [tabs, show]); const renderTabs = tabs.map((tab) => ( - + )); return ( diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details_content.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details_content.tsx index cc1cad52eb21cc..cb920bdbd1b03c 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details_content.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/details/endpoint_details_content.tsx @@ -13,8 +13,9 @@ import { EuiText, EuiFlexGroup, EuiFlexItem, - EuiBadge, EuiSpacer, + EuiLink, + EuiHealth, } from '@elastic/eui'; import React, { memo, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -30,7 +31,6 @@ import { getEndpointDetailsPath } from '../../../../common/routing'; import { EndpointPolicyLink } from '../components/endpoint_policy_link'; import { OutOfDate } from '../components/out_of_date'; import { EndpointAgentStatus } from '../components/endpoint_agent_status'; -import { useAppUrl } from '../../../../../common/lib/kibana/hooks'; const HostIds = styled(EuiListGroupItem)` margin-top: 0; @@ -53,9 +53,8 @@ export const EndpointDetailsContent = memo( const policyStatus = useEndpointSelector( policyResponseStatus ) as keyof typeof POLICY_STATUS_TO_BADGE_COLOR; - const { getAppUrl } = useAppUrl(); - const [policyResponseUri, policyResponseRoutePath] = useMemo(() => { + const policyResponseRoutePath = useMemo(() => { // eslint-disable-next-line @typescript-eslint/naming-convention const { selected_endpoint, show, ...currentUrlParams } = queryParams; const path = getEndpointDetailsPath({ @@ -63,8 +62,8 @@ export const EndpointDetailsContent = memo( ...currentUrlParams, selected_endpoint: details.agent.id, }); - return [getAppUrl({ path }), path]; - }, [details.agent.id, getAppUrl, queryParams]); + return path; + }, [details.agent.id, queryParams]); const policyStatusClickHandler = useNavigateByRouterEventHandler(policyResponseRoutePath); @@ -142,26 +141,20 @@ export const EndpointDetailsContent = memo( defaultMessage: 'Policy Status', }), description: ( - // https://github.com/elastic/eui/issues/4530 - // @ts-ignore - - - - - + + + + + + ), }, { @@ -185,14 +178,7 @@ export const EndpointDetailsContent = memo( ), }, ]; - }, [ - details, - hostStatus, - policyResponseUri, - policyStatus, - policyStatusClickHandler, - policyInfo, - ]); + }, [details, hostStatus, policyStatus, policyStatusClickHandler, policyInfo]); return ( <> diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx index 727c2e8a350245..45dcf5f7a0f7df 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/index.test.tsx @@ -167,7 +167,7 @@ describe('when on the endpoint list page', () => { it('should NOT display timeline', async () => { const renderResult = render(); - const timelineFlyout = await renderResult.queryByTestId('flyoutOverlay'); + const timelineFlyout = renderResult.queryByTestId('flyoutOverlay'); expect(timelineFlyout).toBeNull(); }); @@ -460,7 +460,7 @@ describe('when on the endpoint list page', () => { const outOfDates = await renderResult.findAllByTestId('rowPolicyOutOfDate'); expect(outOfDates).toHaveLength(4); - outOfDates.forEach((item, index) => { + outOfDates.forEach((item) => { expect(item.textContent).toEqual('Out-of-date'); expect(item.querySelector(`[data-euiicon-type][color=warning]`)).not.toBeNull(); }); @@ -512,8 +512,8 @@ describe('when on the endpoint list page', () => { // FLAKY: https://github.com/elastic/kibana/issues/75721 describe.skip('when polling on Endpoint List', () => { - beforeEach(async () => { - await reactTestingLibrary.act(() => { + beforeEach(() => { + reactTestingLibrary.act(() => { const hostListData = mockEndpointResultList({ total: 4 }).hosts; setEndpointListApiMockImplementation(coreStart.http, { @@ -703,8 +703,8 @@ describe('when on the endpoint list page', () => { it('should show the flyout and footer', async () => { const renderResult = await renderAndWaitForData(); - await expect(renderResult.findByTestId('endpointDetailsFlyout')).not.toBeNull(); - await expect(renderResult.queryByTestId('endpointDetailsFlyoutFooter')).not.toBeNull(); + expect(renderResult.getByTestId('endpointDetailsFlyout')).not.toBeNull(); + expect(renderResult.getByTestId('endpointDetailsFlyoutFooter')).not.toBeNull(); }); it('should display policy name value as a link', async () => { @@ -738,15 +738,6 @@ describe('when on the endpoint list page', () => { ); }); - it('should display policy status value as a link', async () => { - const renderResult = await renderAndWaitForData(); - const policyStatusLink = await renderResult.findByTestId('policyStatusValue'); - expect(policyStatusLink).not.toBeNull(); - expect(policyStatusLink.getAttribute('href')).toEqual( - `${APP_PATH}${MANAGEMENT_PATH}/endpoints?page_index=0&page_size=10&selected_endpoint=1&show=policy_response` - ); - }); - it('should update the URL when policy status link is clicked', async () => { const renderResult = await renderAndWaitForData(); const policyStatusLink = await renderResult.findByTestId('policyStatusValue'); @@ -763,10 +754,8 @@ describe('when on the endpoint list page', () => { it('should display Success overall policy status', async () => { const renderResult = await renderAndWaitForData(); const policyStatusBadge = await renderResult.findByTestId('policyStatusValue'); + expect(renderResult.getByTestId('policyStatusValue-success')).toBeTruthy(); expect(policyStatusBadge.textContent).toEqual('Success'); - expect(policyStatusBadge.getAttribute('style')).toMatch( - /background-color\: rgb\(109\, 204\, 177\)\;/ - ); }); it('should display Warning overall policy status', async () => { @@ -774,9 +763,7 @@ describe('when on the endpoint list page', () => { const renderResult = await renderAndWaitForData(); const policyStatusBadge = await renderResult.findByTestId('policyStatusValue'); expect(policyStatusBadge.textContent).toEqual('Warning'); - expect(policyStatusBadge.getAttribute('style')).toMatch( - /background-color\: rgb\(241\, 216\, 111\)\;/ - ); + expect(renderResult.getByTestId('policyStatusValue-warning')).toBeTruthy(); }); it('should display Failed overall policy status', async () => { @@ -784,9 +771,7 @@ describe('when on the endpoint list page', () => { const renderResult = await renderAndWaitForData(); const policyStatusBadge = await renderResult.findByTestId('policyStatusValue'); expect(policyStatusBadge.textContent).toEqual('Failed'); - expect(policyStatusBadge.getAttribute('style')).toMatch( - /background-color\: rgb\(255\, 126\, 98\)\;/ - ); + expect(renderResult.getByTestId('policyStatusValue-failure')).toBeTruthy(); }); it('should display Unknown overall policy status', async () => { @@ -794,9 +779,7 @@ describe('when on the endpoint list page', () => { const renderResult = await renderAndWaitForData(); const policyStatusBadge = await renderResult.findByTestId('policyStatusValue'); expect(policyStatusBadge.textContent).toEqual('Unknown'); - expect(policyStatusBadge.getAttribute('style')).toMatch( - /background-color\: rgb\(211\, 218\, 230\)\;/ - ); + expect(renderResult.getByTestId('policyStatusValue-')).toBeTruthy(); }); it('should show the Take Action button', async () => { @@ -898,7 +881,7 @@ describe('when on the endpoint list page', () => { await reactTestingLibrary.act(async () => { await middlewareSpy.waitForAction('serverReturnedEndpointList'); }); - const hostNameLinks = await renderResult.getAllByTestId('hostnameCellLink'); + const hostNameLinks = renderResult.getAllByTestId('hostnameCellLink'); reactTestingLibrary.fireEvent.click(hostNameLinks[0]); }); @@ -913,7 +896,7 @@ describe('when on the endpoint list page', () => { reactTestingLibrary.act(() => { dispatchEndpointDetailsActivityLogChanged('success', getMockData()); }); - const endpointDetailsFlyout = await renderResult.queryByTestId('endpointDetailsFlyoutBody'); + const endpointDetailsFlyout = renderResult.queryByTestId('endpointDetailsFlyoutBody'); expect(endpointDetailsFlyout).not.toBeNull(); }); @@ -926,7 +909,7 @@ describe('when on the endpoint list page', () => { reactTestingLibrary.act(() => { dispatchEndpointDetailsActivityLogChanged('success', getMockData()); }); - const logEntries = await renderResult.queryAllByTestId('timelineEntry'); + const logEntries = renderResult.queryAllByTestId('timelineEntry'); expect(logEntries.length).toEqual(3); expect(`${logEntries[0]} .euiCommentTimeline__icon--update`).not.toBe(null); expect(`${logEntries[1]} .euiCommentTimeline__icon--regular`).not.toBe(null); @@ -944,7 +927,7 @@ describe('when on the endpoint list page', () => { getMockData({ hasLogsEndpointActionResponses: true }) ); }); - const logEntries = await renderResult.queryAllByTestId('timelineEntry'); + const logEntries = renderResult.queryAllByTestId('timelineEntry'); expect(logEntries.length).toEqual(4); expect(`${logEntries[0]} .euiCommentTimeline__icon--update`).not.toBe(null); expect(`${logEntries[1]} .euiCommentTimeline__icon--update`).not.toBe(null); @@ -960,7 +943,7 @@ describe('when on the endpoint list page', () => { reactTestingLibrary.act(() => { dispatchEndpointDetailsActivityLogChanged('failed', getMockData()); }); - const emptyState = await renderResult.queryByTestId('activityLogEmpty'); + const emptyState = renderResult.queryByTestId('activityLogEmpty'); expect(emptyState).not.toBe(null); }); @@ -980,10 +963,10 @@ describe('when on the endpoint list page', () => { }); }); - const emptyState = await renderResult.queryByTestId('activityLogEmpty'); + const emptyState = renderResult.queryByTestId('activityLogEmpty'); expect(emptyState).toBe(null); - const superDatePicker = await renderResult.queryByTestId('activityLogSuperDatePicker'); + const superDatePicker = renderResult.queryByTestId('activityLogSuperDatePicker'); expect(superDatePicker).not.toBe(null); }); @@ -1002,7 +985,7 @@ describe('when on the endpoint list page', () => { reactTestingLibrary.act(() => { dispatchEndpointDetailsActivityLogChanged('success', getMockData()); }); - const logEntries = await renderResult.queryAllByTestId('timelineEntry'); + const logEntries = renderResult.queryAllByTestId('timelineEntry'); expect(logEntries.length).toEqual(3); }); @@ -1047,7 +1030,7 @@ describe('when on the endpoint list page', () => { reactTestingLibrary.act(() => { dispatchEndpointDetailsActivityLogChanged('success', getMockData()); }); - const commentTexts = await renderResult.queryAllByTestId('activityLogCommentText'); + const commentTexts = renderResult.queryAllByTestId('activityLogCommentText'); expect(commentTexts.length).toEqual(1); expect(commentTexts[0].textContent).toEqual('some comment'); expect(commentTexts[0].parentElement?.parentElement?.className).toContain( @@ -1081,7 +1064,7 @@ describe('when on the endpoint list page', () => { afterEach(reactTestingLibrary.cleanup); it('should hide the host details panel', async () => { - const endpointDetailsFlyout = await renderResult.queryByTestId('endpointDetailsFlyoutBody'); + const endpointDetailsFlyout = renderResult.queryByTestId('endpointDetailsFlyoutBody'); expect(endpointDetailsFlyout).toBeNull(); }); @@ -1328,8 +1311,8 @@ describe('when on the endpoint list page', () => { ).toBe(true); }); - it('should NOT show the flyout footer', async () => { - await expect(renderResult.queryByTestId('endpointDetailsFlyoutFooter')).toBeNull(); + it('should NOT show the flyout footer', () => { + expect(renderResult.queryByTestId('endpointDetailsFlyoutFooter')).toBeNull(); }); }); }); From 4cc94c5a45e616b23e34aaac8dab28033edff3ec Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Mon, 25 Oct 2021 16:54:32 +0100 Subject: [PATCH 26/66] [ML] Fixing index data visualizer not available when no ML nodes available (#115972) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../routing/routes/datavisualizer/index_based.tsx | 7 ------- .../application/routing/routes/new_job/index_or_search.tsx | 7 ------- 2 files changed, 14 deletions(-) diff --git a/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx b/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx index b9e866d2e00d06..04543a28ab3e6b 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/datavisualizer/index_based.tsx @@ -19,10 +19,7 @@ import { IndexDataVisualizerPage as Page } from '../../../datavisualizer/index_b import { checkBasicLicense } from '../../../license'; import { checkGetJobsCapabilitiesResolver } from '../../../capabilities/check_capabilities'; import { loadIndexPatterns } from '../../../util/index_utils'; -import { checkMlNodesAvailable } from '../../../ml_nodes_check'; import { getBreadcrumbWithUrlForApp } from '../../breadcrumbs'; -import { ML_PAGES } from '../../../../../common/constants/locator'; -import { useCreateAndNavigateToMlLink } from '../../../contexts/kibana/use_create_url'; export const indexBasedRouteFactory = ( navigateToPath: NavigateToPath, @@ -44,16 +41,12 @@ export const indexBasedRouteFactory = ( const PageWrapper: FC = ({ location, deps }) => { const { redirectToMlAccessDeniedPage } = deps; - const redirectToJobsManagementPage = useCreateAndNavigateToMlLink( - ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE - ); const { index, savedSearchId }: Record = parse(location.search, { sort: false }); const { context } = useResolver(index, savedSearchId, deps.config, { checkBasicLicense, loadIndexPatterns: () => loadIndexPatterns(deps.indexPatterns), checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), - checkMlNodesAvailable: () => checkMlNodesAvailable(redirectToJobsManagementPage), }); return ( diff --git a/x-pack/plugins/ml/public/application/routing/routes/new_job/index_or_search.tsx b/x-pack/plugins/ml/public/application/routing/routes/new_job/index_or_search.tsx index 8500d85d5580a4..53057cb16c1320 100644 --- a/x-pack/plugins/ml/public/application/routing/routes/new_job/index_or_search.tsx +++ b/x-pack/plugins/ml/public/application/routing/routes/new_job/index_or_search.tsx @@ -19,9 +19,6 @@ import { getBreadcrumbWithUrlForApp } from '../../breadcrumbs'; import { checkBasicLicense } from '../../../license'; import { loadIndexPatterns } from '../../../util/index_utils'; import { checkGetJobsCapabilitiesResolver } from '../../../capabilities/check_capabilities'; -import { checkMlNodesAvailable } from '../../../ml_nodes_check'; -import { ML_PAGES } from '../../../../../common/constants/locator'; -import { useCreateAndNavigateToMlLink } from '../../../contexts/kibana/use_create_url'; enum MODE { NEW_JOB, @@ -85,9 +82,6 @@ const PageWrapper: FC = ({ nextStepPath, deps, mode }) = } = useMlKibana(); const { redirectToMlAccessDeniedPage } = deps; - const redirectToJobsManagementPage = useCreateAndNavigateToMlLink( - ML_PAGES.ANOMALY_DETECTION_JOBS_MANAGE - ); const newJobResolvers = { ...basicResolvers(deps), @@ -98,7 +92,6 @@ const PageWrapper: FC = ({ nextStepPath, deps, mode }) = checkBasicLicense, loadIndexPatterns: () => loadIndexPatterns(deps.indexPatterns), checkGetJobsCapabilities: () => checkGetJobsCapabilitiesResolver(redirectToMlAccessDeniedPage), - checkMlNodesAvailable: () => checkMlNodesAvailable(redirectToJobsManagementPage), }; const { context } = useResolver( From d91bc28846762f916c5c8cc5faa4e6f6a61107f3 Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Mon, 25 Oct 2021 12:04:57 -0400 Subject: [PATCH 27/66] Conditionally sets ignore_throttled only when search:includeFrozen is true (#115451) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../framework/kibana_framework_adapter.ts | 62 ++++++++++--------- 1 file changed, 33 insertions(+), 29 deletions(-) diff --git a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts index 4576a2e8452ac6..b1ea0ce21b3c18 100644 --- a/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts +++ b/x-pack/plugins/infra/server/lib/adapters/framework/kibana_framework_adapter.ts @@ -5,37 +5,41 @@ * 2.0. */ +import { estypes } from '@elastic/elasticsearch'; import { IndicesExistsAlias, IndicesGet, MlGetBuckets, } from '@elastic/elasticsearch/api/requestParams'; import { TransportRequestParams } from '@elastic/elasticsearch/lib/Transport'; -import { estypes } from '@elastic/elasticsearch'; -import { SavedObjectsClientContract, ElasticsearchClient } from 'src/core/server'; -import { - InfraRouteConfig, - InfraServerPluginSetupDeps, - CallWithRequestParams, - InfraDatabaseSearchResponse, - InfraDatabaseMultiResponse, - InfraDatabaseFieldCapsResponse, - InfraDatabaseGetIndicesResponse, - InfraDatabaseGetIndicesAliasResponse, -} from './adapter_types'; -import { TSVBMetricModel } from '../../../../common/inventory_models/types'; +import { ElasticsearchClient, SavedObjectsClientContract } from 'src/core/server'; import { CoreSetup, IRouter, KibanaRequest, + RequestHandler, RouteMethod, } from '../../../../../../../src/core/server'; -import { RequestHandler } from '../../../../../../../src/core/server'; -import { InfraConfig } from '../../../plugin'; -import type { InfraPluginRequestHandlerContext } from '../../../types'; import { UI_SETTINGS } from '../../../../../../../src/plugins/data/server'; import { TimeseriesVisData } from '../../../../../../../src/plugins/vis_types/timeseries/server'; -import { InfraServerPluginStartDeps } from './adapter_types'; +import { TSVBMetricModel } from '../../../../common/inventory_models/types'; +import { InfraConfig } from '../../../plugin'; +import type { InfraPluginRequestHandlerContext } from '../../../types'; +import { + CallWithRequestParams, + InfraDatabaseFieldCapsResponse, + InfraDatabaseGetIndicesAliasResponse, + InfraDatabaseGetIndicesResponse, + InfraDatabaseMultiResponse, + InfraDatabaseSearchResponse, + InfraRouteConfig, + InfraServerPluginSetupDeps, + InfraServerPluginStartDeps, +} from './adapter_types'; + +interface FrozenIndexParams { + ignore_throttled?: boolean; +} export class KibanaFramework { public router: IRouter; @@ -133,7 +137,7 @@ export class KibanaFramework { ) { const { elasticsearch, uiSettings } = requestContext.core; - const includeFrozen = await uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); + const includeFrozen = await uiSettings.client.get(UI_SETTINGS.SEARCH_INCLUDE_FROZEN); if (endpoint === 'msearch') { const maxConcurrentShardRequests = await uiSettings.client.get( UI_SETTINGS.COURIER_MAX_CONCURRENT_SHARD_REQUESTS @@ -143,11 +147,17 @@ export class KibanaFramework { } } - const frozenIndicesParams = ['search', 'msearch'].includes(endpoint) - ? { - ignore_throttled: !includeFrozen, - } - : {}; + // Only set the "ignore_throttled" value (to false) if the Kibana setting + // for "search:includeFrozen" is true (i.e. don't ignore throttled indices, a triple negative!) + // More information: + // - https://github.com/elastic/kibana/issues/113197 + // - https://github.com/elastic/elasticsearch/pull/77479 + // + // NOTE: these params only need to be spread onto the search and msearch calls below + const frozenIndicesParams: FrozenIndexParams = {}; + if (includeFrozen) { + frozenIndicesParams.ignore_throttled = false; + } let apiResult; switch (endpoint) { @@ -166,37 +176,31 @@ export class KibanaFramework { case 'fieldCaps': apiResult = elasticsearch.client.asCurrentUser.fieldCaps({ ...params, - ...frozenIndicesParams, }); break; case 'indices.existsAlias': apiResult = elasticsearch.client.asCurrentUser.indices.existsAlias({ ...params, - ...frozenIndicesParams, } as IndicesExistsAlias); break; case 'indices.getAlias': apiResult = elasticsearch.client.asCurrentUser.indices.getAlias({ ...params, - ...frozenIndicesParams, }); break; case 'indices.get': apiResult = elasticsearch.client.asCurrentUser.indices.get({ ...params, - ...frozenIndicesParams, } as IndicesGet); break; case 'transport.request': apiResult = elasticsearch.client.asCurrentUser.transport.request({ ...params, - ...frozenIndicesParams, } as TransportRequestParams); break; case 'ml.getBuckets': apiResult = elasticsearch.client.asCurrentUser.ml.getBuckets({ ...params, - ...frozenIndicesParams, } as MlGetBuckets); break; } From 1e718a557211e1eda5fd1282c171c43daebff3fe Mon Sep 17 00:00:00 2001 From: Matthew Kime Date: Mon, 25 Oct 2021 11:10:16 -0500 Subject: [PATCH 28/66] [data views] Make data view saved objects share capable (#114408) --- .../server/saved_objects/data_views.ts | 3 +- .../apis/saved_objects_management/find.ts | 2 +- .../saved_objects_management/relationships.ts | 4 +- .../saved_objects/spaces/data.json | 23 ++++--- .../common/suites/copy_to_space.ts | 15 +++-- .../suites/resolve_copy_to_space_conflicts.ts | 67 ++++++++++--------- .../apis/resolve_copy_to_space_conflicts.ts | 5 +- 7 files changed, 67 insertions(+), 52 deletions(-) diff --git a/src/plugins/data_views/server/saved_objects/data_views.ts b/src/plugins/data_views/server/saved_objects/data_views.ts index 5bb85a9bb6e988..ca7592732c3eed 100644 --- a/src/plugins/data_views/server/saved_objects/data_views.ts +++ b/src/plugins/data_views/server/saved_objects/data_views.ts @@ -13,7 +13,8 @@ import { DATA_VIEW_SAVED_OBJECT_TYPE } from '../../common'; export const dataViewSavedObjectType: SavedObjectsType = { name: DATA_VIEW_SAVED_OBJECT_TYPE, hidden: false, - namespaceType: 'single', + namespaceType: 'multiple-isolated', + convertToMultiNamespaceTypeVersion: '8.0.0', management: { displayName: 'Data view', icon: 'indexPatternApp', diff --git a/test/api_integration/apis/saved_objects_management/find.ts b/test/api_integration/apis/saved_objects_management/find.ts index 0b744b7991b38f..ea7f297dfeb084 100644 --- a/test/api_integration/apis/saved_objects_management/find.ts +++ b/test/api_integration/apis/saved_objects_management/find.ts @@ -249,7 +249,7 @@ export default function ({ getService }: FtrProviderContext) { path: '/app/management/kibana/dataViews/dataView/8963ca30-3224-11e8-a572-ffca06da1357', uiCapabilitiesPath: 'management.kibana.indexPatterns', }, - namespaceType: 'single', + namespaceType: 'multiple-isolated', }); })); }); diff --git a/test/api_integration/apis/saved_objects_management/relationships.ts b/test/api_integration/apis/saved_objects_management/relationships.ts index 518ec29947016e..838bc05346dda6 100644 --- a/test/api_integration/apis/saved_objects_management/relationships.ts +++ b/test/api_integration/apis/saved_objects_management/relationships.ts @@ -91,7 +91,7 @@ export default function ({ getService }: FtrProviderContext) { path: '/app/management/kibana/dataViews/dataView/8963ca30-3224-11e8-a572-ffca06da1357', uiCapabilitiesPath: 'management.kibana.indexPatterns', }, - namespaceType: 'single', + namespaceType: 'multiple-isolated', hiddenType: false, }, }, @@ -132,7 +132,7 @@ export default function ({ getService }: FtrProviderContext) { path: '/app/management/kibana/dataViews/dataView/8963ca30-3224-11e8-a572-ffca06da1357', uiCapabilitiesPath: 'management.kibana.indexPatterns', }, - namespaceType: 'single', + namespaceType: 'multiple-isolated', hiddenType: false, }, relationship: 'child', diff --git a/x-pack/test/spaces_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json b/x-pack/test/spaces_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json index 3b2a87d924e88a..c1525409cfa3fc 100644 --- a/x-pack/test/spaces_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json +++ b/x-pack/test/spaces_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json @@ -153,7 +153,7 @@ "references": [ { "type": "index-pattern", - "id": "cts_ip_1", + "id": "cts_ip_1_default", "name": "CTS IP 1" } ], @@ -182,7 +182,7 @@ "references": [ { "type": "index-pattern", - "id": "cts_ip_1", + "id": "cts_ip_1_default", "name": "CTS IP 1" } ], @@ -212,7 +212,7 @@ "references": [ { "type": "index-pattern", - "id": "cts_ip_1", + "id": "cts_ip_1_default", "name": "CTS IP 1" } ], @@ -276,7 +276,7 @@ "references": [ { "type": "index-pattern", - "id": "cts_ip_1", + "id": "cts_ip_1_space_1", "name": "CTS IP 1" } ], @@ -305,7 +305,7 @@ "references": [ { "type": "index-pattern", - "id": "cts_ip_1", + "id": "cts_ip_1_space_1", "name": "CTS IP 1" } ], @@ -335,7 +335,7 @@ "references": [ { "type": "index-pattern", - "id": "cts_ip_1", + "id": "cts_ip_1_space_1", "name": "CTS IP 1" } ], @@ -350,15 +350,17 @@ { "type": "_doc", "value": { - "id": "index-pattern:cts_ip_1", + "id": "index-pattern:cts_ip_1_default", "index": ".kibana", "source": { + "originId": "cts_ip_1", "index-pattern": { "title": "Copy to Space index pattern 1 from default space" }, "references": [], "type": "index-pattern", - "updated_at": "2017-09-21T18:49:16.270Z" + "updated_at": "2017-09-21T18:49:16.270Z", + "namespaces": ["default"] }, "type": "_doc" } @@ -367,16 +369,17 @@ { "type": "_doc", "value": { - "id": "space_1:index-pattern:cts_ip_1", + "id": "index-pattern:cts_ip_1_space_1", "index": ".kibana", "source": { + "originId": "cts_ip_1", "index-pattern": { "title": "Copy to Space index pattern 1 from space_1 space" }, "references": [], "type": "index-pattern", "updated_at": "2017-09-21T18:49:16.270Z", - "namespace": "space_1" + "namespaces": ["space_1"] }, "type": "_doc" } diff --git a/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts b/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts index 3a3f0f889c91c4..23136838f3002e 100644 --- a/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts +++ b/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts @@ -183,6 +183,8 @@ export function copyToSpaceTestSuiteFactory( const destination = getDestinationWithoutConflicts(); const result = resp.body as CopyResponse; + const indexPatternDestinationId = result[destination].successResults![0].destinationId; + expect(indexPatternDestinationId).to.match(UUID_PATTERN); // this was copied to space 2 and hit an unresolvable conflict, so the object ID was regenerated silently / the destinationId is a UUID const vis1DestinationId = result[destination].successResults![1].destinationId; expect(vis1DestinationId).to.match(UUID_PATTERN); // this was copied to space 2 and hit an unresolvable conflict, so the object ID was regenerated silently / the destinationId is a UUID const vis2DestinationId = result[destination].successResults![2].destinationId; @@ -196,12 +198,13 @@ export function copyToSpaceTestSuiteFactory( successCount: 5, successResults: [ { - id: 'cts_ip_1', + id: `cts_ip_1_${spaceId}`, type: 'index-pattern', meta: { icon: 'indexPatternApp', title: `Copy to Space index pattern 1 from ${spaceId} space`, }, + destinationId: indexPatternDestinationId, }, { id: `cts_vis_1_${spaceId}`, @@ -321,13 +324,14 @@ export function copyToSpaceTestSuiteFactory( successCount: 5, successResults: [ { - id: 'cts_ip_1', + id: `cts_ip_1_${spaceId}`, type: 'index-pattern', meta: { icon: 'indexPatternApp', title: `Copy to Space index pattern 1 from ${spaceId} space`, }, overwrite: true, + destinationId: `cts_ip_1_${destination}`, // this conflicted with another index pattern in the destination space because of a shared originId }, { id: `cts_vis_1_${spaceId}`, @@ -409,8 +413,11 @@ export function copyToSpaceTestSuiteFactory( }, }, { - error: { type: 'conflict' }, - id: 'cts_ip_1', + error: { + type: 'conflict', + destinationId: `cts_ip_1_${destination}`, // this conflicted with another index pattern in the destination space because of a shared originId + }, + id: `cts_ip_1_${spaceId}`, title: `Copy to Space index pattern 1 from ${spaceId} space`, type: 'index-pattern', meta: { diff --git a/x-pack/test/spaces_api_integration/common/suites/resolve_copy_to_space_conflicts.ts b/x-pack/test/spaces_api_integration/common/suites/resolve_copy_to_space_conflicts.ts index b190a37965b0bc..72130743b69d95 100644 --- a/x-pack/test/spaces_api_integration/common/suites/resolve_copy_to_space_conflicts.ts +++ b/x-pack/test/spaces_api_integration/common/suites/resolve_copy_to_space_conflicts.ts @@ -82,8 +82,18 @@ export function resolveCopyToSpaceConflictsSuite( expect(result).to.eql({ [destination]: { success: true, - successCount: 1, + successCount: 2, successResults: [ + { + id: `cts_ip_1_${sourceSpaceId}`, + type: 'index-pattern', + meta: { + title: `Copy to Space index pattern 1 from ${sourceSpaceId} space`, + icon: 'indexPatternApp', + }, + destinationId: `cts_ip_1_${destination}`, // this conflicted with another index pattern in the destination space because of a shared originId + overwrite: true, + }, { id: `cts_vis_3_${sourceSpaceId}`, type: 'visualization', @@ -146,6 +156,19 @@ export function resolveCopyToSpaceConflictsSuite( success: false, successCount: 0, errors: [ + { + error: { + type: 'conflict', + destinationId: `cts_ip_1_${destination}`, // this conflicted with another index pattern in the destination space because of a shared originId + }, + id: `cts_ip_1_${sourceSpaceId}`, + title: `Copy to Space index pattern 1 from ${sourceSpaceId} space`, + meta: { + title: `Copy to Space index pattern 1 from ${sourceSpaceId} space`, + icon: 'indexPatternApp', + }, + type: 'index-pattern', + }, { error: { type: 'conflict', @@ -231,35 +254,7 @@ export function resolveCopyToSpaceConflictsSuite( { statusCode: 403, error: 'Forbidden', - message: 'Unable to bulk_get index-pattern', - }, - ], - }, - } as CopyResponse); - - // Query ES to ensure that nothing was copied - const [dashboard, visualization] = await getObjectsAtSpace(destination); - expect(dashboard.attributes.title).to.eql( - `This is the ${destination} test space CTS dashboard` - ); - expect(visualization.attributes.title).to.eql(`CTS vis 3 from ${destination} space`); - }; - - const createExpectReadonlyAtSpaceWithReferencesResult = - (spaceId: string = DEFAULT_SPACE_ID) => - async (resp: TestResponse) => { - const destination = getDestinationSpace(spaceId); - - const result = resp.body as CopyResponse; - expect(result).to.eql({ - [destination]: { - success: false, - successCount: 0, - errors: [ - { - statusCode: 403, - error: 'Forbidden', - message: 'Unable to bulk_create visualization', + message: 'Unable to bulk_create index-pattern,visualization', }, ], }, @@ -449,6 +444,7 @@ export function resolveCopyToSpaceConflictsSuite( const dashboardObject = { type: 'dashboard', id: 'cts_dashboard' }; const visualizationObject = { type: 'visualization', id: `cts_vis_3_${spaceId}` }; + const indexPatternObject = { type: 'index-pattern', id: `cts_ip_1_${spaceId}` }; it(`should return ${tests.withReferencesNotOverwriting.statusCode} when not overwriting, with references`, async () => { const destination = getDestinationSpace(spaceId); @@ -462,6 +458,11 @@ export function resolveCopyToSpaceConflictsSuite( createNewCopies: false, retries: { [destination]: [ + { + ...indexPatternObject, + destinationId: `cts_ip_1_${destination}`, + overwrite: false, + }, { ...visualizationObject, destinationId: `cts_vis_3_${destination}`, @@ -486,6 +487,11 @@ export function resolveCopyToSpaceConflictsSuite( createNewCopies: false, retries: { [destination]: [ + { + ...indexPatternObject, + destinationId: `cts_ip_1_${destination}`, + overwrite: true, + }, { ...visualizationObject, destinationId: `cts_vis_3_${destination}`, @@ -589,7 +595,6 @@ export function resolveCopyToSpaceConflictsSuite( createExpectNonOverriddenResponseWithReferences, createExpectNonOverriddenResponseWithoutReferences, createExpectUnauthorizedAtSpaceWithReferencesResult, - createExpectReadonlyAtSpaceWithReferencesResult, createExpectUnauthorizedAtSpaceWithoutReferencesResult, createMultiNamespaceTestCases, originSpaces: ['default', 'space_1'], diff --git a/x-pack/test/spaces_api_integration/security_and_spaces/apis/resolve_copy_to_space_conflicts.ts b/x-pack/test/spaces_api_integration/security_and_spaces/apis/resolve_copy_to_space_conflicts.ts index efc7827cf8b9a7..1b39cd5d77302a 100644 --- a/x-pack/test/spaces_api_integration/security_and_spaces/apis/resolve_copy_to_space_conflicts.ts +++ b/x-pack/test/spaces_api_integration/security_and_spaces/apis/resolve_copy_to_space_conflicts.ts @@ -24,7 +24,6 @@ export default function resolveCopyToSpaceConflictsTestSuite({ getService }: Ftr createExpectOverriddenResponseWithoutReferences, expectRouteForbiddenResponse, createExpectUnauthorizedAtSpaceWithReferencesResult, - createExpectReadonlyAtSpaceWithReferencesResult, createExpectUnauthorizedAtSpaceWithoutReferencesResult, createMultiNamespaceTestCases, NON_EXISTENT_SPACE_ID, @@ -122,11 +121,11 @@ export default function resolveCopyToSpaceConflictsTestSuite({ getService }: Ftr tests: { withReferencesNotOverwriting: { statusCode: 200, - response: createExpectReadonlyAtSpaceWithReferencesResult(spaceId), + response: createExpectUnauthorizedAtSpaceWithReferencesResult(spaceId), }, withReferencesOverwriting: { statusCode: 200, - response: createExpectReadonlyAtSpaceWithReferencesResult(spaceId), + response: createExpectUnauthorizedAtSpaceWithReferencesResult(spaceId), }, withoutReferencesOverwriting: { statusCode: 200, From 33fd1bdff0556e899e37e6885b3c11f7c4bc33ac Mon Sep 17 00:00:00 2001 From: Thomas Neirynck Date: Mon, 25 Oct 2021 12:41:04 -0400 Subject: [PATCH 29/66] [Maps] Use ES mvt (#114553) * tmp * tmp * tmp * tmp * tmp * use es naming * typo * organize files for clarity * plugin for hits * tmp * initial styling * more boilerplate * tmp * temp * add size support * remove junk * tooltip * edits * too many features * rename for clarity * typing * tooltip improvements * icon * callouts * align count handling * typechecks * i18n * tmp * type fixes * linting * convert to ts and disable option * readd test dependencies * typescheck * update yarn lock * fix typecheck * update snapshot * fix snapshot * fix snapshot * fix snapshot * fix snapshot * fix test * fix tests * fix test * add key * fix integration test * move test * use centroid placement * more text fixes * more test fixes * Remove top terms aggregations when switching to super fine resolution (#114667) * [Maps] MVT metrics * remove js file * updateSourceProps * i18n cleanup * mvt labels * remove isPointsOnly from IVectorSource interface * move get_centroid_featues to vector_layer since its no longer used in server * labels * warn users when selecting scaling type that does not support term joins * clean up scaling_form * remove IField.isCountable method * move pluck code from common to dynamic_style_property * move convert_to_geojson to es_geo_grid_source folder * remove getMbFeatureIdPropertyName from IVectorLayer * clean up cleanTooltipStateForLayer * use euiWarningColor for too many features outline * update jest snapshots and eslint fixes * update docs for incomplete data changes * move tooManyFeatures MB layer definition from VectorLayer to TiledVectorLayer, clean up VectorSource interface * remove commented out filter in tooltip_control add api docs for getMbLayerIds and getMbTooltipLayerIds * revert changing getSourceTooltipContent to getSourceTooltipConfigFromGeoJson * replace DEFAULT_MAX_RESULT_WINDOW with loading maxResultWindow as data request * clean up * eslint * remove unused constants from Kibana MVT implemenation and tooManyFeaturesImage * add better should method for tiled_vector_layer.getCustomIconAndTooltipContent jest test * fix tooltips not being displayed for super-fine clusters and grids * fix check in getFeatureId for es_Search_sources only * eslint, remove __kbn_metadata_feature__ filter from mapbox style expects * remove geoFieldType paramter for tile API * remove searchSessionId from MVT url since its no longer used * tslint * vector tile scaling option copy update * fix getTile and getGridTile API integration tests * remove size from _mvt request body, size provided in query * eslint, fix test expect * stablize jest test * track total hits for _mvt request * track total hits take 2 * align vector tile copy * eslint * revert change to EsSearchSource._loadTooltipProperties with regards to handling undefined _index. MVT now provides _index * clean up * only send metric aggregations to mvt/getGridTile endpoint * update snapshot, update getGridTile URLs in tests * update request URL for getGridTile * eslint Co-authored-by: Nathan Reese Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- docs/maps/vector-layer.asciidoc | 4 +- package.json | 2 +- x-pack/plugins/maps/common/constants.ts | 10 +- .../layer_descriptor_types.ts | 17 +- .../maps/common/elasticsearch_util/index.ts | 1 - .../maps/common/get_geometry_counts.ts | 45 -- .../maps/common/pluck_category_field_meta.ts | 46 -- .../maps/common/pluck_range_field_meta.ts | 34 -- .../public/actions/data_request_actions.ts | 21 +- .../maps/public/actions/layer_actions.ts | 32 +- .../maps/public/actions/map_actions.ts | 4 +- .../maps/public/actions/tooltip_actions.ts | 15 +- .../public/classes/fields/agg/agg_field.ts | 4 + .../classes/fields/agg/count_agg_field.ts | 4 + .../fields/agg/top_term_percentage_field.ts | 4 + .../maps/public/classes/fields/field.ts | 5 + .../maps/public/classes/layers/layer.tsx | 16 +- .../tiled_vector_layer.test.tsx.snap | 14 +- .../tiled_vector_layer.test.tsx | 4 +- .../tiled_vector_layer/tiled_vector_layer.tsx | 202 +++++-- .../vector_layer/assign_feature_ids.test.ts | 17 +- .../layers/vector_layer/assign_feature_ids.ts | 18 +- .../get_centroid_features.test.ts | 29 - .../vector_layer}/get_centroid_features.ts | 7 +- .../classes/layers/vector_layer/index.ts | 1 + .../classes/layers/vector_layer/utils.tsx | 2 +- .../layers/vector_layer/vector_layer.tsx | 101 ++-- .../sources/es_agg_source/es_agg_source.ts | 8 +- .../resolution_editor.test.tsx.snap | 136 ++--- .../update_source_editor.test.tsx.snap | 9 +- .../convert_to_geojson.d.ts | 2 +- .../es_geo_grid_source}/convert_to_geojson.js | 11 +- .../convert_to_geojson.test.ts | 2 +- .../es_geo_grid_source.test.ts | 21 +- .../es_geo_grid_source/es_geo_grid_source.tsx | 38 +- .../es_geo_grid_source/resolution_editor.js | 61 -- .../resolution_editor.test.tsx | 2 +- .../es_geo_grid_source/resolution_editor.tsx | 161 ++++++ .../update_source_editor.test.tsx | 9 +- ...rce_editor.js => update_source_editor.tsx} | 78 ++- .../es_search_source/create_source_editor.js | 2 + .../es_search_source/es_search_source.test.ts | 20 +- .../es_search_source/es_search_source.tsx | 31 +- .../es_search_source/update_source_editor.js | 4 + .../__snapshots__/scaling_form.test.tsx.snap | 24 +- .../util/scaling_form.test.tsx | 2 + .../es_search_source/util/scaling_form.tsx | 134 +++-- .../classes/sources/es_source/es_source.ts | 2 +- .../mvt_field_config_editor.test.tsx.snap | 5 - .../mvt_field_config_editor.tsx | 6 +- .../mvt_single_layer_vector_source.tsx | 4 + .../maps/public/classes/sources/source.ts | 11 +- .../sources/vector_source/vector_source.tsx | 7 +- .../vector_style_editor.test.tsx.snap | 540 ------------------ .../components/vector_style_editor.test.tsx | 46 +- .../vector/components/vector_style_editor.tsx | 20 +- .../properties/dynamic_color_property.tsx | 6 +- .../properties/dynamic_icon_property.tsx | 4 +- .../properties/dynamic_size_property.tsx | 4 +- .../properties/dynamic_style_property.tsx | 121 ++-- .../classes/styles/vector/vector_style.tsx | 61 +- .../classes/util/geo_tile_utils.test.ts} | 0 .../classes/util}/geo_tile_utils.ts | 6 +- .../classes/util/mb_filter_expressions.ts | 21 +- .../edit_layer_panel.test.tsx.snap | 4 + .../edit_layer_panel.test.tsx | 10 +- .../edit_layer_panel/edit_layer_panel.tsx | 23 +- .../edit_layer_panel/index.ts | 12 +- .../join_editor/join_editor.tsx | 2 - .../draw_feature_control.tsx | 7 +- .../connected_components/mb_map/mb_map.tsx | 9 - .../tooltip_control/tooltip_control.test.tsx | 13 + .../tooltip_control/tooltip_control.tsx | 31 +- .../maps/server/kibana_server_services.ts | 3 + .../plugins/maps/server/mvt/get_grid_tile.ts | 64 +++ x-pack/plugins/maps/server/mvt/get_tile.ts | 437 +------------- x-pack/plugins/maps/server/mvt/mvt_routes.ts | 37 +- x-pack/plugins/maps/server/mvt/util.ts | 75 --- .../apis/maps/get_grid_tile.js | 109 ++-- .../api_integration/apis/maps/get_tile.js | 78 +-- .../functional/apps/maps/mapbox_styles.js | 28 - .../test/functional/apps/maps/mvt_scaling.js | 31 +- .../functional/apps/maps/mvt_super_fine.js | 6 +- 83 files changed, 1201 insertions(+), 2056 deletions(-) delete mode 100644 x-pack/plugins/maps/common/get_geometry_counts.ts delete mode 100644 x-pack/plugins/maps/common/pluck_category_field_meta.ts delete mode 100644 x-pack/plugins/maps/common/pluck_range_field_meta.ts rename x-pack/plugins/maps/{common => public/classes/layers/vector_layer}/get_centroid_features.test.ts (93%) rename x-pack/plugins/maps/{common => public/classes/layers/vector_layer}/get_centroid_features.ts (94%) rename x-pack/plugins/maps/{common/elasticsearch_util => public/classes/sources/es_geo_grid_source}/convert_to_geojson.d.ts (89%) rename x-pack/plugins/maps/{common/elasticsearch_util => public/classes/sources/es_geo_grid_source}/convert_to_geojson.js (89%) rename x-pack/plugins/maps/{common/elasticsearch_util => public/classes/sources/es_geo_grid_source}/convert_to_geojson.test.ts (98%) delete mode 100644 x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.js create mode 100644 x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.tsx rename x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/{update_source_editor.js => update_source_editor.tsx} (61%) rename x-pack/plugins/maps/{common/geo_tile_utils.test.js => public/classes/util/geo_tile_utils.test.ts} (100%) rename x-pack/plugins/maps/{common => public/classes/util}/geo_tile_utils.ts (95%) create mode 100644 x-pack/plugins/maps/server/mvt/get_grid_tile.ts delete mode 100644 x-pack/plugins/maps/server/mvt/util.ts diff --git a/docs/maps/vector-layer.asciidoc b/docs/maps/vector-layer.asciidoc index 7191197c27dbed..f70e4d59796cc6 100644 --- a/docs/maps/vector-layer.asciidoc +++ b/docs/maps/vector-layer.asciidoc @@ -27,9 +27,9 @@ Results exceeding `index.max_result_window` are not displayed. * *Show clusters when results exceed 10,000* When results exceed `index.max_result_window`, the layer uses {ref}/search-aggregations-bucket-geotilegrid-aggregation.html[GeoTile grid aggregation] to group your documents into clusters and displays metrics for each cluster. When results are less then `index.max_result_window`, the layer displays features from individual documents. -* *Use vector tiles.* Vector tiles partition your map into 6 to 8 tiles. +* *Use vector tiles.* Vector tiles partition your map into tiles. Each tile request is limited to the `index.max_result_window` index setting. -Tiles exceeding `index.max_result_window` have a visual indicator when there are too many features to display. +When a tile exceeds `index.max_result_window`, results exceeding `index.max_result_window` are not contained in the tile and a dashed rectangle outlining the bounding box containing all geo values within the tile is displayed. *EMS Boundaries*:: Administrative boundaries from https://www.elastic.co/elastic-maps-service[Elastic Maps Service]. diff --git a/package.json b/package.json index e6b17783197bc5..177b70efd4cc7a 100644 --- a/package.json +++ b/package.json @@ -166,7 +166,6 @@ "@mapbox/geojson-rewind": "^0.5.0", "@mapbox/mapbox-gl-draw": "1.3.0", "@mapbox/mapbox-gl-rtl-text": "0.2.3", - "@mapbox/vector-tile": "1.3.1", "@reduxjs/toolkit": "^1.6.1", "@slack/webhook": "^5.0.4", "@turf/along": "6.0.1", @@ -460,6 +459,7 @@ "@kbn/test": "link:bazel-bin/packages/kbn-test", "@kbn/test-subj-selector": "link:bazel-bin/packages/kbn-test-subj-selector", "@loaders.gl/polyfills": "^2.3.5", + "@mapbox/vector-tile": "1.3.1", "@microsoft/api-documenter": "7.7.2", "@microsoft/api-extractor": "7.7.0", "@octokit/rest": "^16.35.0", diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index b6b3e636fffeb3..42c5b705140002 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -47,14 +47,7 @@ export const CHECK_IS_DRAWING_INDEX = `/${GIS_API_PATH}/checkIsDrawingIndex`; export const MVT_GETTILE_API_PATH = 'mvt/getTile'; export const MVT_GETGRIDTILE_API_PATH = 'mvt/getGridTile'; -export const MVT_SOURCE_LAYER_NAME = 'source_layer'; -// Identifies vector tile "too many features" feature. -// "too many features" feature is a box showing area that contains too many features for single ES search response -export const KBN_METADATA_FEATURE = '__kbn_metadata_feature__'; -export const KBN_FEATURE_COUNT = '__kbn_feature_count__'; -export const KBN_IS_TILE_COMPLETE = '__kbn_is_tile_complete__'; -export const KBN_VECTOR_SHAPE_TYPE_COUNTS = '__kbn_vector_shape_type_counts__'; -export const KBN_TOO_MANY_FEATURES_IMAGE_ID = '__kbn_too_many_features_image_id__'; + // Identifies centroid feature. // Centroids are a single point for representing lines, multiLines, polygons, and multiPolygons export const KBN_IS_CENTROID_FEATURE = '__kbn_is_centroid_feature__'; @@ -119,7 +112,6 @@ export const DEFAULT_MAX_RESULT_WINDOW = 10000; export const DEFAULT_MAX_INNER_RESULT_WINDOW = 100; export const DEFAULT_MAX_BUCKETS_LIMIT = 65535; -export const FEATURE_ID_PROPERTY_NAME = '__kbn__feature_id__'; export const FEATURE_VISIBLE_PROPERTY_NAME = '__kbn_isvisibleduetojoin__'; export const MB_SOURCE_ID_LAYER_ID_PREFIX_DELIMITER = '_'; diff --git a/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts b/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts index 244ebc59efd173..8f681cc9de70de 100644 --- a/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts +++ b/x-pack/plugins/maps/common/descriptor_types/layer_descriptor_types.ts @@ -10,21 +10,13 @@ import { Query } from 'src/plugins/data/public'; import { Feature } from 'geojson'; import { - FieldMeta, HeatmapStyleDescriptor, StyleDescriptor, VectorStyleDescriptor, } from './style_property_descriptor_types'; import { DataRequestDescriptor } from './data_request_descriptor_types'; import { AbstractSourceDescriptor, TermJoinSourceDescriptor } from './source_descriptor_types'; -import { VectorShapeTypeCounts } from '../get_geometry_counts'; -import { - KBN_FEATURE_COUNT, - KBN_IS_TILE_COMPLETE, - KBN_METADATA_FEATURE, - KBN_VECTOR_SHAPE_TYPE_COUNTS, - LAYER_TYPE, -} from '../constants'; +import { LAYER_TYPE } from '../constants'; export type Attribution = { label: string; @@ -38,11 +30,8 @@ export type JoinDescriptor = { export type TileMetaFeature = Feature & { properties: { - [KBN_METADATA_FEATURE]: true; - [KBN_IS_TILE_COMPLETE]: boolean; - [KBN_FEATURE_COUNT]: number; - [KBN_VECTOR_SHAPE_TYPE_COUNTS]: VectorShapeTypeCounts; - fieldMeta?: FieldMeta; + 'hits.total.relation': string; + 'hits.total.value': number; }; }; diff --git a/x-pack/plugins/maps/common/elasticsearch_util/index.ts b/x-pack/plugins/maps/common/elasticsearch_util/index.ts index 7073a4201f7a5a..6febb237cdda71 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/index.ts +++ b/x-pack/plugins/maps/common/elasticsearch_util/index.ts @@ -6,7 +6,6 @@ */ export * from './es_agg_utils'; -export * from './convert_to_geojson'; export * from './elasticsearch_geo_utils'; export * from './spatial_filter_utils'; export * from './types'; diff --git a/x-pack/plugins/maps/common/get_geometry_counts.ts b/x-pack/plugins/maps/common/get_geometry_counts.ts deleted file mode 100644 index 2a3368560c7625..00000000000000 --- a/x-pack/plugins/maps/common/get_geometry_counts.ts +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 { Feature } from 'geojson'; -import { GEO_JSON_TYPE, VECTOR_SHAPE_TYPE } from './constants'; - -export interface VectorShapeTypeCounts { - [VECTOR_SHAPE_TYPE.POINT]: number; - [VECTOR_SHAPE_TYPE.LINE]: number; - [VECTOR_SHAPE_TYPE.POLYGON]: number; -} - -export function countVectorShapeTypes(features: Feature[]): VectorShapeTypeCounts { - const vectorShapeTypeCounts: VectorShapeTypeCounts = { - [VECTOR_SHAPE_TYPE.POINT]: 0, - [VECTOR_SHAPE_TYPE.LINE]: 0, - [VECTOR_SHAPE_TYPE.POLYGON]: 0, - }; - - for (let i = 0; i < features.length; i++) { - const feature: Feature = features[i]; - if ( - feature.geometry.type === GEO_JSON_TYPE.POINT || - feature.geometry.type === GEO_JSON_TYPE.MULTI_POINT - ) { - vectorShapeTypeCounts[VECTOR_SHAPE_TYPE.POINT] += 1; - } else if ( - feature.geometry.type === GEO_JSON_TYPE.LINE_STRING || - feature.geometry.type === GEO_JSON_TYPE.MULTI_LINE_STRING - ) { - vectorShapeTypeCounts[VECTOR_SHAPE_TYPE.LINE] += 1; - } else if ( - feature.geometry.type === GEO_JSON_TYPE.POLYGON || - feature.geometry.type === GEO_JSON_TYPE.MULTI_POLYGON - ) { - vectorShapeTypeCounts[VECTOR_SHAPE_TYPE.POLYGON] += 1; - } - } - - return vectorShapeTypeCounts; -} diff --git a/x-pack/plugins/maps/common/pluck_category_field_meta.ts b/x-pack/plugins/maps/common/pluck_category_field_meta.ts deleted file mode 100644 index c71316f864a848..00000000000000 --- a/x-pack/plugins/maps/common/pluck_category_field_meta.ts +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 { Feature } from 'geojson'; -import { CategoryFieldMeta } from './descriptor_types'; - -export function pluckCategoryFieldMeta( - features: Feature[], - name: string, - size: number -): CategoryFieldMeta | null { - const counts = new Map(); - for (let i = 0; i < features.length; i++) { - const feature = features[i]; - const term = feature.properties ? feature.properties[name] : undefined; - // properties object may be sparse, so need to check if the field is effectively present - if (typeof term !== undefined) { - if (counts.has(term)) { - counts.set(term, counts.get(term) + 1); - } else { - counts.set(term, 1); - } - } - } - - return trimCategories(counts, size); -} - -export function trimCategories(counts: Map, size: number): CategoryFieldMeta { - const ordered = []; - for (const [key, value] of counts) { - ordered.push({ key, count: value }); - } - - ordered.sort((a, b) => { - return b.count - a.count; - }); - const truncated = ordered.slice(0, size); - return { - categories: truncated, - } as CategoryFieldMeta; -} diff --git a/x-pack/plugins/maps/common/pluck_range_field_meta.ts b/x-pack/plugins/maps/common/pluck_range_field_meta.ts deleted file mode 100644 index b0bf03896892f6..00000000000000 --- a/x-pack/plugins/maps/common/pluck_range_field_meta.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 { Feature } from 'geojson'; -import { RangeFieldMeta } from './descriptor_types'; - -export function pluckRangeFieldMeta( - features: Feature[], - name: string, - parseValue: (rawValue: unknown) => number -): RangeFieldMeta | null { - let min = Infinity; - let max = -Infinity; - for (let i = 0; i < features.length; i++) { - const feature = features[i]; - const newValue = feature.properties ? parseValue(feature.properties[name]) : NaN; - if (!isNaN(newValue)) { - min = Math.min(min, newValue); - max = Math.max(max, newValue); - } - } - - return min === Infinity || max === -Infinity - ? null - : ({ - min, - max, - delta: max - min, - } as RangeFieldMeta); -} diff --git a/x-pack/plugins/maps/public/actions/data_request_actions.ts b/x-pack/plugins/maps/public/actions/data_request_actions.ts index b912e8c52e6800..c1a6d05cc05779 100644 --- a/x-pack/plugins/maps/public/actions/data_request_actions.ts +++ b/x-pack/plugins/maps/public/actions/data_request_actions.ts @@ -282,10 +282,10 @@ function endDataLoad( if (dataId === SOURCE_DATA_REQUEST_ID) { const features = data && 'features' in data ? (data as FeatureCollection).features : []; + const layer = getLayerById(layerId, getState()); const eventHandlers = getEventHandlers(getState()); if (eventHandlers && eventHandlers.onDataLoadEnd) { - const layer = getLayerById(layerId, getState()); const resultMeta: ResultMeta = {}; if (layer && layer.getType() === LAYER_TYPE.VECTOR) { const featuresWithoutCentroids = features.filter((feature) => { @@ -301,7 +301,9 @@ function endDataLoad( }); } - dispatch(updateTooltipStateForLayer(layerId, features)); + if (layer) { + dispatch(updateTooltipStateForLayer(layer, features)); + } } dispatch({ @@ -344,7 +346,10 @@ function onDataLoadError( }); } - dispatch(updateTooltipStateForLayer(layerId)); + const layer = getLayerById(layerId, getState()); + if (layer) { + dispatch(updateTooltipStateForLayer(layer)); + } } dispatch({ @@ -359,7 +364,10 @@ function onDataLoadError( } export function updateSourceDataRequest(layerId: string, newData: object) { - return (dispatch: ThunkDispatch) => { + return ( + dispatch: ThunkDispatch, + getState: () => MapStoreState + ) => { dispatch({ type: UPDATE_SOURCE_DATA_REQUEST, dataId: SOURCE_DATA_REQUEST_ID, @@ -368,7 +376,10 @@ export function updateSourceDataRequest(layerId: string, newData: object) { }); if ('features' in newData) { - dispatch(updateTooltipStateForLayer(layerId, (newData as FeatureCollection).features)); + const layer = getLayerById(layerId, getState()); + if (layer) { + dispatch(updateTooltipStateForLayer(layer, (newData as FeatureCollection).features)); + } } dispatch(updateStyleMeta(layerId)); diff --git a/x-pack/plugins/maps/public/actions/layer_actions.ts b/x-pack/plugins/maps/public/actions/layer_actions.ts index 9e937d86515e2b..c9254df40bcf17 100644 --- a/x-pack/plugins/maps/public/actions/layer_actions.ts +++ b/x-pack/plugins/maps/public/actions/layer_actions.ts @@ -51,6 +51,7 @@ import { } from '../../common/descriptor_types'; import { ILayer } from '../classes/layers/layer'; import { IVectorLayer } from '../classes/layers/vector_layer'; +import { OnSourceChangeArgs } from '../classes/sources/source'; import { DRAW_MODE, LAYER_STYLE_TYPE, LAYER_TYPE } from '../../common/constants'; import { IVectorStyle } from '../classes/styles/vector/vector_style'; import { notifyLicensedFeatureUsage } from '../licensed_features'; @@ -217,7 +218,7 @@ export function setLayerVisibility(layerId: string, makeVisible: boolean) { } if (!makeVisible) { - dispatch(updateTooltipStateForLayer(layerId)); + dispatch(updateTooltipStateForLayer(layer)); } dispatch({ @@ -323,18 +324,17 @@ function updateMetricsProp(layerId: string, value: unknown) { ) => { const layer = getLayerById(layerId, getState()); const previousFields = await (layer as IVectorLayer).getFields(); - await dispatch({ + dispatch({ type: UPDATE_SOURCE_PROP, layerId, propName: 'metrics', value, }); await dispatch(updateStyleProperties(layerId, previousFields as IESAggField[])); - dispatch(syncDataForLayerId(layerId, false)); }; } -export function updateSourceProp( +function updateSourcePropWithoutSync( layerId: string, propName: string, value: unknown, @@ -356,6 +356,28 @@ export function updateSourceProp( if (newLayerType) { dispatch(updateLayerType(layerId, newLayerType)); } + }; +} + +export function updateSourceProp( + layerId: string, + propName: string, + value: unknown, + newLayerType?: LAYER_TYPE +) { + return async (dispatch: ThunkDispatch) => { + await dispatch(updateSourcePropWithoutSync(layerId, propName, value, newLayerType)); + dispatch(syncDataForLayerId(layerId, false)); + }; +} + +export function updateSourceProps(layerId: string, sourcePropChanges: OnSourceChangeArgs[]) { + return async (dispatch: ThunkDispatch) => { + // Using for loop to ensure update completes before starting next update + for (let i = 0; i < sourcePropChanges.length; i++) { + const { propName, value, newLayerType } = sourcePropChanges[i]; + await dispatch(updateSourcePropWithoutSync(layerId, propName, value, newLayerType)); + } dispatch(syncDataForLayerId(layerId, false)); }; } @@ -504,7 +526,7 @@ function removeLayerFromLayerList(layerId: string) { layerGettingRemoved.getInFlightRequestTokens().forEach((requestToken) => { dispatch(cancelRequest(requestToken)); }); - dispatch(updateTooltipStateForLayer(layerId)); + dispatch(updateTooltipStateForLayer(layerGettingRemoved)); layerGettingRemoved.destroy(); dispatch({ type: REMOVE_LAYER, diff --git a/x-pack/plugins/maps/public/actions/map_actions.ts b/x-pack/plugins/maps/public/actions/map_actions.ts index cf1e22ab90f883..d921f9748f65cd 100644 --- a/x-pack/plugins/maps/public/actions/map_actions.ts +++ b/x-pack/plugins/maps/public/actions/map_actions.ts @@ -63,7 +63,7 @@ import { INITIAL_LOCATION } from '../../common/constants'; import { updateTooltipStateForLayer } from './tooltip_actions'; import { VectorLayer } from '../classes/layers/vector_layer'; import { SET_DRAW_MODE } from './ui_actions'; -import { expandToTileBoundaries } from '../../common/geo_tile_utils'; +import { expandToTileBoundaries } from '../classes/util/geo_tile_utils'; import { getToasts } from '../kibana_services'; export function setMapInitError(errorMessage: string) { @@ -171,7 +171,7 @@ export function mapExtentChanged(mapExtentState: MapExtentState) { if (prevZoom !== nextZoom) { getLayerList(getState()).map((layer) => { if (!layer.showAtZoomLevel(nextZoom)) { - dispatch(updateTooltipStateForLayer(layer.getId())); + dispatch(updateTooltipStateForLayer(layer)); } }); } diff --git a/x-pack/plugins/maps/public/actions/tooltip_actions.ts b/x-pack/plugins/maps/public/actions/tooltip_actions.ts index 67b6842caeb467..30213510c8be45 100644 --- a/x-pack/plugins/maps/public/actions/tooltip_actions.ts +++ b/x-pack/plugins/maps/public/actions/tooltip_actions.ts @@ -10,9 +10,11 @@ import { Dispatch } from 'redux'; import { Feature } from 'geojson'; import { getOpenTooltips } from '../selectors/map_selectors'; import { SET_OPEN_TOOLTIPS } from './map_action_constants'; -import { FEATURE_ID_PROPERTY_NAME, FEATURE_VISIBLE_PROPERTY_NAME } from '../../common/constants'; +import { FEATURE_VISIBLE_PROPERTY_NAME } from '../../common/constants'; import { TooltipFeature, TooltipState } from '../../common/descriptor_types'; import { MapStoreState } from '../reducers/store'; +import { ILayer } from '../classes/layers/layer'; +import { IVectorLayer, getFeatureId, isVectorLayer } from '../classes/layers/vector_layer'; export function closeOnClickTooltip(tooltipId: string) { return (dispatch: Dispatch, getState: () => MapStoreState) => { @@ -62,13 +64,17 @@ export function openOnHoverTooltip(tooltipState: TooltipState) { }; } -export function updateTooltipStateForLayer(layerId: string, layerFeatures: Feature[] = []) { +export function updateTooltipStateForLayer(layer: ILayer, layerFeatures: Feature[] = []) { return (dispatch: Dispatch, getState: () => MapStoreState) => { + if (!isVectorLayer(layer)) { + return; + } + const openTooltips = getOpenTooltips(getState()) .map((tooltipState) => { const nextFeatures: TooltipFeature[] = []; tooltipState.features.forEach((tooltipFeature) => { - if (tooltipFeature.layerId !== layerId) { + if (tooltipFeature.layerId !== layer.getId()) { // feature from another layer, keep it nextFeatures.push(tooltipFeature); } @@ -79,7 +85,8 @@ export function updateTooltipStateForLayer(layerId: string, layerFeatures: Featu ? layerFeature.properties![FEATURE_VISIBLE_PROPERTY_NAME] : true; return ( - isVisible && layerFeature.properties![FEATURE_ID_PROPERTY_NAME] === tooltipFeature.id + isVisible && + getFeatureId(layerFeature, (layer as IVectorLayer).getSource()) === tooltipFeature.id ); }); diff --git a/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts index 70d5cea6e4620c..acfe6a9055eb66 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/agg_field.ts @@ -34,6 +34,10 @@ export class AggField extends CountAggField { return !!this._esDocField; } + getMbFieldName(): string { + return this._source.isMvt() ? this.getName() + '.value' : this.getName(); + } + supportsFieldMeta(): boolean { // count and sum aggregations are not within field bounds so they do not support field meta. return !isMetricCountable(this._getAggType()); diff --git a/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts index 3bd26666005a62..b303dbc342bb26 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/count_agg_field.ts @@ -43,6 +43,10 @@ export class CountAggField implements IESAggField { return this._source.getAggKey(this._getAggType(), this.getRootName()); } + getMbFieldName(): string { + return this._source.isMvt() ? '_count' : this.getName(); + } + getRootName(): string { return ''; } diff --git a/x-pack/plugins/maps/public/classes/fields/agg/top_term_percentage_field.ts b/x-pack/plugins/maps/public/classes/fields/agg/top_term_percentage_field.ts index f6cdcf43fe3438..227084bfe0cad5 100644 --- a/x-pack/plugins/maps/public/classes/fields/agg/top_term_percentage_field.ts +++ b/x-pack/plugins/maps/public/classes/fields/agg/top_term_percentage_field.ts @@ -23,6 +23,10 @@ export class TopTermPercentageField implements IESAggField { return this._topTermAggField.getSource(); } + getMbFieldName(): string { + return this.getName(); + } + getOrigin(): FIELD_ORIGIN { return this._topTermAggField.getOrigin(); } diff --git a/x-pack/plugins/maps/public/classes/fields/field.ts b/x-pack/plugins/maps/public/classes/fields/field.ts index 586f9f74da8ace..014d75caf90b67 100644 --- a/x-pack/plugins/maps/public/classes/fields/field.ts +++ b/x-pack/plugins/maps/public/classes/fields/field.ts @@ -11,6 +11,7 @@ import { ITooltipProperty, TooltipProperty } from '../tooltips/tooltip_property' export interface IField { getName(): string; + getMbFieldName(): string; getRootName(): string; canValueBeFormatted(): boolean; getLabel(): Promise; @@ -50,6 +51,10 @@ export class AbstractField implements IField { return this._fieldName; } + getMbFieldName(): string { + return this.getName(); + } + getRootName(): string { return this.getName(); } diff --git a/x-pack/plugins/maps/public/classes/layers/layer.tsx b/x-pack/plugins/maps/public/classes/layers/layer.tsx index e1043a33f28adf..051115a0726083 100644 --- a/x-pack/plugins/maps/public/classes/layers/layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/layer.tsx @@ -63,13 +63,18 @@ export interface ILayer { getStyleForEditing(): IStyle; getCurrentStyle(): IStyle; getImmutableSourceProperties(): Promise; - renderSourceSettingsEditor({ onChange }: SourceEditorArgs): ReactElement | null; + renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs): ReactElement | null; isLayerLoading(): boolean; isLoadingBounds(): boolean; isFilteredByGlobalTime(): Promise; hasErrors(): boolean; getErrors(): string; + + /* + * ILayer.getMbLayerIds returns a list of all mapbox layers assoicated with this layer. + */ getMbLayerIds(): string[]; + ownsMbLayerId(mbLayerId: string): boolean; ownsMbSourceId(mbSourceId: string): boolean; syncLayerWithMB(mbMap: MbMap, timeslice?: Timeslice): void; @@ -77,7 +82,7 @@ export interface ILayer { isInitialDataLoadComplete(): boolean; getIndexPatternIds(): string[]; getQueryableIndexPatternIds(): string[]; - getType(): LAYER_TYPE | undefined; + getType(): LAYER_TYPE; isVisible(): boolean; cloneDescriptor(): Promise; renderStyleEditor( @@ -325,9 +330,8 @@ export class AbstractLayer implements ILayer { return await source.getImmutableProperties(); } - renderSourceSettingsEditor({ onChange }: SourceEditorArgs) { - const source = this.getSourceForEditing(); - return source.renderSourceSettingsEditor({ onChange, currentLayerType: this._descriptor.type }); + renderSourceSettingsEditor(sourceEditorArgs: SourceEditorArgs) { + return this.getSourceForEditing().renderSourceSettingsEditor(sourceEditorArgs); } getPrevRequestToken(dataId: string): symbol | undefined { @@ -437,7 +441,7 @@ export class AbstractLayer implements ILayer { mbMap.setLayoutProperty(mbLayerId, 'visibility', this.isVisible() ? 'visible' : 'none'); } - getType(): LAYER_TYPE | undefined { + getType(): LAYER_TYPE { return this._descriptor.type as LAYER_TYPE; } diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/__snapshots__/tiled_vector_layer.test.tsx.snap b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/__snapshots__/tiled_vector_layer.test.tsx.snap index d3b96936a85a1b..8b4911342f8415 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/__snapshots__/tiled_vector_layer.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/__snapshots__/tiled_vector_layer.test.tsx.snap @@ -1,9 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`icon should use no data icon 1`] = ` - `; diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx index e1f134cdf2a855..fd78ea2ebde596 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.test.tsx @@ -95,8 +95,8 @@ describe('visiblity', () => { }); }); -describe('icon', () => { - it('should use no data icon', async () => { +describe('getCustomIconAndTooltipContent', () => { + it('Layers with non-elasticsearch sources should display icon', async () => { const layer: TiledVectorLayer = createLayer({}, {}); const iconAndTooltipContent = layer.getCustomIconAndTooltipContent(); diff --git a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx index 9b5298685865a4..ece57af7b54ce1 100644 --- a/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/tiled_vector_layer/tiled_vector_layer.tsx @@ -7,39 +7,44 @@ import type { Map as MbMap, + AnyLayer as MbLayer, GeoJSONSource as MbGeoJSONSource, VectorSource as MbVectorSource, } from '@kbn/mapbox-gl'; import { Feature } from 'geojson'; +import { i18n } from '@kbn/i18n'; import uuid from 'uuid/v4'; import { parse as parseUrl } from 'url'; -import { i18n } from '@kbn/i18n'; +import { euiThemeVars } from '@kbn/ui-shared-deps-src/theme'; import { IVectorStyle, VectorStyle } from '../../styles/vector/vector_style'; +import { LAYER_TYPE, SOURCE_DATA_REQUEST_ID, SOURCE_TYPES } from '../../../../common/constants'; import { - KBN_FEATURE_COUNT, - KBN_IS_TILE_COMPLETE, - KBN_METADATA_FEATURE, - LAYER_TYPE, - SOURCE_DATA_REQUEST_ID, -} from '../../../../common/constants'; -import { + NO_RESULTS_ICON_AND_TOOLTIPCONTENT, VectorLayer, VectorLayerArguments, - NO_RESULTS_ICON_AND_TOOLTIPCONTENT, } from '../vector_layer'; import { ITiledSingleLayerVectorSource } from '../../sources/tiled_single_layer_vector_source'; import { DataRequestContext } from '../../../actions'; import { - Timeslice, StyleMetaDescriptor, + TileMetaFeature, + Timeslice, VectorLayerDescriptor, VectorSourceRequestMeta, - TileMetaFeature, } from '../../../../common/descriptor_types'; import { MVTSingleLayerVectorSourceConfig } from '../../sources/mvt_single_layer_vector_source/types'; +import { ESSearchSource } from '../../sources/es_search_source'; import { canSkipSourceUpdate } from '../../util/can_skip_fetch'; import { CustomIconAndTooltipContent } from '../layer'; +const ES_MVT_META_LAYER_NAME = 'meta'; +const ES_MVT_HITS_TOTAL_RELATION = 'hits.total.relation'; +const ES_MVT_HITS_TOTAL_VALUE = 'hits.total.value'; +const MAX_RESULT_WINDOW_DATA_REQUEST_ID = 'maxResultWindow'; + +/* + * MVT vector layer + */ export class TiledVectorLayer extends VectorLayer { static type = LAYER_TYPE.TILED_VECTOR; @@ -70,13 +75,46 @@ export class TiledVectorLayer extends VectorLayer { } getCustomIconAndTooltipContent(): CustomIconAndTooltipContent { - const tileMetas = this._getMetaFromTiles(); - if (!tileMetas.length) { + const icon = this.getCurrentStyle().getIcon(); + if (!this.getSource().isESSource()) { + // Only ES-sources can have a special meta-tile, not 3rd party vector tile sources + return { + icon, + tooltipContent: null, + areResultsTrimmed: false, + }; + } + + // + // TODO ES MVT specific - move to es_tiled_vector_layer implementation + // + + const tileMetaFeatures = this._getMetaFromTiles(); + if (!tileMetaFeatures.length) { return NO_RESULTS_ICON_AND_TOOLTIPCONTENT; } - const totalFeaturesCount: number = tileMetas.reduce((acc: number, tileMeta: Feature) => { - const count = tileMeta && tileMeta.properties ? tileMeta.properties[KBN_FEATURE_COUNT] : 0; + if (this.getSource().getType() !== SOURCE_TYPES.ES_SEARCH) { + // aggregation ES sources are never trimmed + return { + icon, + tooltipContent: null, + areResultsTrimmed: false, + }; + } + + const maxResultWindow = this._getMaxResultWindow(); + if (maxResultWindow === undefined) { + return { + icon, + tooltipContent: null, + areResultsTrimmed: false, + }; + } + + const totalFeaturesCount: number = tileMetaFeatures.reduce((acc: number, tileMeta: Feature) => { + const count = + tileMeta && tileMeta.properties ? tileMeta.properties[ES_MVT_HITS_TOTAL_VALUE] : 0; return count + acc; }, 0); @@ -84,12 +122,16 @@ export class TiledVectorLayer extends VectorLayer { return NO_RESULTS_ICON_AND_TOOLTIPCONTENT; } - const isIncomplete: boolean = tileMetas.some((tileMeta: Feature) => { - return !tileMeta?.properties?.[KBN_IS_TILE_COMPLETE]; + const isIncomplete: boolean = tileMetaFeatures.some((tileMeta: TileMetaFeature) => { + if (tileMeta?.properties?.[ES_MVT_HITS_TOTAL_RELATION] === 'gte') { + return tileMeta?.properties?.[ES_MVT_HITS_TOTAL_VALUE] >= maxResultWindow + 1; + } else { + return false; + } }); return { - icon: this.getCurrentStyle().getIcon(), + icon, tooltipContent: isIncomplete ? i18n.translate('xpack.maps.tiles.resultsTrimmedMsg', { defaultMessage: `Results limited to {count} documents.`, @@ -107,6 +149,27 @@ export class TiledVectorLayer extends VectorLayer { }; } + _getMaxResultWindow(): number | undefined { + const dataRequest = this.getDataRequest(MAX_RESULT_WINDOW_DATA_REQUEST_ID); + if (!dataRequest) { + return; + } + const data = dataRequest.getData() as { maxResultWindow: number } | undefined; + return data ? data.maxResultWindow : undefined; + } + + async _syncMaxResultWindow({ startLoading, stopLoading }: DataRequestContext) { + const prevDataRequest = this.getDataRequest(MAX_RESULT_WINDOW_DATA_REQUEST_ID); + if (prevDataRequest) { + return; + } + + const requestToken = Symbol(`${this.getId()}-${MAX_RESULT_WINDOW_DATA_REQUEST_ID}`); + startLoading(MAX_RESULT_WINDOW_DATA_REQUEST_ID, requestToken); + const maxResultWindow = await (this.getSource() as ESSearchSource).getMaxResultWindow(); + stopLoading(MAX_RESULT_WINDOW_DATA_REQUEST_ID, requestToken, { maxResultWindow }); + } + async _syncMVTUrlTemplate({ startLoading, stopLoading, @@ -141,6 +204,7 @@ export class TiledVectorLayer extends VectorLayer { }, }); const canSkip = noChangesInSourceState && noChangesInSearchState; + if (canSkip) { return null; } @@ -180,6 +244,9 @@ export class TiledVectorLayer extends VectorLayer { } async syncData(syncContext: DataRequestContext) { + if (this.getSource().getType() === SOURCE_TYPES.ES_SEARCH) { + await this._syncMaxResultWindow(syncContext); + } await this._syncSourceStyleMeta(syncContext, this._source, this._style as IVectorStyle); await this._syncSourceFormatters(syncContext, this._source, this._style as IVectorStyle); await this._syncMVTUrlTemplate(syncContext); @@ -213,10 +280,18 @@ export class TiledVectorLayer extends VectorLayer { }); } + getMbLayerIds() { + return [...super.getMbLayerIds(), this._getMbTooManyFeaturesLayerId()]; + } + ownsMbSourceId(mbSourceId: string): boolean { return this._getMbSourceId() === mbSourceId; } + _getMbTooManyFeaturesLayerId() { + return this.makeMbLayerId('toomanyfeatures'); + } + _syncStylePropertiesWithMb(mbMap: MbMap) { // @ts-ignore const mbSource = mbMap.getSource(this._getMbSourceId()); @@ -236,10 +311,52 @@ export class TiledVectorLayer extends VectorLayer { this._setMbPointsProperties(mbMap, sourceMeta.layerName); this._setMbLinePolygonProperties(mbMap, sourceMeta.layerName); - this._setMbCentroidProperties(mbMap, sourceMeta.layerName); + this._setMbLabelProperties(mbMap, sourceMeta.layerName); + this._syncTooManyFeaturesProperties(mbMap); + } + + // TODO ES MVT specific - move to es_tiled_vector_layer implementation + _syncTooManyFeaturesProperties(mbMap: MbMap) { + if (this.getSource().getType() !== SOURCE_TYPES.ES_SEARCH) { + return; + } + + const maxResultWindow = this._getMaxResultWindow(); + if (maxResultWindow === undefined) { + return; + } + + const tooManyFeaturesLayerId = this._getMbTooManyFeaturesLayerId(); + + if (!mbMap.getLayer(tooManyFeaturesLayerId)) { + const mbTooManyFeaturesLayer: MbLayer = { + id: tooManyFeaturesLayerId, + type: 'line', + source: this.getId(), + paint: {}, + }; + mbTooManyFeaturesLayer['source-layer'] = ES_MVT_META_LAYER_NAME; + mbMap.addLayer(mbTooManyFeaturesLayer); + mbMap.setFilter(tooManyFeaturesLayerId, [ + 'all', + ['==', ['get', ES_MVT_HITS_TOTAL_RELATION], 'gte'], + ['>=', ['get', ES_MVT_HITS_TOTAL_VALUE], maxResultWindow + 1], + ]); + mbMap.setPaintProperty(tooManyFeaturesLayerId, 'line-color', euiThemeVars.euiColorWarning); + mbMap.setPaintProperty(tooManyFeaturesLayerId, 'line-width', 3); + mbMap.setPaintProperty(tooManyFeaturesLayerId, 'line-dasharray', [2, 1]); + mbMap.setPaintProperty(tooManyFeaturesLayerId, 'line-opacity', this.getAlpha()); + } + + this.syncVisibilityWithMb(mbMap, tooManyFeaturesLayerId); + mbMap.setLayerZoomRange(tooManyFeaturesLayerId, this.getMinZoom(), this.getMaxZoom()); } queryTileMetaFeatures(mbMap: MbMap): TileMetaFeature[] | null { + if (!this.getSource().isESSource()) { + return null; + } + // @ts-ignore const mbSource = mbMap.getSource(this._getMbSourceId()); if (!mbSource) { @@ -259,26 +376,38 @@ export class TiledVectorLayer extends VectorLayer { // querySourceFeatures can return duplicated features when features cross tile boundaries. // Tile meta will never have duplicated features since by there nature, tile meta is a feature contained within a single tile const mbFeatures = mbMap.querySourceFeatures(this._getMbSourceId(), { - sourceLayer: sourceMeta.layerName, - filter: ['==', ['get', KBN_METADATA_FEATURE], true], + sourceLayer: ES_MVT_META_LAYER_NAME, }); - const metaFeatures: TileMetaFeature[] = mbFeatures.map((mbFeature: Feature) => { + const metaFeatures: Array = ( + mbFeatures as unknown as TileMetaFeature[] + ).map((mbFeature: TileMetaFeature | null) => { const parsedProperties: Record = {}; - for (const key in mbFeature.properties) { - if (mbFeature.properties.hasOwnProperty(key)) { - parsedProperties[key] = JSON.parse(mbFeature.properties[key]); // mvt properties cannot be nested geojson + for (const key in mbFeature?.properties) { + if (mbFeature?.properties.hasOwnProperty(key)) { + parsedProperties[key] = + typeof mbFeature.properties[key] === 'string' || + typeof mbFeature.properties[key] === 'number' || + typeof mbFeature.properties[key] === 'boolean' + ? mbFeature.properties[key] + : JSON.parse(mbFeature.properties[key]); // mvt properties cannot be nested geojson } } - return { - type: 'Feature', - id: mbFeature.id, - geometry: mbFeature.geometry, - properties: parsedProperties, - } as TileMetaFeature; + + try { + return { + type: 'Feature', + id: mbFeature?.id, + geometry: mbFeature?.geometry, // this getter might throw with non-conforming geometries + properties: parsedProperties, + } as TileMetaFeature; + } catch (e) { + return null; + } }); - return metaFeatures as TileMetaFeature[]; + const filtered = metaFeatures.filter((f) => f !== null); + return filtered as TileMetaFeature[]; } _requiresPrevSourceCleanup(mbMap: MbMap): boolean { @@ -317,8 +446,13 @@ export class TiledVectorLayer extends VectorLayer { const mbLayer = mbMap.getLayer(layerIds[i]); // The mapbox type in the spec is specified with `source-layer` // but the programmable JS-object uses camelcase `sourceLayer` - // @ts-expect-error - if (mbLayer && mbLayer.sourceLayer !== tiledSourceMeta.layerName) { + if ( + mbLayer && + // @ts-expect-error + mbLayer.sourceLayer !== tiledSourceMeta.layerName && + // @ts-expect-error + mbLayer.sourceLayer !== ES_MVT_META_LAYER_NAME + ) { // If the source-pointer of one of the layers is stale, they will all be stale. // In this case, all the mb-layers need to be removed and re-added. return true; diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/assign_feature_ids.test.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/assign_feature_ids.test.ts index 137d443b39b914..2250e86da0ec22 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/assign_feature_ids.test.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/assign_feature_ids.test.ts @@ -5,8 +5,7 @@ * 2.0. */ -import { assignFeatureIds } from './assign_feature_ids'; -import { FEATURE_ID_PROPERTY_NAME } from '../../../../common/constants'; +import { assignFeatureIds, GEOJSON_FEATURE_ID_PROPERTY_NAME } from './assign_feature_ids'; import { FeatureCollection, Feature, Point } from 'geojson'; const featureId = 'myFeature1'; @@ -34,7 +33,7 @@ test('should provide unique id when feature.id is not provided', () => { expect(typeof feature1.id).toBe('number'); expect(typeof feature2.id).toBe('number'); // @ts-ignore - expect(feature1.id).toBe(feature1.properties[FEATURE_ID_PROPERTY_NAME]); + expect(feature1.id).toBe(feature1.properties[GEOJSON_FEATURE_ID_PROPERTY_NAME]); expect(feature1.id).not.toBe(feature2.id); }); @@ -53,9 +52,9 @@ test('should preserve feature id when provided', () => { const feature1 = updatedFeatureCollection.features[0]; expect(typeof feature1.id).toBe('number'); // @ts-ignore - expect(feature1.id).not.toBe(feature1.properties[FEATURE_ID_PROPERTY_NAME]); + expect(feature1.id).not.toBe(feature1.properties[GEOJSON_FEATURE_ID_PROPERTY_NAME]); // @ts-ignore - expect(feature1.properties[FEATURE_ID_PROPERTY_NAME]).toBe(featureId); + expect(feature1.properties[GEOJSON_FEATURE_ID_PROPERTY_NAME]).toBe(featureId); }); test('should preserve feature id for falsy value', () => { @@ -73,9 +72,9 @@ test('should preserve feature id for falsy value', () => { const feature1 = updatedFeatureCollection.features[0]; expect(typeof feature1.id).toBe('number'); // @ts-ignore - expect(feature1.id).not.toBe(feature1.properties[FEATURE_ID_PROPERTY_NAME]); + expect(feature1.id).not.toBe(feature1.properties[GEOJSON_FEATURE_ID_PROPERTY_NAME]); // @ts-ignore - expect(feature1.properties[FEATURE_ID_PROPERTY_NAME]).toBe(0); + expect(feature1.properties[GEOJSON_FEATURE_ID_PROPERTY_NAME]).toBe(0); }); test('should not modify original feature properties', () => { @@ -94,6 +93,6 @@ test('should not modify original feature properties', () => { const updatedFeatureCollection = assignFeatureIds(featureCollection); const feature1 = updatedFeatureCollection.features[0]; // @ts-ignore - expect(feature1.properties[FEATURE_ID_PROPERTY_NAME]).toBe(featureId); - expect(featureProperties).not.toHaveProperty(FEATURE_ID_PROPERTY_NAME); + expect(feature1.properties[GEOJSON_FEATURE_ID_PROPERTY_NAME]).toBe(featureId); + expect(featureProperties).not.toHaveProperty(GEOJSON_FEATURE_ID_PROPERTY_NAME); }); diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/assign_feature_ids.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/assign_feature_ids.ts index c40c8299ad04c2..53ce15439e8159 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/assign_feature_ids.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/assign_feature_ids.ts @@ -7,7 +7,11 @@ import _ from 'lodash'; import { FeatureCollection, Feature } from 'geojson'; -import { FEATURE_ID_PROPERTY_NAME } from '../../../../common/constants'; +import { SOURCE_TYPES } from '../../../../common/constants'; +import { IVectorSource } from '../../sources/vector_source'; + +export const GEOJSON_FEATURE_ID_PROPERTY_NAME = '__kbn__feature_id__'; +export const ES_MVT_FEATURE_ID_PROPERTY_NAME = '_id'; let idCounter = 0; @@ -43,7 +47,7 @@ export function assignFeatureIds(featureCollection: FeatureCollection): FeatureC geometry: feature.geometry, // do not copy geometry, this object can be massive properties: { // preserve feature id provided by source so features can be referenced across fetches - [FEATURE_ID_PROPERTY_NAME]: feature.id == null ? numericId : feature.id, + [GEOJSON_FEATURE_ID_PROPERTY_NAME]: feature.id == null ? numericId : feature.id, // create new object for properties so original is not polluted with kibana internal props ...feature.properties, }, @@ -56,3 +60,13 @@ export function assignFeatureIds(featureCollection: FeatureCollection): FeatureC features, }; } + +export function getFeatureId(feature: Feature, source: IVectorSource): string | number | undefined { + if (!source.isMvt()) { + return feature.properties?.[GEOJSON_FEATURE_ID_PROPERTY_NAME]; + } + + return source.getType() === SOURCE_TYPES.ES_SEARCH + ? feature.properties?.[ES_MVT_FEATURE_ID_PROPERTY_NAME] + : feature.id; +} diff --git a/x-pack/plugins/maps/common/get_centroid_features.test.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/get_centroid_features.test.ts similarity index 93% rename from x-pack/plugins/maps/common/get_centroid_features.test.ts rename to x-pack/plugins/maps/public/classes/layers/vector_layer/get_centroid_features.test.ts index 0fac9dc3a355ff..2b8d03a2c3f8c7 100644 --- a/x-pack/plugins/maps/common/get_centroid_features.test.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/get_centroid_features.test.ts @@ -44,35 +44,6 @@ test('should not create centroid feature for point and multipoint', () => { expect(centroidFeatures.length).toBe(0); }); -test('should not create centroid for the metadata polygon', () => { - const polygonFeature: Feature = { - type: 'Feature', - geometry: { - type: 'Polygon', - coordinates: [ - [ - [35, 10], - [45, 45], - [15, 40], - [10, 20], - [35, 10], - ], - ], - }, - properties: { - __kbn_metadata_feature__: true, - prop0: 'value0', - prop1: 0.0, - }, - }; - const featureCollection: FeatureCollection = { - type: 'FeatureCollection', - features: [polygonFeature], - }; - const centroidFeatures = getCentroidFeatures(featureCollection); - expect(centroidFeatures.length).toBe(0); -}); - test('should create centroid feature for line (even number of points)', () => { const lineFeature: Feature = { type: 'Feature', diff --git a/x-pack/plugins/maps/common/get_centroid_features.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/get_centroid_features.ts similarity index 94% rename from x-pack/plugins/maps/common/get_centroid_features.ts rename to x-pack/plugins/maps/public/classes/layers/vector_layer/get_centroid_features.ts index 8aaeb56576a844..6afe61f8a16b9c 100644 --- a/x-pack/plugins/maps/common/get_centroid_features.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/get_centroid_features.ts @@ -21,18 +21,13 @@ import turfArea from '@turf/area'; import turfCenterOfMass from '@turf/center-of-mass'; import turfLength from '@turf/length'; import { lineString, polygon } from '@turf/helpers'; -import { GEO_JSON_TYPE, KBN_IS_CENTROID_FEATURE, KBN_METADATA_FEATURE } from './constants'; +import { GEO_JSON_TYPE, KBN_IS_CENTROID_FEATURE } from '../../../../common/constants'; export function getCentroidFeatures(featureCollection: FeatureCollection): Feature[] { const centroids = []; for (let i = 0; i < featureCollection.features.length; i++) { const feature = featureCollection.features[i]; - // do not add centroid for kibana added features - if (feature.properties?.[KBN_METADATA_FEATURE]) { - continue; - } - const centroid = getCentroid(feature); if (centroid) { centroids.push(centroid); diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/index.ts b/x-pack/plugins/maps/public/classes/layers/vector_layer/index.ts index cb964f77613da1..80d83996d8fd62 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/index.ts +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/index.ts @@ -13,3 +13,4 @@ export { VectorLayerArguments, NO_RESULTS_ICON_AND_TOOLTIPCONTENT, } from './vector_layer'; +export { getFeatureId } from './assign_feature_ids'; diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx index 8e4eb349036ea1..cc30f30fe98987 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/utils.tsx @@ -24,7 +24,7 @@ import { DataRequestContext } from '../../../actions'; import { IVectorSource } from '../../sources/vector_source'; import { DataRequestAbortError } from '../../util/data_request'; import { DataRequest } from '../../util/data_request'; -import { getCentroidFeatures } from '../../../../common/get_centroid_features'; +import { getCentroidFeatures } from './get_centroid_features'; import { canSkipSourceUpdate } from '../../util/can_skip_fetch'; import { assignFeatureIds } from './assign_feature_ids'; diff --git a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx index 3faf92715451c3..cd1b644e9cfba5 100644 --- a/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx +++ b/x-pack/plugins/maps/public/classes/layers/vector_layer/vector_layer.tsx @@ -21,20 +21,16 @@ import { AbstractLayer } from '../layer'; import { IVectorStyle, VectorStyle } from '../../styles/vector/vector_style'; import { AGG_TYPE, - FEATURE_ID_PROPERTY_NAME, SOURCE_META_DATA_REQUEST_ID, SOURCE_FORMATTERS_DATA_REQUEST_ID, FEATURE_VISIBLE_PROPERTY_NAME, EMPTY_FEATURE_COLLECTION, - KBN_METADATA_FEATURE, LAYER_TYPE, FIELD_ORIGIN, - KBN_TOO_MANY_FEATURES_IMAGE_ID, FieldFormatter, SOURCE_TYPES, STYLE_TYPE, SUPPORTS_FEATURE_EDITING_REQUEST_ID, - KBN_IS_TILE_COMPLETE, VECTOR_STYLES, } from '../../../../common/constants'; import { JoinTooltipProperty } from '../../tooltips/join_tooltip_property'; @@ -46,7 +42,7 @@ import { } from '../../util/can_skip_fetch'; import { getFeatureCollectionBounds } from '../../util/get_feature_collection_bounds'; import { - getCentroidFilterExpression, + getLabelFilterExpression, getFillFilterExpression, getLineFilterExpression, getPointFilterExpression, @@ -80,6 +76,7 @@ import { addGeoJsonMbSource, getVectorSourceBounds, syncVectorSource } from './u import { JoinState, performInnerJoins } from './perform_inner_joins'; import { buildVectorRequestMeta } from '../build_vector_request_meta'; import { getJoinAggKey } from '../../../../common/get_agg_key'; +import { getFeatureId } from './assign_feature_ids'; export function isVectorLayer(layer: ILayer) { return (layer as IVectorLayer).canShowTooltip !== undefined; @@ -93,6 +90,12 @@ export interface VectorLayerArguments { } export interface IVectorLayer extends ILayer { + /* + * IVectorLayer.getMbLayerIds returns a list of mapbox layers assoicated with this layer for identifing features with tooltips. + * Must return ILayer.getMbLayerIds or a subset of ILayer.getMbLayerIds. + */ + getMbTooltipLayerIds(): string[]; + getFields(): Promise; getStyleEditorFields(): Promise; getJoins(): InnerJoin[]; @@ -118,6 +121,9 @@ export const NO_RESULTS_ICON_AND_TOOLTIPCONTENT = { }), }; +/* + * Geojson vector layer + */ export class VectorLayer extends AbstractLayer implements IVectorLayer { static type = LAYER_TYPE.VECTOR; @@ -589,6 +595,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { timeFilters: nextMeta.timeFilters, searchSessionId: dataFilters.searchSessionId, }); + stopLoading(dataRequestId, requestToken, styleMeta, nextMeta); } catch (error) { if (!(error instanceof DataRequestAbortError)) { @@ -774,6 +781,9 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } _getSourceFeatureCollection() { + if (this.getSource().isMvt()) { + return null; + } const sourceDataRequest = this.getSourceDataRequest(); return sourceDataRequest ? (sourceDataRequest.getData() as FeatureCollection) : null; } @@ -946,7 +956,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { const sourceId = this.getId(); const fillLayerId = this._getMbPolygonLayerId(); const lineLayerId = this._getMbLineLayerId(); - const tooManyFeaturesLayerId = this._getMbTooManyFeaturesLayerId(); const hasJoins = this.hasJoins(); if (!mbMap.getLayer(fillLayerId)) { @@ -973,29 +982,6 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } mbMap.addLayer(mbLayer); } - if (!mbMap.getLayer(tooManyFeaturesLayerId)) { - const mbLayer: MbLayer = { - id: tooManyFeaturesLayerId, - type: 'fill', - source: sourceId, - paint: {}, - }; - if (mvtSourceLayer) { - mbLayer['source-layer'] = mvtSourceLayer; - } - mbMap.addLayer(mbLayer); - mbMap.setFilter(tooManyFeaturesLayerId, [ - 'all', - ['==', ['get', KBN_METADATA_FEATURE], true], - ['==', ['get', KBN_IS_TILE_COMPLETE], false], - ]); - mbMap.setPaintProperty( - tooManyFeaturesLayerId, - 'fill-pattern', - KBN_TOO_MANY_FEATURES_IMAGE_ID - ); - mbMap.setPaintProperty(tooManyFeaturesLayerId, 'fill-opacity', this.getAlpha()); - } this.getCurrentStyle().setMBPaintProperties({ alpha: this.getAlpha(), @@ -1017,21 +1003,18 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { if (!_.isEqual(lineFilterExpr, mbMap.getFilter(lineLayerId))) { mbMap.setFilter(lineLayerId, lineFilterExpr); } - - this.syncVisibilityWithMb(mbMap, tooManyFeaturesLayerId); - mbMap.setLayerZoomRange(tooManyFeaturesLayerId, this.getMinZoom(), this.getMaxZoom()); } - _setMbCentroidProperties( + _setMbLabelProperties( mbMap: MbMap, mvtSourceLayer?: string, timesliceMaskConfig?: TimesliceMaskConfig ) { - const centroidLayerId = this._getMbCentroidLayerId(); - const centroidLayer = mbMap.getLayer(centroidLayerId); - if (!centroidLayer) { + const labelLayerId = this._getMbLabelLayerId(); + const labelLayer = mbMap.getLayer(labelLayerId); + if (!labelLayer) { const mbLayer: MbLayer = { - id: centroidLayerId, + id: labelLayerId, type: 'symbol', source: this.getId(), }; @@ -1041,27 +1024,32 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { mbMap.addLayer(mbLayer); } - const filterExpr = getCentroidFilterExpression(this.hasJoins(), timesliceMaskConfig); - if (!_.isEqual(filterExpr, mbMap.getFilter(centroidLayerId))) { - mbMap.setFilter(centroidLayerId, filterExpr); + const isSourceGeoJson = !this.getSource().isMvt(); + const filterExpr = getLabelFilterExpression( + this.hasJoins(), + isSourceGeoJson, + timesliceMaskConfig + ); + if (!_.isEqual(filterExpr, mbMap.getFilter(labelLayerId))) { + mbMap.setFilter(labelLayerId, filterExpr); } this.getCurrentStyle().setMBPropertiesForLabelText({ alpha: this.getAlpha(), mbMap, - textLayerId: centroidLayerId, + textLayerId: labelLayerId, }); - this.syncVisibilityWithMb(mbMap, centroidLayerId); - mbMap.setLayerZoomRange(centroidLayerId, this.getMinZoom(), this.getMaxZoom()); + this.syncVisibilityWithMb(mbMap, labelLayerId); + mbMap.setLayerZoomRange(labelLayerId, this.getMinZoom(), this.getMaxZoom()); } _syncStylePropertiesWithMb(mbMap: MbMap, timeslice?: Timeslice) { const timesliceMaskConfig = this._getTimesliceMaskConfig(timeslice); this._setMbPointsProperties(mbMap, undefined, timesliceMaskConfig); this._setMbLinePolygonProperties(mbMap, undefined, timesliceMaskConfig); - // centroid layers added after polygon layers to ensure they are on top of polygon layers - this._setMbCentroidProperties(mbMap, undefined, timesliceMaskConfig); + // label layers added after geometry layers to ensure they are on top + this._setMbLabelProperties(mbMap, undefined, timesliceMaskConfig); } _getTimesliceMaskConfig(timeslice?: Timeslice): TimesliceMaskConfig | undefined { @@ -1092,8 +1080,12 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { return this.makeMbLayerId('text'); } - _getMbCentroidLayerId() { - return this.makeMbLayerId('centroid'); + // _getMbTextLayerId is labels for Points and MultiPoints + // _getMbLabelLayerId is labels for not Points and MultiPoints + // _getMbLabelLayerId used to be called _getMbCentroidLayerId + // TODO merge textLayer and labelLayer into single layer + _getMbLabelLayerId() { + return this.makeMbLayerId('label'); } _getMbSymbolLayerId() { @@ -1108,22 +1100,21 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { return this.makeMbLayerId('fill'); } - _getMbTooManyFeaturesLayerId() { - return this.makeMbLayerId('toomanyfeatures'); - } - - getMbLayerIds() { + getMbTooltipLayerIds() { return [ this._getMbPointLayerId(), this._getMbTextLayerId(), - this._getMbCentroidLayerId(), + this._getMbLabelLayerId(), this._getMbSymbolLayerId(), this._getMbLineLayerId(), this._getMbPolygonLayerId(), - this._getMbTooManyFeaturesLayerId(), ]; } + getMbLayerIds() { + return this.getMbTooltipLayerIds(); + } + ownsMbLayerId(mbLayerId: string) { return this.getMbLayerIds().includes(mbLayerId); } @@ -1170,7 +1161,7 @@ export class VectorLayer extends AbstractLayer implements IVectorLayer { } const targetFeature = featureCollection.features.find((feature) => { - return feature.properties?.[FEATURE_ID_PROPERTY_NAME] === id; + return getFeatureId(feature, this.getSource()) === id; }); return targetFeature ? targetFeature : null; } diff --git a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts index 78bc2592182d8a..dc9637c7a76376 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_agg_source/es_agg_source.ts @@ -134,14 +134,14 @@ export abstract class AbstractESAggSource extends AbstractESSource implements IE return valueAggsDsl; } - async getTooltipProperties(properties: GeoJsonProperties): Promise { + async getTooltipProperties(mbProperties: GeoJsonProperties): Promise { const metricFields = await this.getFields(); const promises: Array> = []; metricFields.forEach((metricField) => { let value; - for (const key in properties) { - if (properties.hasOwnProperty(key) && metricField.getName() === key) { - value = properties[key]; + for (const key in mbProperties) { + if (mbProperties.hasOwnProperty(key) && metricField.getMbFieldName() === key) { + value = mbProperties[key]; break; } } diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/__snapshots__/resolution_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/__snapshots__/resolution_editor.test.tsx.snap index ca9775594a9d73..6a1dbf9e1590b3 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/__snapshots__/resolution_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/__snapshots__/resolution_editor.test.tsx.snap @@ -1,73 +1,77 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`resolution editor should add super-fine option 1`] = ` - - - + + + + + `; exports[`resolution editor should omit super-fine option 1`] = ` - - - + + + + + `; diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/__snapshots__/update_source_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/__snapshots__/update_source_editor.test.tsx.snap index dfce6b36396a75..0d4467792e636d 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/__snapshots__/update_source_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/__snapshots__/update_source_editor.test.tsx.snap @@ -19,9 +19,9 @@ exports[`source editor geo_grid_source default vector layer config should allow /> @@ -45,6 +45,7 @@ exports[`source editor geo_grid_source default vector layer config should allow /> @@ -79,7 +80,8 @@ exports[`source editor geo_grid_source should put limitations based on heatmap-r /> diff --git a/x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.d.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.d.ts similarity index 89% rename from x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.d.ts rename to x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.d.ts index 3bb2e165fa7406..94526204472599 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.d.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.d.ts @@ -6,7 +6,7 @@ */ import { Feature } from 'geojson'; -import { RENDER_AS } from '../constants'; +import { RENDER_AS } from '../../../../common/constants'; export function convertCompositeRespToGeoJson(esResponse: any, renderAs: RENDER_AS): Feature[]; export function convertRegularRespToGeoJson(esResponse: any, renderAs: RENDER_AS): Feature[]; diff --git a/x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.js similarity index 89% rename from x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.js rename to x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.js index f416847941a8ae..87fb0d53efa629 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.js @@ -6,10 +6,13 @@ */ import _ from 'lodash'; -import { RENDER_AS, GEOTILE_GRID_AGG_NAME, GEOCENTROID_AGG_NAME } from '../constants'; -import { getTileBoundingBox } from '../geo_tile_utils'; -import { extractPropertiesFromBucket } from './es_agg_utils'; -import { clamp } from './elasticsearch_geo_utils'; +import { + RENDER_AS, + GEOTILE_GRID_AGG_NAME, + GEOCENTROID_AGG_NAME, +} from '../../../../common/constants'; +import { getTileBoundingBox } from '../../util/geo_tile_utils'; +import { clamp, extractPropertiesFromBucket } from '../../../../common/elasticsearch_util'; const GRID_BUCKET_KEYS_TO_IGNORE = ['key', GEOCENTROID_AGG_NAME]; diff --git a/x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.test.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.test.ts similarity index 98% rename from x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.test.ts rename to x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.test.ts index 2dc96038d931d8..d6de17bef710b1 100644 --- a/x-pack/plugins/maps/common/elasticsearch_util/convert_to_geojson.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/convert_to_geojson.test.ts @@ -7,7 +7,7 @@ // @ts-ignore import { convertCompositeRespToGeoJson, convertRegularRespToGeoJson } from './convert_to_geojson'; -import { RENDER_AS } from '../constants'; +import { RENDER_AS } from '../../../../common/constants'; describe('convertCompositeRespToGeoJson', () => { const esResponse = { diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts index 41d5715e47b8ed..8eebf01a550dd2 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.test.ts @@ -296,7 +296,7 @@ describe('ESGeoGridSource', () => { ); it('getLayerName', () => { - expect(mvtGeogridSource.getLayerName()).toBe('source_layer'); + expect(mvtGeogridSource.getLayerName()).toBe('aggs'); }); it('getMinZoom', () => { @@ -312,28 +312,13 @@ describe('ESGeoGridSource', () => { vectorSourceRequestMeta ); - expect(urlTemplateWithMeta.layerName).toBe('source_layer'); + expect(urlTemplateWithMeta.layerName).toBe('aggs'); expect(urlTemplateWithMeta.minSourceZoom).toBe(0); expect(urlTemplateWithMeta.maxSourceZoom).toBe(24); expect(urlTemplateWithMeta.urlTemplate).toEqual( - "rootdir/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=undefined&requestBody=(foobar:ES_DSL_PLACEHOLDER,params:('0':('0':index,'1':(fields:())),'1':('0':size,'1':0),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:())),'5':('0':query,'1':(language:KQL,query:'')),'6':('0':aggs,'1':(gridSplit:(aggs:(gridCentroid:(geo_centroid:(field:bar))),geotile_grid:(bounds:!n,field:bar,precision:!n,shard_size:65535,size:65535))))))&requestType=heatmap&geoFieldType=geo_point" + "rootdir/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=undefined&requestBody=(foobar:ES_DSL_PLACEHOLDER,params:('0':('0':index,'1':(fields:())),'1':('0':size,'1':0),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:())),'5':('0':query,'1':(language:KQL,query:'')),'6':('0':aggs,'1':())))&requestType=heatmap" ); }); - - it('should include searchSourceId in urlTemplateWithMeta', async () => { - const urlTemplateWithMeta = await mvtGeogridSource.getUrlTemplateWithMeta({ - ...vectorSourceRequestMeta, - searchSessionId: '1', - }); - - expect( - urlTemplateWithMeta.urlTemplate.startsWith( - "rootdir/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=undefined&requestBody=(foobar:ES_DSL_PLACEHOLDER,params:('0':('0':index,'1':(fields:())),'1':('0':size,'1':0),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:())),'5':('0':query,'1':(language:KQL,query:'')),'6':('0':aggs,'1':(gridSplit:(aggs:(gridCentroid:(geo_centroid:(field:bar))),geotile_grid:(bounds:!n,field:bar,precision:!n,shard_size:65535,size:65535))))))&requestType=heatmap&geoFieldType=geo_point&searchSessionId=1" - ) - ).toBe(true); - - expect(urlTemplateWithMeta.urlTemplate.endsWith('&searchSessionId=1')).toBe(true); - }); }); describe('Gold+ usage', () => { diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx index 7bd1e4dfd75f3e..d038c139a1667a 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx @@ -11,12 +11,8 @@ import { i18n } from '@kbn/i18n'; import rison from 'rison-node'; import { Feature } from 'geojson'; import type { estypes } from '@elastic/elasticsearch'; -import { - convertCompositeRespToGeoJson, - convertRegularRespToGeoJson, - makeESBbox, -} from '../../../../common/elasticsearch_util'; -// @ts-expect-error +import { makeESBbox } from '../../../../common/elasticsearch_util'; +import { convertCompositeRespToGeoJson, convertRegularRespToGeoJson } from './convert_to_geojson'; import { UpdateSourceEditor } from './update_source_editor'; import { DEFAULT_MAX_BUCKETS_LIMIT, @@ -26,7 +22,6 @@ import { GIS_API_PATH, GRID_RESOLUTION, MVT_GETGRIDTILE_API_PATH, - MVT_SOURCE_LAYER_NAME, MVT_TOKEN_PARAM_NAME, RENDER_AS, SOURCE_TYPES, @@ -55,6 +50,8 @@ import { ITiledSingleLayerMvtParams } from '../tiled_single_layer_vector_source/ type ESGeoGridSourceSyncMeta = Pick; +const ES_MVT_AGGS_LAYER_NAME = 'aggs'; + export const MAX_GEOTILE_LEVEL = 29; export const clustersTitle = i18n.translate('xpack.maps.source.esGridClustersTitle', { @@ -140,6 +137,10 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle ]; } + isMvt() { + return this._descriptor.resolution === GRID_RESOLUTION.SUPER_FINE; + } + getFieldNames() { return this.getMetricFields().map((esAggMetricField) => esAggMetricField.getName()); } @@ -305,8 +306,8 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle _addNonCompositeAggsToSearchSource( searchSource: ISearchSource, indexPattern: IndexPattern, - precision: number | null, - bufferedExtent?: MapExtent | null + precision: number, + bufferedExtent?: MapExtent ) { searchSource.setField('aggs', { [GEOTILE_GRID_AGG_NAME]: { @@ -419,7 +420,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle } getLayerName(): string { - return MVT_SOURCE_LAYER_NAME; + return ES_MVT_AGGS_LAYER_NAME; } async getUrlTemplateWithMeta( @@ -427,14 +428,7 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle ): Promise { const indexPattern = await this.getIndexPattern(); const searchSource = await this.makeSearchSource(searchFilters, 0); - - this._addNonCompositeAggsToSearchSource( - searchSource, - indexPattern, - null, // needs to be set server-side - null // needs to be stripped server-side - ); - + searchSource.setField('aggs', this.getValueAggsDsl(indexPattern)); const dsl = searchSource.getSearchRequestBody(); const risonDsl = rison.encode(dsl); @@ -443,22 +437,18 @@ export class ESGeoGridSource extends AbstractESAggSource implements ITiledSingle `/${GIS_API_PATH}/${MVT_GETGRIDTILE_API_PATH}/{z}/{x}/{y}.pbf` ); - const geoField = await this._getGeoField(); const urlTemplate = `${mvtUrlServicePath}\ ?geometryFieldName=${this._descriptor.geoField}\ &index=${indexPattern.title}\ &requestBody=${risonDsl}\ -&requestType=${this._descriptor.requestType}\ -&geoFieldType=${geoField.type}`; +&requestType=${this._descriptor.requestType}`; return { refreshTokenParamName: MVT_TOKEN_PARAM_NAME, layerName: this.getLayerName(), minSourceZoom: this.getMinZoom(), maxSourceZoom: this.getMaxZoom(), - urlTemplate: searchFilters.searchSessionId - ? urlTemplate + `&searchSessionId=${searchFilters.searchSessionId}` - : urlTemplate, + urlTemplate, }; } diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.js deleted file mode 100644 index 52f4e4c9b7b880..00000000000000 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.js +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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 { GRID_RESOLUTION } from '../../../../common/constants'; -import { EuiSelect, EuiFormRow } from '@elastic/eui'; -import { i18n } from '@kbn/i18n'; - -const BASE_OPTIONS = [ - { - value: GRID_RESOLUTION.COARSE, - text: i18n.translate('xpack.maps.source.esGrid.coarseDropdownOption', { - defaultMessage: 'coarse', - }), - }, - { - value: GRID_RESOLUTION.FINE, - text: i18n.translate('xpack.maps.source.esGrid.fineDropdownOption', { - defaultMessage: 'fine', - }), - }, - { - value: GRID_RESOLUTION.MOST_FINE, - text: i18n.translate('xpack.maps.source.esGrid.finestDropdownOption', { - defaultMessage: 'finest', - }), - }, -]; - -export function ResolutionEditor({ resolution, onChange, includeSuperFine }) { - const options = [...BASE_OPTIONS]; - - if (includeSuperFine) { - options.push({ - value: GRID_RESOLUTION.SUPER_FINE, - text: i18n.translate('xpack.maps.source.esGrid.superFineDropDownOption', { - defaultMessage: 'super fine (beta)', - }), - }); - } - - return ( - - onChange(e.target.value)} - compressed - /> - - ); -} diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.test.tsx index 0066160402fa31..a642bbe41449f1 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.test.tsx @@ -8,7 +8,6 @@ import React from 'react'; import { shallow } from 'enzyme'; -// @ts-expect-error import { ResolutionEditor } from './resolution_editor'; import { GRID_RESOLUTION } from '../../../../common/constants'; @@ -16,6 +15,7 @@ const defaultProps = { resolution: GRID_RESOLUTION.COARSE, onChange: () => {}, includeSuperFine: false, + metrics: [], }; describe('resolution editor', () => { diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.tsx new file mode 100644 index 00000000000000..55ce46e1212733 --- /dev/null +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/resolution_editor.tsx @@ -0,0 +1,161 @@ +/* + * 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, { ChangeEvent, Component } from 'react'; +import { EuiConfirmModal, EuiSelect, EuiFormRow } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { i18n } from '@kbn/i18n'; +import { AggDescriptor } from '../../../../common/descriptor_types'; +import { AGG_TYPE, GRID_RESOLUTION } from '../../../../common/constants'; + +const BASE_OPTIONS = [ + { + value: GRID_RESOLUTION.COARSE, + text: i18n.translate('xpack.maps.source.esGrid.coarseDropdownOption', { + defaultMessage: 'coarse', + }), + }, + { + value: GRID_RESOLUTION.FINE, + text: i18n.translate('xpack.maps.source.esGrid.fineDropdownOption', { + defaultMessage: 'fine', + }), + }, + { + value: GRID_RESOLUTION.MOST_FINE, + text: i18n.translate('xpack.maps.source.esGrid.finestDropdownOption', { + defaultMessage: 'finest', + }), + }, +]; + +function isUnsupportedVectorTileMetric(metric: AggDescriptor) { + return metric.type === AGG_TYPE.TERMS; +} + +interface Props { + includeSuperFine: boolean; + resolution: GRID_RESOLUTION; + onChange: (resolution: GRID_RESOLUTION, metrics: AggDescriptor[]) => void; + metrics: AggDescriptor[]; +} + +interface State { + showModal: boolean; +} + +export class ResolutionEditor extends Component { + private readonly _options = [...BASE_OPTIONS]; + + constructor(props: Props) { + super(props); + + this.state = { + showModal: false, + }; + + if (props.includeSuperFine) { + this._options.push({ + value: GRID_RESOLUTION.SUPER_FINE, + text: i18n.translate('xpack.maps.source.esGrid.superFineDropDownOption', { + defaultMessage: 'super fine', + }), + }); + } + } + + _onResolutionChange = (e: ChangeEvent) => { + const resolution = e.target.value as GRID_RESOLUTION; + if (resolution === GRID_RESOLUTION.SUPER_FINE) { + const hasUnsupportedMetrics = this.props.metrics.find(isUnsupportedVectorTileMetric); + if (hasUnsupportedMetrics) { + this.setState({ showModal: true }); + return; + } + } + + this.props.onChange(resolution, this.props.metrics); + }; + + _closeModal = () => { + this.setState({ + showModal: false, + }); + }; + + _acceptModal = () => { + this._closeModal(); + const supportedMetrics = this.props.metrics.filter((metric) => { + return !isUnsupportedVectorTileMetric(metric); + }); + this.props.onChange( + GRID_RESOLUTION.SUPER_FINE, + supportedMetrics.length ? supportedMetrics : [{ type: AGG_TYPE.COUNT }] + ); + }; + + _renderModal() { + return this.state.showModal ? ( + +

+ +

+
+ ) : null; + } + + render() { + const helpText = + this.props.resolution === GRID_RESOLUTION.SUPER_FINE + ? i18n.translate('xpack.maps.source.esGrid.superFineHelpText', { + defaultMessage: 'Super fine grid resolution uses vector tiles.', + }) + : undefined; + return ( + <> + {this._renderModal()} + + + + + ); + } +} diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.test.tsx b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.test.tsx index 18a263143afea0..9dab6698b73f01 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.test.tsx @@ -8,14 +8,19 @@ import React from 'react'; import { shallow } from 'enzyme'; -// @ts-expect-error import { UpdateSourceEditor } from './update_source_editor'; import { GRID_RESOLUTION, LAYER_TYPE, RENDER_AS } from '../../../../common/constants'; +jest.mock('uuid/v4', () => { + return function () { + return '12345'; + }; +}); + const defaultProps = { currentLayerType: LAYER_TYPE.VECTOR, indexPatternId: 'foobar', - onChange: () => {}, + onChange: async () => {}, metrics: [], renderAs: RENDER_AS.POINT, resolution: GRID_RESOLUTION.COARSE, diff --git a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.tsx similarity index 61% rename from x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.js rename to x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.tsx index c2a0935c237196..03b5e1fe3c7943 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/update_source_editor.tsx @@ -7,20 +7,40 @@ import React, { Fragment, Component } from 'react'; +import uuid from 'uuid/v4'; +import { FormattedMessage } from '@kbn/i18n/react'; +import { EuiPanel, EuiSpacer, EuiComboBoxOptionOption, EuiTitle } from '@elastic/eui'; import { getDataViewNotFoundMessage } from '../../../../common/i18n_getters'; -import { GRID_RESOLUTION, LAYER_TYPE } from '../../../../common/constants'; +import { AGG_TYPE, GRID_RESOLUTION, LAYER_TYPE, RENDER_AS } from '../../../../common/constants'; import { MetricsEditor } from '../../../components/metrics_editor'; import { getIndexPatternService } from '../../../kibana_services'; import { ResolutionEditor } from './resolution_editor'; -import { FormattedMessage } from '@kbn/i18n/react'; -import { EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import { isMetricCountable } from '../../util/is_metric_countable'; -import { indexPatterns } from '../../../../../../../src/plugins/data/public'; +import { IndexPatternField, indexPatterns } from '../../../../../../../src/plugins/data/public'; import { RenderAsSelect } from './render_as_select'; +import { AggDescriptor } from '../../../../common/descriptor_types'; +import { OnSourceChangeArgs } from '../source'; + +interface Props { + currentLayerType?: string; + indexPatternId: string; + onChange: (...args: OnSourceChangeArgs[]) => Promise; + metrics: AggDescriptor[]; + renderAs: RENDER_AS; + resolution: GRID_RESOLUTION; +} -export class UpdateSourceEditor extends Component { - state = { - fields: null, +interface State { + metricsEditorKey: string; + fields: IndexPatternField[]; + loadError?: string; +} + +export class UpdateSourceEditor extends Component { + private _isMounted?: boolean; + state: State = { + fields: [], + metricsEditorKey: uuid(), }; componentDidMount() { @@ -54,11 +74,11 @@ export class UpdateSourceEditor extends Component { }); } - _onMetricsChange = (metrics) => { + _onMetricsChange = (metrics: AggDescriptor[]) => { this.props.onChange({ propName: 'metrics', value: metrics }); }; - _onResolutionChange = (resolution) => { + _onResolutionChange = async (resolution: GRID_RESOLUTION, metrics: AggDescriptor[]) => { let newLayerType; if ( this.props.currentLayerType === LAYER_TYPE.VECTOR || @@ -76,22 +96,36 @@ export class UpdateSourceEditor extends Component { throw new Error('Unexpected layer-type'); } - this.props.onChange({ propName: 'resolution', value: resolution, newLayerType }); + await this.props.onChange( + { propName: 'metrics', value: metrics }, + { propName: 'resolution', value: resolution, newLayerType } + ); + + // Metrics editor persists metrics in state. + // Reset metricsEditorKey to force new instance and new internal state with latest metrics + this.setState({ metricsEditorKey: uuid() }); }; - _onRequestTypeSelect = (requestType) => { + _onRequestTypeSelect = (requestType: RENDER_AS) => { this.props.onChange({ propName: 'requestType', value: requestType }); }; + _getMetricsFilter() { + if (this.props.currentLayerType === LAYER_TYPE.HEATMAP) { + return (metric: EuiComboBoxOptionOption) => { + // these are countable metrics, where blending heatmap color blobs make sense + return metric.value ? isMetricCountable(metric.value) : false; + }; + } + + if (this.props.resolution === GRID_RESOLUTION.SUPER_FINE) { + return (metric: EuiComboBoxOptionOption) => { + return metric.value !== AGG_TYPE.TERMS; + }; + } + } + _renderMetricsPanel() { - const metricsFilter = - this.props.currentLayerType === LAYER_TYPE.HEATMAP - ? (metric) => { - //these are countable metrics, where blending heatmap color blobs make sense - return isMetricCountable(metric.value); - } - : null; - const allowMultipleMetrics = this.props.currentLayerType !== LAYER_TYPE.HEATMAP; return ( @@ -101,8 +135,9 @@ export class UpdateSourceEditor extends Component { {}} /> ); diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts index 6359abd06d3be9..aad377ef53649f 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.test.ts @@ -31,7 +31,7 @@ describe('ESSearchSource', () => { const esSearchSource = new ESSearchSource(mockDescriptor); expect(esSearchSource.getMinZoom()).toBe(0); expect(esSearchSource.getMaxZoom()).toBe(24); - expect(esSearchSource.getLayerName()).toBe('source_layer'); + expect(esSearchSource.getLayerName()).toBe('hits'); }); describe('getUrlTemplateWithMeta', () => { @@ -117,21 +117,7 @@ describe('ESSearchSource', () => { }); const urlTemplateWithMeta = await esSearchSource.getUrlTemplateWithMeta(searchFilters); expect(urlTemplateWithMeta.urlTemplate).toBe( - `rootdir/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=foobar-title-*&requestBody=(foobar:ES_DSL_PLACEHOLDER,params:('0':('0':index,'1':(fields:(),title:'foobar-title-*')),'1':('0':size,'1':1000),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:(),title:'foobar-title-*')),'5':('0':query,'1':(language:KQL,query:'tooltipField: foobar')),'6':('0':fieldsFromSource,'1':!(tooltipField,styleField)),'7':('0':source,'1':!(tooltipField,styleField))))&geoFieldType=geo_shape` - ); - }); - - it('should include searchSourceId in urlTemplateWithMeta', async () => { - const esSearchSource = new ESSearchSource({ - geoField: geoFieldName, - indexPatternId: 'ipId', - }); - const urlTemplateWithMeta = await esSearchSource.getUrlTemplateWithMeta({ - ...searchFilters, - searchSessionId: '1', - }); - expect(urlTemplateWithMeta.urlTemplate).toBe( - `rootdir/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=foobar-title-*&requestBody=(foobar:ES_DSL_PLACEHOLDER,params:('0':('0':index,'1':(fields:(),title:'foobar-title-*')),'1':('0':size,'1':1000),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:(),title:'foobar-title-*')),'5':('0':query,'1':(language:KQL,query:'tooltipField: foobar')),'6':('0':fieldsFromSource,'1':!(tooltipField,styleField)),'7':('0':source,'1':!(tooltipField,styleField))))&geoFieldType=geo_shape&searchSessionId=1` + `rootdir/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=bar&index=foobar-title-*&requestBody=(foobar:ES_DSL_PLACEHOLDER,params:('0':('0':index,'1':(fields:(),title:'foobar-title-*')),'1':('0':size,'1':1000),'2':('0':filter,'1':!()),'3':('0':query),'4':('0':index,'1':(fields:(),title:'foobar-title-*')),'5':('0':query,'1':(language:KQL,query:'tooltipField: foobar')),'6':('0':fieldsFromSource,'1':!(tooltipField,styleField)),'7':('0':source,'1':!(tooltipField,styleField))))` ); }); }); @@ -162,7 +148,7 @@ describe('ESSearchSource', () => { scalingType: SCALING_TYPES.MVT, }); expect(esSearchSource.getJoinsDisabledReason()).toBe( - 'Joins are not supported when scaling by mvt vector tiles' + 'Joins are not supported when scaling by vector tiles' ); }); }); diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx index 75ec128f5a8aab..31cc07d03549a4 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx @@ -9,8 +9,8 @@ import _ from 'lodash'; import React, { ReactElement } from 'react'; import rison from 'rison-node'; import { i18n } from '@kbn/i18n'; -import type { Filter, IndexPatternField, IndexPattern } from 'src/plugins/data/public'; import { GeoJsonProperties, Geometry, Position } from 'geojson'; +import type { Filter, IndexPatternField, IndexPattern } from 'src/plugins/data/public'; import { esFilters } from '../../../../../../../src/plugins/data/public'; import { AbstractESSource } from '../es_source'; import { @@ -35,7 +35,6 @@ import { FIELD_ORIGIN, GIS_API_PATH, MVT_GETTILE_API_PATH, - MVT_SOURCE_LAYER_NAME, MVT_TOKEN_PARAM_NAME, SCALING_TYPES, SOURCE_TYPES, @@ -54,14 +53,17 @@ import { VectorSourceRequestMeta, } from '../../../../common/descriptor_types'; import { Adapters } from '../../../../../../../src/plugins/inspector/common/adapters'; -import { TimeRange } from '../../../../../../../src/plugins/data/common'; +import { + SortDirection, + SortDirectionNumeric, + TimeRange, +} from '../../../../../../../src/plugins/data/common'; import { ImmutableSourceProperty, SourceEditorArgs } from '../source'; import { IField } from '../../fields/field'; import { GeoJsonWithMeta, SourceTooltipConfig } from '../vector_source'; import { ITiledSingleLayerVectorSource } from '../tiled_single_layer_vector_source'; import { ITooltipProperty } from '../../tooltips/tooltip_property'; import { DataRequest } from '../../util/data_request'; -import { SortDirection, SortDirectionNumeric } from '../../../../../../../src/plugins/data/common'; import { isValidStringConfig } from '../../util/valid_string_config'; import { TopHitsUpdateSourceEditor } from './top_hits'; import { getDocValueAndSourceFields, ScriptField } from './util/get_docvalue_source_fields'; @@ -83,6 +85,8 @@ type ESSearchSourceSyncMeta = Pick< | 'topHitsSize' >; +const ES_MVT_HITS_LAYER_NAME = 'hits'; + export function timerangeToTimeextent(timerange: TimeRange): Timeslice | undefined { const timeRangeBounds = getTimeFilter().calculateBounds(timerange); return timeRangeBounds.min !== undefined && timeRangeBounds.max !== undefined @@ -185,6 +189,8 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye sortOrder={this._descriptor.sortOrder} scalingType={this._descriptor.scalingType} filterByMapBounds={this.isFilterByMapBounds()} + hasJoins={sourceEditorArgs.hasJoins} + clearJoins={sourceEditorArgs.clearJoins} /> ); } @@ -211,6 +217,10 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye return [this._descriptor.geoField]; } + isMvt() { + return this._descriptor.scalingType === SCALING_TYPES.MVT; + } + async getImmutableProperties(): Promise { let indexPatternName = this.getIndexPatternId(); let geoFieldType = ''; @@ -748,7 +758,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye }); } else if (this._descriptor.scalingType === SCALING_TYPES.MVT) { reason = i18n.translate('xpack.maps.source.esSearch.joinsDisabledReasonMvt', { - defaultMessage: 'Joins are not supported when scaling by mvt vector tiles', + defaultMessage: 'Joins are not supported when scaling by vector tiles', }); } else { reason = null; @@ -757,7 +767,7 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye } getLayerName(): string { - return MVT_SOURCE_LAYER_NAME; + return ES_MVT_HITS_LAYER_NAME; } async _getEditableIndex(): Promise { @@ -828,22 +838,17 @@ export class ESSearchSource extends AbstractESSource implements ITiledSingleLaye `/${GIS_API_PATH}/${MVT_GETTILE_API_PATH}/{z}/{x}/{y}.pbf` ); - const geoField = await this._getGeoField(); - const urlTemplate = `${mvtUrlServicePath}\ ?geometryFieldName=${this._descriptor.geoField}\ &index=${indexPattern.title}\ -&requestBody=${risonDsl}\ -&geoFieldType=${geoField.type}`; +&requestBody=${risonDsl}`; return { refreshTokenParamName: MVT_TOKEN_PARAM_NAME, layerName: this.getLayerName(), minSourceZoom: this.getMinZoom(), maxSourceZoom: this.getMaxZoom(), - urlTemplate: searchFilters.searchSessionId - ? urlTemplate + `&searchSessionId=${searchFilters.searchSessionId}` - : urlTemplate, + urlTemplate, }; } diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.js b/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.js index c28c8bedafaf94..ad0e03c2fe09d5 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.js +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/update_source_editor.js @@ -35,6 +35,8 @@ export class UpdateSourceEditor extends Component { sortOrder: PropTypes.string.isRequired, scalingType: PropTypes.string.isRequired, source: PropTypes.object, + hasJoins: PropTypes.bool.isRequired, + clearJoins: PropTypes.func.isRequired, }; state = { @@ -205,6 +207,8 @@ export class UpdateSourceEditor extends Component { scalingType={this.props.scalingType} supportsClustering={this.state.supportsClustering} clusteringDisabledReason={this.state.clusteringDisabledReason} + hasJoins={this.props.hasJoins} + clearJoins={this.props.clearJoins} /> ); diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap index 749d55aeb5da73..bafb3172bbc113 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/__snapshots__/scaling_form.test.tsx.snap @@ -46,17 +46,7 @@ exports[`scaling form should disable clusters option when clustering is not supp /> - - - Use vector tiles for faster display of large datasets. - - } + content="Use vector tiles for faster display of large datasets." delay="regular" display="inlineBlock" position="left" @@ -127,17 +117,7 @@ exports[`scaling form should render 1`] = ` onChange={[Function]} /> - - - Use vector tiles for faster display of large datasets. - - } + content="Use vector tiles for faster display of large datasets." delay="regular" display="inlineBlock" position="left" diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx index c02d855f13aa4c..aa3c7b51df5bb4 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.test.tsx @@ -26,6 +26,8 @@ const defaultProps = { scalingType: SCALING_TYPES.LIMIT, supportsClustering: true, termFields: [], + hasJoins: false, + clearJoins: () => {}, }; describe('scaling form', () => { diff --git a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx index 2d202e934cea99..896b4935073220 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx +++ b/x-pack/plugins/maps/public/classes/sources/es_search_source/util/scaling_form.tsx @@ -7,15 +7,14 @@ import React, { Component, Fragment } from 'react'; import { + EuiConfirmModal, EuiFormRow, - EuiHorizontalRule, EuiRadio, EuiSpacer, EuiSwitch, EuiSwitchEvent, EuiTitle, EuiToolTip, - EuiBetaBadge, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; @@ -35,15 +34,20 @@ interface Props { scalingType: SCALING_TYPES; supportsClustering: boolean; clusteringDisabledReason?: string | null; + hasJoins: boolean; + clearJoins: () => void; } interface State { + nextScalingType?: SCALING_TYPES; maxResultWindow: string; + showModal: boolean; } export class ScalingForm extends Component { - state = { + state: State = { maxResultWindow: DEFAULT_MAX_RESULT_WINDOW.toLocaleString(), + showModal: false, }; _isMounted = false; @@ -68,7 +72,15 @@ export class ScalingForm extends Component { } } - _onScalingTypeChange = (optionId: string): void => { + _onScalingTypeSelect = (optionId: SCALING_TYPES): void => { + if (this.props.hasJoins && optionId !== SCALING_TYPES.LIMIT) { + this._openModal(optionId); + } else { + this._onScalingTypeChange(optionId); + } + }; + + _onScalingTypeChange = (optionId: SCALING_TYPES): void => { let layerType; if (optionId === SCALING_TYPES.CLUSTERS) { layerType = LAYER_TYPE.BLENDED_VECTOR; @@ -85,6 +97,69 @@ export class ScalingForm extends Component { this.props.onChange({ propName: 'filterByMapBounds', value: event.target.checked }); }; + _openModal = (optionId: SCALING_TYPES) => { + this.setState({ + nextScalingType: optionId, + showModal: true, + }); + }; + + _closeModal = () => { + this.setState({ + nextScalingType: undefined, + showModal: false, + }); + }; + + _acceptModal = () => { + this.props.clearJoins(); + this._onScalingTypeChange(this.state.nextScalingType!); + this._closeModal(); + }; + + _renderModal() { + if (!this.state.showModal || this.state.nextScalingType === undefined) { + return null; + } + + const scalingOptionLabel = + this.state.nextScalingType === SCALING_TYPES.CLUSTERS + ? i18n.translate('xpack.maps.source.esSearch.scalingModal.clusters', { + defaultMessage: `clusters`, + }) + : i18n.translate('xpack.maps.source.esSearch.scalingModal.vectorTiles', { + defaultMessage: `vector tiles`, + }); + return ( + +

+ +

+
+ ); + } + _renderClusteringRadio() { const clusteringRadio = ( { values: { maxResultWindow: this.state.maxResultWindow }, })} checked={this.props.scalingType === SCALING_TYPES.CLUSTERS} - onChange={() => this._onScalingTypeChange(SCALING_TYPES.CLUSTERS)} + onChange={() => this._onScalingTypeSelect(SCALING_TYPES.CLUSTERS)} disabled={!this.props.supportsClustering} /> ); @@ -108,36 +183,6 @@ export class ScalingForm extends Component { ); } - _renderMVTRadio() { - const labelText = i18n.translate('xpack.maps.source.esSearch.useMVTVectorTiles', { - defaultMessage: 'Use vector tiles', - }); - const mvtRadio = ( - this._onScalingTypeChange(SCALING_TYPES.MVT)} - /> - ); - - const enabledInfo = ( - <> - - - {i18n.translate('xpack.maps.source.esSearch.mvtDescription', { - defaultMessage: 'Use vector tiles for faster display of large datasets.', - })} - - ); - - return ( - - {mvtRadio} - - ); - } - render() { let filterByBoundsSwitch; if (this.props.scalingType === SCALING_TYPES.LIMIT) { @@ -157,6 +202,7 @@ export class ScalingForm extends Component { return ( + {this._renderModal()}
@@ -174,10 +220,24 @@ export class ScalingForm extends Component { values: { maxResultWindow: this.state.maxResultWindow }, })} checked={this.props.scalingType === SCALING_TYPES.LIMIT} - onChange={() => this._onScalingTypeChange(SCALING_TYPES.LIMIT)} + onChange={() => this._onScalingTypeSelect(SCALING_TYPES.LIMIT)} /> {this._renderClusteringRadio()} - {this._renderMVTRadio()} + + this._onScalingTypeSelect(SCALING_TYPES.MVT)} + /> + diff --git a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts index 0fa6335c1e0d9e..ed95fdbb022fd2 100644 --- a/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts +++ b/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts @@ -20,7 +20,7 @@ import { getDataViewNotFoundMessage } from '../../../../common/i18n_getters'; import { createExtentFilter } from '../../../../common/elasticsearch_util'; import { copyPersistentState } from '../../../reducers/copy_persistent_state'; import { DataRequestAbortError } from '../../util/data_request'; -import { expandToTileBoundaries } from '../../../../common/geo_tile_utils'; +import { expandToTileBoundaries } from '../../util/geo_tile_utils'; import { IVectorSource } from '../vector_source'; import { TimeRange } from '../../../../../../../src/plugins/data/common'; import { diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap index f6d0129e85abf6..b8f7af8b3844e9 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/__snapshots__/mvt_field_config_editor.test.tsx.snap @@ -5,7 +5,6 @@ exports[`should render error for dupes 1`] = ` { _renderFieldConfig() { return this.state.currentFields.map((mvtFieldConfig: MVTFieldDescriptor, index: number) => { return ( - <> - + + {this._renderFieldNameInput(mvtFieldConfig, index)} {this._renderFieldTypeDropDown(mvtFieldConfig, index)} {this._renderFieldButtonDelete(index)} - + ); }); } diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx index 34a30ae9ec9774..387bb9c3ca1fff 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/mvt_single_layer_vector_source.tsx @@ -82,6 +82,10 @@ export class MVTSingleLayerVectorSource .filter((f) => f !== null) as MVTField[]; } + isMvt() { + return true; + } + async supportsFitToBounds() { return false; } diff --git a/x-pack/plugins/maps/public/classes/sources/source.ts b/x-pack/plugins/maps/public/classes/sources/source.ts index 4c2cffcf8b070f..0ecca16fde07bd 100644 --- a/x-pack/plugins/maps/public/classes/sources/source.ts +++ b/x-pack/plugins/maps/public/classes/sources/source.ts @@ -29,8 +29,10 @@ export type OnSourceChangeArgs = { }; export type SourceEditorArgs = { - onChange: (...args: OnSourceChangeArgs[]) => void; - currentLayerType?: string; + clearJoins: () => void; + currentLayerType: string; + hasJoins: boolean; + onChange: (...args: OnSourceChangeArgs[]) => Promise; }; export type ImmutableSourceProperty = { @@ -43,6 +45,7 @@ export interface ISource { destroy(): void; getDisplayName(): Promise; getInspectorAdapters(): Adapters | undefined; + getType(): string; isFieldAware(): boolean; isFilterByMapBounds(): boolean; isGeoGridPrecisionAware(): boolean; @@ -101,6 +104,10 @@ export class AbstractSource implements ISource { return this._inspectorAdapters; } + getType(): string { + return this._descriptor.type; + } + async getDisplayName(): Promise { return ''; } diff --git a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx index 3c0adf64216e60..7042374296bbea 100644 --- a/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx +++ b/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx @@ -9,7 +9,7 @@ import type { Query } from 'src/plugins/data/common'; import { FeatureCollection, GeoJsonProperties, Geometry, Position } from 'geojson'; import { Filter, TimeRange } from 'src/plugins/data/public'; import { VECTOR_SHAPE_TYPE } from '../../../../common/constants'; -import { TooltipProperty, ITooltipProperty } from '../../tooltips/tooltip_property'; +import { ITooltipProperty, TooltipProperty } from '../../tooltips/tooltip_property'; import { AbstractSource, ISource } from '../source'; import { IField } from '../../fields/field'; import { @@ -44,6 +44,7 @@ export interface BoundsRequestMeta { } export interface IVectorSource extends ISource { + isMvt(): boolean; getTooltipProperties(properties: GeoJsonProperties): Promise; getBoundsForFilters( layerDataFilters: BoundsRequestMeta, @@ -89,6 +90,10 @@ export class AbstractVectorSource extends AbstractSource implements IVectorSourc return []; } + isMvt() { + return false; + } + createField({ fieldName }: { fieldName: string }): IField { throw new Error('Not implemented'); } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/__snapshots__/vector_style_editor.test.tsx.snap b/x-pack/plugins/maps/public/classes/styles/vector/components/__snapshots__/vector_style_editor.test.tsx.snap index 64da5777988d1b..be8c9b0750b94e 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/__snapshots__/vector_style_editor.test.tsx.snap +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/__snapshots__/vector_style_editor.test.tsx.snap @@ -384,546 +384,6 @@ exports[`should render 1`] = ` `; -exports[`should render line-style with label properties when ES-source is rendered as mvt 1`] = ` - - - - - - - - - - - - - - - - - - - -`; - -exports[`should render polygon-style without label properties when 3rd party mvt 1`] = ` - - - - - - - - - - - -`; - exports[`should render with no style fields 1`] = ` { class MockField extends AbstractField {} -function createLayerMock( - numFields: number, - supportedShapeTypes: VECTOR_SHAPE_TYPE[], - layerType: LAYER_TYPE = LAYER_TYPE.VECTOR, - isESSource: boolean = false -) { +function createLayerMock(numFields: number, supportedShapeTypes: VECTOR_SHAPE_TYPE[]) { const fields: IField[] = []; for (let i = 0; i < numFields; i++) { fields.push(new MockField({ fieldName: `field${i}`, origin: FIELD_ORIGIN.SOURCE })); @@ -45,17 +39,11 @@ function createLayerMock( getStyleEditorFields: async () => { return fields; }, - getType() { - return layerType; - }, getSource: () => { return { getSupportedShapeTypes: async () => { return supportedShapeTypes; }, - isESSource() { - return isESSource; - }, } as unknown as IVectorSource; }, } as unknown as IVectorLayer; @@ -111,35 +99,3 @@ test('should render with no style fields', async () => { expect(component).toMatchSnapshot(); }); - -test('should render polygon-style without label properties when 3rd party mvt', async () => { - const component = shallow( - - ); - - // Ensure all promises resolve - await new Promise((resolve) => process.nextTick(resolve)); - // Ensure the state changes are reflected - component.update(); - - expect(component).toMatchSnapshot(); -}); - -test('should render line-style with label properties when ES-source is rendered as mvt', async () => { - const component = shallow( - - ); - - // Ensure all promises resolve - await new Promise((resolve) => process.nextTick(resolve)); - // Ensure the state changes are reflected - component.update(); - - expect(component).toMatchSnapshot(); -}); diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/vector_style_editor.tsx b/x-pack/plugins/maps/public/classes/styles/vector/components/vector_style_editor.tsx index d909f31315e7d3..e11a560c8755f8 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/vector_style_editor.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/vector_style_editor.tsx @@ -25,7 +25,6 @@ import { DEFAULT_FILL_COLORS, DEFAULT_LINE_COLORS } from '../../color_palettes'; import { LABEL_BORDER_SIZES, - LAYER_TYPE, STYLE_TYPE, VECTOR_SHAPE_TYPE, VECTOR_STYLES, @@ -258,18 +257,7 @@ export class VectorStyleEditor extends Component { ); } - _renderLabelProperties(isPoints: boolean) { - if ( - !isPoints && - this.props.layer.getType() === LAYER_TYPE.TILED_VECTOR && - !this.props.layer.getSource().isESSource() - ) { - // This handles and edge-case - // 3rd party lines and polygons from mvt sources cannot be labeled, because they do not have label-centroid geometries inside the tile. - // These label-centroids are only added for ES-sources - return; - } - + _renderLabelProperties() { const hasLabel = this._hasLabel(); const hasLabelBorder = this._hasLabelBorder(); return ( @@ -468,7 +456,7 @@ export class VectorStyleEditor extends Component { /> - {this._renderLabelProperties(true)} + {this._renderLabelProperties()} ); } @@ -482,7 +470,7 @@ export class VectorStyleEditor extends Component { {this._renderLineWidth()} - {this._renderLabelProperties(false)} + {this._renderLabelProperties()} ); } @@ -499,7 +487,7 @@ export class VectorStyleEditor extends Component { {this._renderLineWidth()} - {this._renderLabelProperties(false)} + {this._renderLabelProperties()} ); } diff --git a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.tsx b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.tsx index 73f8736750656e..bff053fc469a01 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/properties/dynamic_color_property.tsx @@ -135,7 +135,7 @@ export class DynamicColorProperty extends DynamicStyleProperty extends IStyleProperty { getFieldMetaOptions(): FieldMetaOptions; getField(): IField | null; getFieldName(): string; + getMbFieldName(): string; getFieldOrigin(): FIELD_ORIGIN | null; getRangeFieldMeta(): RangeFieldMeta | null; getCategoryFieldMeta(): CategoryFieldMeta | null; @@ -63,7 +58,7 @@ export interface IDynamicStyleProperty extends IStyleProperty { getFieldMetaRequest(): Promise; pluckOrdinalStyleMetaFromFeatures(features: Feature[]): RangeFieldMeta | null; pluckCategoricalStyleMetaFromFeatures(features: Feature[]): CategoryFieldMeta | null; - pluckOrdinalStyleMetaFromTileMetaFeatures(features: TileMetaFeature[]): RangeFieldMeta | null; + pluckOrdinalStyleMetaFromTileMetaFeatures(metaFeatures: TileMetaFeature[]): RangeFieldMeta | null; pluckCategoricalStyleMetaFromTileMetaFeatures( features: TileMetaFeature[] ): CategoryFieldMeta | null; @@ -213,6 +208,10 @@ export class DynamicStyleProperty return this._field ? this._field.getName() : ''; } + getMbFieldName() { + return this._field ? this._field.getMbFieldName() : ''; + } + isDynamic() { return true; } @@ -314,54 +313,36 @@ export class DynamicStyleProperty return null; } - const name = this.getFieldName(); + const mbFieldName = this.getMbFieldName(); let min = Infinity; let max = -Infinity; for (let i = 0; i < metaFeatures.length; i++) { - const fieldMeta = metaFeatures[i].properties.fieldMeta; - if (fieldMeta && fieldMeta[name] && fieldMeta[name].range) { - min = Math.min(fieldMeta[name].range?.min as number, min); - max = Math.max(fieldMeta[name].range?.max as number, max); + const fieldMeta = metaFeatures[i].properties; + const minField = `aggregations.${mbFieldName}.min`; + const maxField = `aggregations.${mbFieldName}.max`; + if ( + fieldMeta && + typeof fieldMeta[minField] === 'number' && + typeof fieldMeta[maxField] === 'number' + ) { + min = Math.min(fieldMeta[minField] as number, min); + max = Math.max(fieldMeta[maxField] as number, max); } } - return { - min, - max, - delta: max - min, - }; + + return min === Infinity || max === -Infinity + ? null + : { + min, + max, + delta: max - min, + }; } pluckCategoricalStyleMetaFromTileMetaFeatures( metaFeatures: TileMetaFeature[] ): CategoryFieldMeta | null { - const size = this.getNumberOfCategories(); - if (!this.isCategorical() || size <= 0) { - return null; - } - - const name = this.getFieldName(); - - const counts = new Map(); - for (let i = 0; i < metaFeatures.length; i++) { - const fieldMeta = metaFeatures[i].properties.fieldMeta; - if (fieldMeta && fieldMeta[name] && fieldMeta[name].categories) { - const categoryFieldMeta: CategoryFieldMeta = fieldMeta[name] - .categories as CategoryFieldMeta; - for (let c = 0; c < categoryFieldMeta.categories.length; c++) { - const category: Category = categoryFieldMeta.categories[c]; - // properties object may be sparse, so need to check if the field is effectively present - if (typeof category.key !== undefined) { - if (counts.has(category.key)) { - counts.set(category.key, (counts.get(category.key) as number) + category.count); - } else { - counts.set(category.key, category.count); - } - } - } - } - } - - return trimCategories(counts, size); + return null; } pluckOrdinalStyleMetaFromFeatures(features: Feature[]): RangeFieldMeta | null { @@ -370,9 +351,24 @@ export class DynamicStyleProperty } const name = this.getFieldName(); - return pluckRangeFieldMeta(features, name, (rawValue: unknown) => { - return parseFloat(rawValue as string); - }); + let min = Infinity; + let max = -Infinity; + for (let i = 0; i < features.length; i++) { + const feature = features[i]; + const newValue = feature.properties ? parseFloat(feature.properties[name]) : NaN; + if (!isNaN(newValue)) { + min = Math.min(min, newValue); + max = Math.max(max, newValue); + } + } + + return min === Infinity || max === -Infinity + ? null + : { + min, + max, + delta: max - min, + }; } pluckCategoricalStyleMetaFromFeatures(features: Feature[]): CategoryFieldMeta | null { @@ -381,7 +377,32 @@ export class DynamicStyleProperty return null; } - return pluckCategoryFieldMeta(features, this.getFieldName(), size); + const counts = new Map(); + for (let i = 0; i < features.length; i++) { + const feature = features[i]; + const term = feature.properties ? feature.properties[this.getFieldName()] : undefined; + // properties object may be sparse, so need to check if the field is effectively present + if (typeof term !== undefined) { + if (counts.has(term)) { + counts.set(term, counts.get(term) + 1); + } else { + counts.set(term, 1); + } + } + } + + const ordered = []; + for (const [key, value] of counts) { + ordered.push({ key, count: value }); + } + + ordered.sort((a, b) => { + return b.count - a.count; + }); + const truncated = ordered.slice(0, size); + return { + categories: truncated, + } as CategoryFieldMeta; } _pluckOrdinalStyleMetaFromFieldMetaData(styleMetaData: StyleMetaData): RangeFieldMeta | null { @@ -487,7 +508,7 @@ export class DynamicStyleProperty targetName = getComputedFieldName(this.getStyleName(), this._field.getName()); } else { // Non-geojson sources (e.g. 3rd party mvt or ES-source as mvt) - targetName = this._field.getName(); + targetName = this._field.getMbFieldName(); } } return targetName; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/vector_style.tsx b/x-pack/plugins/maps/public/classes/styles/vector/vector_style.tsx index 1e7267b9e1e328..058ee0db08d359 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/vector_style.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/vector_style.tsx @@ -16,7 +16,6 @@ import { FIELD_ORIGIN, GEO_JSON_TYPE, KBN_IS_CENTROID_FEATURE, - KBN_VECTOR_SHAPE_TYPE_COUNTS, LAYER_STYLE_TYPE, SOURCE_FORMATTERS_DATA_REQUEST_ID, STYLE_TYPE, @@ -76,7 +75,6 @@ import { IVectorLayer } from '../../layers/vector_layer'; import { IVectorSource } from '../../sources/vector_source'; import { createStyleFieldsHelper, StyleFieldsHelper } from './style_fields_helper'; import { IESAggField } from '../../fields/agg'; -import { VectorShapeTypeCounts } from '../../../../common/get_geometry_counts'; const POINTS = [GEO_JSON_TYPE.POINT, GEO_JSON_TYPE.MULTI_POINT]; const LINES = [GEO_JSON_TYPE.LINE_STRING, GEO_JSON_TYPE.MULTI_LINE_STRING]; @@ -92,9 +90,8 @@ export interface IVectorStyle extends IStyle { previousFields: IField[], mapColors: string[] ): Promise<{ hasChanges: boolean; nextStyleDescriptor?: VectorStyleDescriptor }>; - isTimeAware: () => boolean; - getIcon: () => ReactElement; - getIconFromGeometryTypes: (isLinesOnly: boolean, isPointsOnly: boolean) => ReactElement; + isTimeAware(): boolean; + getIcon(): ReactElement; hasLegendDetails: () => Promise; renderLegendDetails: () => ReactElement; clearFeatureState: (featureCollection: FeatureCollection, mbMap: MbMap, sourceId: string) => void; @@ -492,50 +489,16 @@ export class VectorStyle implements IVectorStyle { } async pluckStyleMetaFromTileMeta(metaFeatures: TileMetaFeature[]): Promise { - const shapeTypeCountMeta: VectorShapeTypeCounts = metaFeatures.reduce( - (accumulator: VectorShapeTypeCounts, tileMeta: TileMetaFeature) => { - if ( - !tileMeta || - !tileMeta.properties || - !tileMeta.properties[KBN_VECTOR_SHAPE_TYPE_COUNTS] - ) { - return accumulator; - } - - accumulator[VECTOR_SHAPE_TYPE.POINT] += - tileMeta.properties[KBN_VECTOR_SHAPE_TYPE_COUNTS][VECTOR_SHAPE_TYPE.POINT]; - accumulator[VECTOR_SHAPE_TYPE.LINE] += - tileMeta.properties[KBN_VECTOR_SHAPE_TYPE_COUNTS][VECTOR_SHAPE_TYPE.LINE]; - accumulator[VECTOR_SHAPE_TYPE.POLYGON] += - tileMeta.properties[KBN_VECTOR_SHAPE_TYPE_COUNTS][VECTOR_SHAPE_TYPE.POLYGON]; - - return accumulator; - }, - { - [VECTOR_SHAPE_TYPE.POLYGON]: 0, - [VECTOR_SHAPE_TYPE.LINE]: 0, - [VECTOR_SHAPE_TYPE.POINT]: 0, - } - ); - - const isLinesOnly = - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.LINE] > 0 && - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.POINT] === 0 && - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.POLYGON] === 0; - const isPointsOnly = - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.LINE] === 0 && - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.POINT] > 0 && - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.POLYGON] === 0; - const isPolygonsOnly = - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.LINE] === 0 && - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.POINT] === 0 && - shapeTypeCountMeta[VECTOR_SHAPE_TYPE.POLYGON] > 0; - + const supportedShapeTypes = await this._source.getSupportedShapeTypes(); const styleMeta: StyleMetaDescriptor = { geometryTypes: { - isPointsOnly, - isLinesOnly, - isPolygonsOnly, + isPointsOnly: + supportedShapeTypes.length === 1 && supportedShapeTypes.includes(VECTOR_SHAPE_TYPE.POINT), + isLinesOnly: + supportedShapeTypes.length === 1 && supportedShapeTypes.includes(VECTOR_SHAPE_TYPE.LINE), + isPolygonsOnly: + supportedShapeTypes.length === 1 && + supportedShapeTypes.includes(VECTOR_SHAPE_TYPE.POLYGON), }, fieldMeta: {}, }; @@ -737,7 +700,7 @@ export class VectorStyle implements IVectorStyle { : (this._iconStyleProperty as StaticIconProperty).getOptions().value; } - getIconFromGeometryTypes(isLinesOnly: boolean, isPointsOnly: boolean) { + _getIconFromGeometryTypes(isLinesOnly: boolean, isPointsOnly: boolean) { let strokeColor; if (isLinesOnly) { strokeColor = extractColorFromStyleProperty( @@ -771,7 +734,7 @@ export class VectorStyle implements IVectorStyle { getIcon() { const isLinesOnly = this._getIsLinesOnly(); const isPointsOnly = this._getIsPointsOnly(); - return this.getIconFromGeometryTypes(isLinesOnly, isPointsOnly); + return this._getIconFromGeometryTypes(isLinesOnly, isPointsOnly); } _getLegendDetailStyleProperties = () => { diff --git a/x-pack/plugins/maps/common/geo_tile_utils.test.js b/x-pack/plugins/maps/public/classes/util/geo_tile_utils.test.ts similarity index 100% rename from x-pack/plugins/maps/common/geo_tile_utils.test.js rename to x-pack/plugins/maps/public/classes/util/geo_tile_utils.test.ts diff --git a/x-pack/plugins/maps/common/geo_tile_utils.ts b/x-pack/plugins/maps/public/classes/util/geo_tile_utils.ts similarity index 95% rename from x-pack/plugins/maps/common/geo_tile_utils.ts rename to x-pack/plugins/maps/public/classes/util/geo_tile_utils.ts index 1a8ac3cbe17aec..6e82d3b5095654 100644 --- a/x-pack/plugins/maps/common/geo_tile_utils.ts +++ b/x-pack/plugins/maps/public/classes/util/geo_tile_utils.ts @@ -6,9 +6,9 @@ */ import _ from 'lodash'; -import { DECIMAL_DEGREES_PRECISION } from './constants'; -import { clampToLatBounds } from './elasticsearch_util'; -import { MapExtent } from './descriptor_types'; +import { DECIMAL_DEGREES_PRECISION } from '../../../common/constants'; +import { clampToLatBounds } from '../../../common/elasticsearch_util'; +import { MapExtent } from '../../../common/descriptor_types'; const ZOOM_TILE_KEY_INDEX = 0; const X_TILE_KEY_INDEX = 1; diff --git a/x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts b/x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts index 68efd416718fd5..544b2697cab439 100644 --- a/x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts +++ b/x-pack/plugins/maps/public/classes/util/mb_filter_expressions.ts @@ -9,7 +9,6 @@ import { GEO_JSON_TYPE, FEATURE_VISIBLE_PROPERTY_NAME, KBN_IS_CENTROID_FEATURE, - KBN_METADATA_FEATURE, } from '../../../common/constants'; import { Timeslice } from '../../../common/descriptor_types'; @@ -19,7 +18,6 @@ export interface TimesliceMaskConfig { timeslice: Timeslice; } -export const EXCLUDE_TOO_MANY_FEATURES_BOX = ['!=', ['get', KBN_METADATA_FEATURE], true]; export const EXCLUDE_CENTROID_FEATURES = ['!=', ['get', KBN_IS_CENTROID_FEATURE], true]; function getFilterExpression( @@ -56,7 +54,6 @@ export function getFillFilterExpression( ): unknown[] { return getFilterExpression( [ - EXCLUDE_TOO_MANY_FEATURES_BOX, EXCLUDE_CENTROID_FEATURES, [ 'any', @@ -75,7 +72,6 @@ export function getLineFilterExpression( ): unknown[] { return getFilterExpression( [ - EXCLUDE_TOO_MANY_FEATURES_BOX, EXCLUDE_CENTROID_FEATURES, [ 'any', @@ -96,7 +92,6 @@ export function getPointFilterExpression( ): unknown[] { return getFilterExpression( [ - EXCLUDE_TOO_MANY_FEATURES_BOX, EXCLUDE_CENTROID_FEATURES, [ 'any', @@ -109,13 +104,17 @@ export function getPointFilterExpression( ); } -export function getCentroidFilterExpression( +export function getLabelFilterExpression( hasJoins: boolean, + isSourceGeoJson: boolean, timesliceMaskConfig?: TimesliceMaskConfig ): unknown[] { - return getFilterExpression( - [EXCLUDE_TOO_MANY_FEATURES_BOX, ['==', ['get', KBN_IS_CENTROID_FEATURE], true]], - hasJoins, - timesliceMaskConfig - ); + const filters: unknown[] = []; + + // centroids added for geojson sources only + if (isSourceGeoJson) { + filters.push(['==', ['get', KBN_IS_CENTROID_FEATURE], true]); + } + + return getFilterExpression(filters, hasJoins, timesliceMaskConfig); } diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/__snapshots__/edit_layer_panel.test.tsx.snap b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/__snapshots__/edit_layer_panel.test.tsx.snap index 5fb1cc6f725854..1a3e97ee4fae19 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/__snapshots__/edit_layer_panel.test.tsx.snap +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/__snapshots__/edit_layer_panel.test.tsx.snap @@ -98,7 +98,9 @@ exports[`EditLayerPanel is rendered 1`] = ` "getId": [Function], "getImmutableSourceProperties": [Function], "getLayerTypeIconName": [Function], + "getType": [Function], "hasErrors": [Function], + "hasJoins": [Function], "renderSourceSettingsEditor": [Function], "showJoinEditor": [Function], "supportsElasticsearchFilters": [Function], @@ -119,7 +121,9 @@ exports[`EditLayerPanel is rendered 1`] = ` "getId": [Function], "getImmutableSourceProperties": [Function], "getLayerTypeIconName": [Function], + "getType": [Function], "hasErrors": [Function], + "hasJoins": [Function], "renderSourceSettingsEditor": [Function], "showJoinEditor": [Function], "supportsElasticsearchFilters": [Function], diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/edit_layer_panel.test.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/edit_layer_panel.test.tsx index e66dc8a10948fa..82795b8bd93179 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/edit_layer_panel.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/edit_layer_panel.test.tsx @@ -48,6 +48,7 @@ jest.mock('../../kibana_services', () => { import React from 'react'; import { shallow } from 'enzyme'; +import { LAYER_TYPE } from '../../../common/constants'; import { ILayer } from '../../classes/layers/layer'; import { EditLayerPanel } from './edit_layer_panel'; @@ -55,6 +56,9 @@ const mockLayer = { getId: () => { return '1'; }, + getType: () => { + return LAYER_TYPE.VECTOR; + }, getDisplayName: () => { return 'layer 1'; }, @@ -79,6 +83,9 @@ const mockLayer = { hasErrors: () => { return false; }, + hasJoins: () => { + return false; + }, supportsFitToBounds: () => { return true; }, @@ -87,7 +94,8 @@ const mockLayer = { const defaultProps = { selectedLayer: mockLayer, fitToBounds: () => {}, - updateSourceProp: () => {}, + updateSourceProps: async () => {}, + clearJoins: () => {}, }; describe('EditLayerPanel', () => { diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/edit_layer_panel.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/edit_layer_panel.tsx index 424c4b8e16bec1..7ba2f74ddc7d9d 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/edit_layer_panel.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/edit_layer_panel.tsx @@ -30,7 +30,6 @@ import { StyleSettings } from './style_settings'; import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; -import { LAYER_TYPE } from '../../../common/constants'; import { getData, getCore } from '../../kibana_services'; import { ILayer } from '../../classes/layers/layer'; import { isVectorLayer, IVectorLayer } from '../../classes/layers/vector_layer'; @@ -40,13 +39,9 @@ import { IField } from '../../classes/fields/field'; const localStorage = new Storage(window.localStorage); export interface Props { + clearJoins: (layer: ILayer) => void; selectedLayer?: ILayer; - updateSourceProp: ( - layerId: string, - propName: string, - value: unknown, - newLayerType?: LAYER_TYPE - ) => void; + updateSourceProps: (layerId: string, sourcePropChanges: OnSourceChangeArgs[]) => Promise; } interface State { @@ -141,9 +136,12 @@ export class EditLayerPanel extends Component { } _onSourceChange = (...args: OnSourceChangeArgs[]) => { - for (let i = 0; i < args.length; i++) { - const { propName, value, newLayerType } = args[i]; - this.props.updateSourceProp(this.props.selectedLayer!.getId(), propName, value, newLayerType); + return this.props.updateSourceProps(this.props.selectedLayer!.getId(), args); + }; + + _clearJoins = () => { + if (this.props.selectedLayer) { + this.props.clearJoins(this.props.selectedLayer); } }; @@ -279,6 +277,11 @@ export class EditLayerPanel extends Component { /> {this.props.selectedLayer.renderSourceSettingsEditor({ + clearJoins: this._clearJoins, + currentLayerType: this.props.selectedLayer.getType(), + hasJoins: isVectorLayer(this.props.selectedLayer) + ? (this.props.selectedLayer as IVectorLayer).hasJoins() + : false, onChange: this._onSourceChange, })} diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/index.ts b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/index.ts index 84caa45741a629..5f9a920d384948 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/index.ts +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/index.ts @@ -9,11 +9,12 @@ import { AnyAction } from 'redux'; import { ThunkDispatch } from 'redux-thunk'; import { connect } from 'react-redux'; import { EditLayerPanel } from './edit_layer_panel'; -import { LAYER_TYPE } from '../../../common/constants'; import { getSelectedLayer } from '../../selectors/map_selectors'; -import { updateSourceProp } from '../../actions'; +import { setJoinsForLayer, updateSourceProps } from '../../actions'; import { MapStoreState } from '../../reducers/store'; +import { ILayer } from '../../classes/layers/layer'; import { isVectorLayer, IVectorLayer } from '../../classes/layers/vector_layer'; +import { OnSourceChangeArgs } from '../../classes/sources/source'; function mapStateToProps(state: MapStoreState) { const selectedLayer = getSelectedLayer(state); @@ -31,8 +32,11 @@ function mapStateToProps(state: MapStoreState) { function mapDispatchToProps(dispatch: ThunkDispatch) { return { - updateSourceProp: (id: string, propName: string, value: unknown, newLayerType?: LAYER_TYPE) => - dispatch(updateSourceProp(id, propName, value, newLayerType)), + clearJoins: (layer: ILayer) => { + dispatch(setJoinsForLayer(layer, [])); + }, + updateSourceProps: async (id: string, sourcePropChanges: OnSourceChangeArgs[]) => + await dispatch(updateSourceProps(id, sourcePropChanges)), }; } diff --git a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.tsx b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.tsx index e99ec6a688092a..24cdd9b7dc8133 100644 --- a/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.tsx +++ b/x-pack/plugins/maps/public/connected_components/edit_layer_panel/join_editor/join_editor.tsx @@ -90,9 +90,7 @@ export function JoinEditor({ joins, layer, onChange, leftJoinFields, layerDispla ) : ( {renderJoins()} - - { ] as [MbPoint, MbPoint]; const selectedFeatures = this.props.mbMap.queryRenderedFeatures(mbBbox, { layers: mbEditLayerIds, - filter: ['all', EXCLUDE_TOO_MANY_FEATURES_BOX, EXCLUDE_CENTROID_FEATURES], + filter: ['all', EXCLUDE_CENTROID_FEATURES], }); if (!selectedFeatures.length) { return; diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx index 053e410b8c7123..93dfebecd1c34b 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/mb_map.tsx @@ -33,7 +33,6 @@ import { } from '../../../common/descriptor_types'; import { DECIMAL_DEGREES_PRECISION, - KBN_TOO_MANY_FEATURES_IMAGE_ID, LAYER_TYPE, RawValue, ZOOM_PRECISION, @@ -209,14 +208,6 @@ export class MbMap extends Component { }, }); - const tooManyFeaturesImageSrc = - 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAA7DgAAOw4BzLahgwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAAARLSURBVHic7ZnPbxRVAMe/7735sWO3293ZlUItJsivCxEE0oTYRgu1FqTQoFSwKTYx8SAH/wHjj4vRozGGi56sMcW2UfqTEuOhppE0KJc2GIuKQFDY7qzdtrudX88D3YTUdFuQN8+k87ltZt7uZz958/bNLAGwBWsYKltANmEA2QKyCQPIFpBNGEC2gGzCALIFZBMGkC0gmzCAbAHZhAFkC8gmDCBbQDZhANkCslnzARQZH6oDpNs0D5UDSUIInePcOpPLfdfnODNBuwQWIAWwNOABwHZN0x8npE6hNLJ4DPWRyFSf40wE5VOEQPBjcR0g3YlE4ybGmtK+/1NzJtOZA/xSYwZMs3nG962T2ez3It2AANaA/kSidYuivOQBs5WM1fUnk6f0u+GXJUqIuUtVXx00zRbRfkIDfBqL7a1WlIYbjvNtTTr99jXXHVpH6dMjK0R4cXq6c9rzxjcx9sKX8XitSEdhAToMI7VP10/97fsTh7PZrgWAN1lW72KE2vOm2b5chDTgtWQyn93x/bEEIetEOQIC14CxVOr1CkKefH929t0v8vn0vcdGEoljGxXl4C3PGz2YyXy+AHARDqtByAxoUdWKBKV70r4/vvTLA0CjZfX+5nkDGxirKzUTgkBIgNaysh3gnF627R+XO+dQJvP1ddcdrmSsbtA020pF+CAW21qrqmUiXIUEqGRsIwD0FQq/lzqv0bJ6rrvucBVjzwyb5ivLRTiiaW+8VV7eIEBVTAANiIIQd9RxZlc6t9Gyem647vn1jD07ZJonl4sQASoevqmgABzwwHnJzc69PGdZ3X+47sgGxuqHTPPE0ggeVtg5/QeEBMhxPg1Aa1DV2GrHPG9ZXy1G2D+wNALn9jyQEeHKAJgP+033Kgrdqij7AFwZtu3bqx3XWShMHtV1o1pRGo4YxiNd+fyEB2DKdX/4aG5u0hbwcylkBryTy/3scT6zW9Nq7ndso2Wdvea6Q1WUHuiPx1/WAXLBcWZXun94UMRcAoD/p+ddTFK6u8MwUvc7vsmyem+67oVqVT0wkEgcF+FYRNhW+L25uX6f84XThtHxIBudE5bVY/t++jFVrU/dvVSFICzAqG3PX/S8rihj2/61qK1AOUB7ksl2jdLUL7Z9rvgcQQRCFsEi5wqFmw26XnhCUQ63GcZmCly95Lrzpca0G0byk3j8tEnpU1c975tmyxoU5QcE8EAEAM5WVOzfoarHAeC2749dcpzxMwsLv07Ztg0AOzVNf03Ttu/S9T2PMlbjc25fdpyutmx2TLRbIAEA4M1otKo1EjmaoHQn4ZwBgA/kAVAK6MXXdzxv/ONcrq/HcbJBeAUWoEizqsaORaPbKglZrxMSZZyrM76f/ovzWx/m85PFWREUgQf4v7Hm/xcIA8gWkE0YQLaAbMIAsgVkEwaQLSCbMIBsAdmEAWQLyCYMIFtANmEA2QKyCQPIFpDNmg/wD3OFdEybUvJjAAAAAElFTkSuQmCC'; - const tooManyFeaturesImage = new Image(); - tooManyFeaturesImage.onload = () => { - mbMap.addImage(KBN_TOO_MANY_FEATURES_IMAGE_ID, tooManyFeaturesImage); - }; - tooManyFeaturesImage.src = tooManyFeaturesImageSrc; - let emptyImage: HTMLImageElement; mbMap.on('styleimagemissing', (e: unknown) => { if (emptyImage) { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx index 7e79113d6b242a..04b1d2205644f1 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.test.tsx @@ -36,6 +36,19 @@ const mockLayer = { canShowTooltip: () => { return true; }, + getMbTooltipLayerIds: () => { + return ['foo', 'bar']; + }, + getSource: () => { + return { + isMvt: () => { + return false; + }, + isESSource: () => { + return false; + }, + }; + }, getFeatureById: () => { return { geometry: { diff --git a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx index c2ad75d9cb3354..c2b89e64a449b9 100644 --- a/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx +++ b/x-pack/plugins/maps/public/connected_components/mb_map/tooltip_control/tooltip_control.tsx @@ -19,12 +19,7 @@ import uuid from 'uuid/v4'; import { Geometry } from 'geojson'; import { Filter } from 'src/plugins/data/public'; import { ActionExecutionContext, Action } from 'src/plugins/ui_actions/public'; -import { - FEATURE_ID_PROPERTY_NAME, - GEO_JSON_TYPE, - LON_INDEX, - RawValue, -} from '../../../../common/constants'; +import { GEO_JSON_TYPE, LON_INDEX, RawValue } from '../../../../common/constants'; import { GEOMETRY_FILTER_ACTION, TooltipFeature, @@ -33,9 +28,8 @@ import { } from '../../../../common/descriptor_types'; import { TooltipPopover } from './tooltip_popover'; import { FeatureGeometryFilterForm } from './features_tooltip'; -import { EXCLUDE_TOO_MANY_FEATURES_BOX } from '../../../classes/util/mb_filter_expressions'; import { ILayer } from '../../../classes/layers/layer'; -import { IVectorLayer, isVectorLayer } from '../../../classes/layers/vector_layer'; +import { IVectorLayer, isVectorLayer, getFeatureId } from '../../../classes/layers/vector_layer'; import { RenderToolTipContent } from '../../../classes/tooltips/tooltip_property'; function justifyAnchorLocation( @@ -132,7 +126,13 @@ export class TooltipControl extends Component { }) as IVectorLayer; } - _loadPreIndexedShape = async ({ layerId, featureId }: { layerId: string; featureId: string }) => { + _loadPreIndexedShape = async ({ + layerId, + featureId, + }: { + layerId: string; + featureId?: string | number; + }) => { const tooltipLayer = this._findLayerById(layerId); if (!tooltipLayer || typeof featureId === 'undefined') { return null; @@ -152,7 +152,7 @@ export class TooltipControl extends Component { tooltipId, }: { layerId: string; - featureId: string; + featureId?: string | number; tooltipId: string; }): TooltipFeatureAction[] { const actions = []; @@ -203,7 +203,8 @@ export class TooltipControl extends Component { if (!layer) { break; } - const featureId = mbFeature.properties?.[FEATURE_ID_PROPERTY_NAME]; + + const featureId = getFeatureId(mbFeature, layer.getSource()); const layerId = layer.getId(); let match = false; for (let j = 0; j < uniqueFeatures.length; j++) { @@ -284,9 +285,10 @@ export class TooltipControl extends Component { } const targetMbFeature = mbFeatures[0]; - if (this.props.openTooltips[0] && this.props.openTooltips[0].features.length) { + const layer = this._getLayerByMbLayerId(targetMbFeature.layer.id); + if (layer && this.props.openTooltips[0] && this.props.openTooltips[0].features.length) { const firstFeature = this.props.openTooltips[0].features[0]; - if (targetMbFeature.properties?.[FEATURE_ID_PROPERTY_NAME] === firstFeature.id) { + if (getFeatureId(targetMbFeature, layer.getSource()) === firstFeature.id) { // ignore hover events when hover tooltip is all ready opened for feature return; } @@ -312,7 +314,7 @@ export class TooltipControl extends Component { (accumulator: string[], layer: ILayer) => { // tooltips are only supported for vector layers, filter out all other layer types return layer.isVisible() && isVectorLayer(layer) - ? accumulator.concat(layer.getMbLayerIds()) + ? accumulator.concat((layer as IVectorLayer).getMbTooltipLayerIds()) : accumulator; }, [] @@ -347,7 +349,6 @@ export class TooltipControl extends Component { ] as [MbPoint, MbPoint]; return this.props.mbMap.queryRenderedFeatures(mbBbox, { layers: mbLayerIds, - filter: EXCLUDE_TOO_MANY_FEATURES_BOX, }); } diff --git a/x-pack/plugins/maps/server/kibana_server_services.ts b/x-pack/plugins/maps/server/kibana_server_services.ts index e3c612f415c4d4..f5bd4dad085d8b 100644 --- a/x-pack/plugins/maps/server/kibana_server_services.ts +++ b/x-pack/plugins/maps/server/kibana_server_services.ts @@ -20,14 +20,17 @@ export const setInternalRepository = ( }; export const getInternalRepository = () => internalRepository; +let esClient: ElasticsearchClient; let indexPatternsService: IndexPatternsCommonService; export const setIndexPatternsService = async ( indexPatternsServiceFactory: IndexPatternsServiceStart['indexPatternsServiceFactory'], elasticsearchClient: ElasticsearchClient ) => { + esClient = elasticsearchClient; indexPatternsService = await indexPatternsServiceFactory( new SavedObjectsClient(getInternalRepository()), elasticsearchClient ); }; export const getIndexPatternsService = () => indexPatternsService; +export const getESClient = () => esClient; diff --git a/x-pack/plugins/maps/server/mvt/get_grid_tile.ts b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts new file mode 100644 index 00000000000000..cfc894d5124508 --- /dev/null +++ b/x-pack/plugins/maps/server/mvt/get_grid_tile.ts @@ -0,0 +1,64 @@ +/* + * 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 { Logger } from 'src/core/server'; +import type { DataRequestHandlerContext } from 'src/plugins/data/server'; +import { RENDER_AS } from '../../common/constants'; + +function isAbortError(error: Error) { + return error.message === 'Request aborted' || error.message === 'Aborted'; +} + +export async function getEsGridTile({ + logger, + context, + index, + geometryFieldName, + x, + y, + z, + requestBody = {}, + requestType = RENDER_AS.POINT, +}: { + x: number; + y: number; + z: number; + geometryFieldName: string; + index: string; + context: DataRequestHandlerContext; + logger: Logger; + requestBody: any; + requestType: RENDER_AS.GRID | RENDER_AS.POINT; +}): Promise { + try { + const path = `/${encodeURIComponent(index)}/_mvt/${geometryFieldName}/${z}/${x}/${y}`; + const body = { + size: 0, // no hits + grid_precision: 7, + exact_bounds: false, + extent: 4096, // full resolution, + query: requestBody.query, + grid_type: requestType === RENDER_AS.GRID ? 'grid' : 'centroid', + aggs: requestBody.aggs, + fields: requestBody.fields, + runtime_mappings: requestBody.runtime_mappings, + }; + const tile = await context.core.elasticsearch.client.asCurrentUser.transport.request({ + method: 'GET', + path, + body, + }); + return tile.body as unknown as Buffer; + } catch (e) { + if (!isAbortError(e)) { + // These are often circuit breaking exceptions + // Should return a tile with some error message + logger.warn(`Cannot generate ES-grid-tile for ${z}/${x}/${y}: ${e.message}`); + } + return null; + } +} diff --git a/x-pack/plugins/maps/server/mvt/get_tile.ts b/x-pack/plugins/maps/server/mvt/get_tile.ts index 11e1af5a7d3686..0864b373af3f8b 100644 --- a/x-pack/plugins/maps/server/mvt/get_tile.ts +++ b/x-pack/plugins/maps/server/mvt/get_tile.ts @@ -5,53 +5,15 @@ * 2.0. */ -// @ts-expect-error -import geojsonvt from 'geojson-vt'; -// @ts-expect-error -import vtpbf from 'vt-pbf'; +import _ from 'lodash'; import { Logger } from 'src/core/server'; import type { DataRequestHandlerContext } from 'src/plugins/data/server'; -import { Feature, FeatureCollection, Polygon } from 'geojson'; -import { countVectorShapeTypes } from '../../common/get_geometry_counts'; -import { - COUNT_PROP_NAME, - ES_GEO_FIELD_TYPE, - FEATURE_ID_PROPERTY_NAME, - GEOTILE_GRID_AGG_NAME, - KBN_FEATURE_COUNT, - KBN_IS_TILE_COMPLETE, - KBN_METADATA_FEATURE, - KBN_VECTOR_SHAPE_TYPE_COUNTS, - MAX_ZOOM, - MVT_SOURCE_LAYER_NAME, - RENDER_AS, - SUPER_FINE_ZOOM_DELTA, - VECTOR_SHAPE_TYPE, -} from '../../common/constants'; - -import { - createExtentFilter, - convertRegularRespToGeoJson, - hitsToGeoJson, - isTotalHitsGreaterThan, - formatEnvelopeAsPolygon, - TotalHits, -} from '../../common/elasticsearch_util'; -import { flattenHit } from './util'; -import { ESBounds, tileToESBbox } from '../../common/geo_tile_utils'; -import { getCentroidFeatures } from '../../common/get_centroid_features'; -import { pluckRangeFieldMeta } from '../../common/pluck_range_field_meta'; -import { FieldMeta, TileMetaFeature } from '../../common/descriptor_types'; -import { pluckCategoryFieldMeta } from '../../common/pluck_category_field_meta'; - -// heuristic. largest color-palette has 30 colors. 1 color is used for 'other'. -const TERM_COUNT = 30 - 1; function isAbortError(error: Error) { return error.message === 'Request aborted' || error.message === 'Aborted'; } -export async function getGridTile({ +export async function getEsTile({ logger, context, index, @@ -60,9 +22,6 @@ export async function getGridTile({ y, z, requestBody = {}, - requestType = RENDER_AS.POINT, - searchSessionId, - abortSignal, }: { x: number; y: number; @@ -72,388 +31,32 @@ export async function getGridTile({ context: DataRequestHandlerContext; logger: Logger; requestBody: any; - requestType: RENDER_AS.GRID | RENDER_AS.POINT; - geoFieldType: ES_GEO_FIELD_TYPE; - searchSessionId?: string; - abortSignal: AbortSignal; }): Promise { try { - const tileBounds: ESBounds = tileToESBbox(x, y, z); - requestBody.query.bool.filter.push(getTileSpatialFilter(geometryFieldName, tileBounds)); - requestBody.aggs[GEOTILE_GRID_AGG_NAME].geotile_grid.precision = Math.min( - z + SUPER_FINE_ZOOM_DELTA, - MAX_ZOOM - ); - requestBody.aggs[GEOTILE_GRID_AGG_NAME].geotile_grid.bounds = tileBounds; - requestBody.track_total_hits = false; - - const response = await context - .search!.search( - { - params: { - index, - body: requestBody, - }, - }, - { - sessionId: searchSessionId, - legacyHitsTotal: false, - abortSignal, - } - ) - .toPromise(); - const features: Feature[] = convertRegularRespToGeoJson(response.rawResponse, requestType); - - if (features.length) { - const bounds = formatEnvelopeAsPolygon({ - maxLat: tileBounds.top_left.lat, - minLat: tileBounds.bottom_right.lat, - maxLon: tileBounds.bottom_right.lon, - minLon: tileBounds.top_left.lon, - }); - - const fieldNames = new Set(); - features.forEach((feature) => { - for (const key in feature.properties) { - if (feature.properties.hasOwnProperty(key) && key !== 'key' && key !== 'gridCentroid') { - fieldNames.add(key); - } - } - }); - - const fieldMeta: FieldMeta = {}; - fieldNames.forEach((fieldName: string) => { - const rangeMeta = pluckRangeFieldMeta(features, fieldName, (rawValue: unknown) => { - if (fieldName === COUNT_PROP_NAME) { - return parseFloat(rawValue as string); - } else if (typeof rawValue === 'number') { - return rawValue; - } else if (rawValue) { - return parseFloat((rawValue as { value: string }).value); - } else { - return NaN; - } - }); - - const categoryMeta = pluckCategoryFieldMeta(features, fieldName, TERM_COUNT); - - if (!fieldMeta[fieldName]) { - fieldMeta[fieldName] = {}; - } - - if (rangeMeta) { - fieldMeta[fieldName].range = rangeMeta; - } - - if (categoryMeta) { - fieldMeta[fieldName].categories = categoryMeta; - } - }); - - const metaDataFeature: TileMetaFeature = { - type: 'Feature', - properties: { - [KBN_METADATA_FEATURE]: true, - [KBN_FEATURE_COUNT]: features.length, - [KBN_IS_TILE_COMPLETE]: true, - [KBN_VECTOR_SHAPE_TYPE_COUNTS]: - requestType === RENDER_AS.GRID - ? { - [VECTOR_SHAPE_TYPE.POINT]: 0, - [VECTOR_SHAPE_TYPE.LINE]: 0, - [VECTOR_SHAPE_TYPE.POLYGON]: features.length, - } - : { - [VECTOR_SHAPE_TYPE.POINT]: features.length, - [VECTOR_SHAPE_TYPE.LINE]: 0, - [VECTOR_SHAPE_TYPE.POLYGON]: 0, - }, - fieldMeta, - }, - geometry: bounds, - }; - - features.push(metaDataFeature); - } - - const featureCollection: FeatureCollection = { - features, - type: 'FeatureCollection', + const path = `/${encodeURIComponent(index)}/_mvt/${geometryFieldName}/${z}/${x}/${y}`; + let fields = _.uniq(requestBody.docvalue_fields.concat(requestBody.stored_fields)); + fields = fields.filter((f) => f !== geometryFieldName); + const body = { + grid_precision: 0, // no aggs + exact_bounds: true, + extent: 4096, // full resolution, + query: requestBody.query, + fields, + runtime_mappings: requestBody.runtime_mappings, + track_total_hits: requestBody.size + 1, }; - - return createMvtTile(featureCollection, z, x, y); + const tile = await context.core.elasticsearch.client.asCurrentUser.transport.request({ + method: 'GET', + path, + body, + }); + return tile.body as unknown as Buffer; } catch (e) { if (!isAbortError(e)) { // These are often circuit breaking exceptions // Should return a tile with some error message - logger.warn(`Cannot generate grid-tile for ${z}/${x}/${y}: ${e.message}`); + logger.warn(`Cannot generate ES-grid-tile for ${z}/${x}/${y}: ${e.message}`); } return null; } } - -export async function getTile({ - logger, - context, - index, - geometryFieldName, - x, - y, - z, - requestBody = {}, - geoFieldType, - searchSessionId, - abortSignal, -}: { - x: number; - y: number; - z: number; - geometryFieldName: string; - index: string; - context: DataRequestHandlerContext; - logger: Logger; - requestBody: any; - geoFieldType: ES_GEO_FIELD_TYPE; - searchSessionId?: string; - abortSignal: AbortSignal; -}): Promise { - let features: Feature[]; - try { - requestBody.query.bool.filter.push( - getTileSpatialFilter(geometryFieldName, tileToESBbox(x, y, z)) - ); - - const searchOptions = { - sessionId: searchSessionId, - legacyHitsTotal: false, - abortSignal, - }; - - const countResponse = await context - .search!.search( - { - params: { - index, - body: { - size: 0, - query: requestBody.query, - track_total_hits: requestBody.size + 1, - }, - }, - }, - searchOptions - ) - .toPromise(); - - if ( - isTotalHitsGreaterThan( - countResponse.rawResponse.hits.total as unknown as TotalHits, - requestBody.size - ) - ) { - // Generate "too many features"-bounds - const bboxResponse = await context - .search!.search( - { - params: { - index, - body: { - size: 0, - query: requestBody.query, - aggs: { - data_bounds: { - geo_bounds: { - field: geometryFieldName, - }, - }, - }, - track_total_hits: false, - }, - }, - }, - searchOptions - ) - .toPromise(); - - const metaDataFeature: TileMetaFeature = { - type: 'Feature', - properties: { - [KBN_METADATA_FEATURE]: true, - [KBN_IS_TILE_COMPLETE]: false, - [KBN_FEATURE_COUNT]: 0, - [KBN_VECTOR_SHAPE_TYPE_COUNTS]: { - [VECTOR_SHAPE_TYPE.POINT]: 0, - [VECTOR_SHAPE_TYPE.LINE]: 0, - [VECTOR_SHAPE_TYPE.POLYGON]: 0, - }, - }, - geometry: esBboxToGeoJsonPolygon( - // @ts-expect-error @elastic/elasticsearch no way to declare aggregations for search response - bboxResponse.rawResponse.aggregations.data_bounds.bounds, - tileToESBbox(x, y, z) - ), - }; - features = [metaDataFeature]; - } else { - const documentsResponse = await context - .search!.search( - { - params: { - index, - body: { - ...requestBody, - track_total_hits: false, - }, - }, - }, - searchOptions - ) - .toPromise(); - - const featureCollection = hitsToGeoJson( - // @ts-expect-error hitsToGeoJson should be refactored to accept estypes.SearchHit - documentsResponse.rawResponse.hits.hits, - (hit: Record) => { - return flattenHit(geometryFieldName, hit); - }, - geometryFieldName, - geoFieldType, - [] - ); - - features = featureCollection.features; - - // Correct system-fields. - for (let i = 0; i < features.length; i++) { - const props = features[i].properties; - if (props !== null) { - props[FEATURE_ID_PROPERTY_NAME] = features[i].id; - } - } - - const counts = countVectorShapeTypes(features); - - const fieldNames = new Set(); - features.forEach((feature) => { - for (const key in feature.properties) { - if ( - feature.properties.hasOwnProperty(key) && - key !== '_index' && - key !== '_id' && - key !== FEATURE_ID_PROPERTY_NAME - ) { - fieldNames.add(key); - } - } - }); - - const fieldMeta: FieldMeta = {}; - fieldNames.forEach((fieldName: string) => { - const rangeMeta = pluckRangeFieldMeta(features, fieldName, (rawValue: unknown) => { - return typeof rawValue === 'number' ? rawValue : NaN; - }); - const categoryMeta = pluckCategoryFieldMeta(features, fieldName, TERM_COUNT); - - if (!fieldMeta[fieldName]) { - fieldMeta[fieldName] = {}; - } - - if (rangeMeta) { - fieldMeta[fieldName].range = rangeMeta; - } - - if (categoryMeta) { - fieldMeta[fieldName].categories = categoryMeta; - } - }); - - const metadataFeature: TileMetaFeature = { - type: 'Feature', - properties: { - [KBN_METADATA_FEATURE]: true, - [KBN_IS_TILE_COMPLETE]: true, - [KBN_VECTOR_SHAPE_TYPE_COUNTS]: counts, - [KBN_FEATURE_COUNT]: features.length, - fieldMeta, - }, - geometry: esBboxToGeoJsonPolygon(tileToESBbox(x, y, z), tileToESBbox(x, y, z)), - }; - - features.push(metadataFeature); - } - - const featureCollection: FeatureCollection = { - features, - type: 'FeatureCollection', - }; - - return createMvtTile(featureCollection, z, x, y); - } catch (e) { - if (!isAbortError(e)) { - logger.warn(`Cannot generate tile for ${z}/${x}/${y}: ${e.message}`); - } - return null; - } -} - -function getTileSpatialFilter(geometryFieldName: string, tileBounds: ESBounds): unknown { - const tileExtent = { - minLon: tileBounds.top_left.lon, - minLat: tileBounds.bottom_right.lat, - maxLon: tileBounds.bottom_right.lon, - maxLat: tileBounds.top_left.lat, - }; - const tileExtentFilter = createExtentFilter(tileExtent, [geometryFieldName]); - return tileExtentFilter.query; -} - -function esBboxToGeoJsonPolygon(esBounds: ESBounds, tileBounds: ESBounds): Polygon { - // Intersecting geo_shapes may push bounding box outside of tile so need to clamp to tile bounds. - let minLon = Math.max(esBounds.top_left.lon, tileBounds.top_left.lon); - const maxLon = Math.min(esBounds.bottom_right.lon, tileBounds.bottom_right.lon); - minLon = minLon > maxLon ? minLon - 360 : minLon; // fixes an ES bbox to straddle dateline - const minLat = Math.max(esBounds.bottom_right.lat, tileBounds.bottom_right.lat); - const maxLat = Math.min(esBounds.top_left.lat, tileBounds.top_left.lat); - - return { - type: 'Polygon', - coordinates: [ - [ - [minLon, minLat], - [minLon, maxLat], - [maxLon, maxLat], - [maxLon, minLat], - [minLon, minLat], - ], - ], - }; -} - -function createMvtTile( - featureCollection: FeatureCollection, - z: number, - x: number, - y: number -): Buffer | null { - featureCollection.features.push(...getCentroidFeatures(featureCollection)); - const tileIndex = geojsonvt(featureCollection, { - maxZoom: 24, // max zoom to preserve detail on; can't be higher than 24 - tolerance: 3, // simplification tolerance (higher means simpler) - extent: 4096, // tile extent (both width and height) - buffer: 64, // tile buffer on each side - debug: 0, // logging level (0 to disable, 1 or 2) - lineMetrics: false, // whether to enable line metrics tracking for LineString/MultiLineString features - promoteId: null, // name of a feature property to promote to feature.id. Cannot be used with `generateId` - generateId: false, // whether to generate feature ids. Cannot be used with `promoteId` - indexMaxZoom: 5, // max zoom in the initial tile index - indexMaxPoints: 100000, // max number of points per tile in the index - }); - const tile = tileIndex.getTile(z, x, y); - - if (tile) { - const pbf = vtpbf.fromGeojsonVt({ [MVT_SOURCE_LAYER_NAME]: tile }, { version: 2 }); - return Buffer.from(pbf); - } else { - return null; - } -} diff --git a/x-pack/plugins/maps/server/mvt/mvt_routes.ts b/x-pack/plugins/maps/server/mvt/mvt_routes.ts index 01a89aff1a6613..3c61a47a383d66 100644 --- a/x-pack/plugins/maps/server/mvt/mvt_routes.ts +++ b/x-pack/plugins/maps/server/mvt/mvt_routes.ts @@ -16,10 +16,10 @@ import { MVT_GETTILE_API_PATH, API_ROOT_PATH, MVT_GETGRIDTILE_API_PATH, - ES_GEO_FIELD_TYPE, RENDER_AS, } from '../../common/constants'; -import { getGridTile, getTile } from './get_tile'; +import { getEsTile } from './get_tile'; +import { getEsGridTile } from './get_grid_tile'; const CACHE_TIMEOUT_SECONDS = 60 * 60; @@ -43,8 +43,6 @@ export function initMVTRoutes({ geometryFieldName: schema.string(), requestBody: schema.string(), index: schema.string(), - geoFieldType: schema.string(), - searchSessionId: schema.maybe(schema.string()), token: schema.maybe(schema.string()), }), }, @@ -56,14 +54,15 @@ export function initMVTRoutes({ ) => { const { query, params } = request; - const abortController = new AbortController(); - request.events.aborted$.subscribe(() => { - abortController.abort(); - }); + // todo - replace with direct abortion of raw transport request + // const abortController = new AbortController(); + // request.events.aborted$.subscribe(() => { + // abortController.abort(); + // }); const requestBodyDSL = rison.decode(query.requestBody as string); - const tile = await getTile({ + const tile = await getEsTile({ logger, context, geometryFieldName: query.geometryFieldName as string, @@ -72,9 +71,6 @@ export function initMVTRoutes({ z: parseInt((params as any).z, 10) as number, index: query.index as string, requestBody: requestBodyDSL as any, - geoFieldType: query.geoFieldType as ES_GEO_FIELD_TYPE, - searchSessionId: query.searchSessionId, - abortSignal: abortController.signal, }); return sendResponse(response, tile); @@ -95,8 +91,6 @@ export function initMVTRoutes({ requestBody: schema.string(), index: schema.string(), requestType: schema.string(), - geoFieldType: schema.string(), - searchSessionId: schema.maybe(schema.string()), token: schema.maybe(schema.string()), }), }, @@ -107,14 +101,16 @@ export function initMVTRoutes({ response: KibanaResponseFactory ) => { const { query, params } = request; - const abortController = new AbortController(); - request.events.aborted$.subscribe(() => { - abortController.abort(); - }); + + // todo - replace with direct abortion of raw transport request + // const abortController = new AbortController(); + // request.events.aborted$.subscribe(() => { + // abortController.abort(); + // }); const requestBodyDSL = rison.decode(query.requestBody as string); - const tile = await getGridTile({ + const tile = await getEsGridTile({ logger, context, geometryFieldName: query.geometryFieldName as string, @@ -124,9 +120,6 @@ export function initMVTRoutes({ index: query.index as string, requestBody: requestBodyDSL as any, requestType: query.requestType as RENDER_AS.POINT | RENDER_AS.GRID, - geoFieldType: query.geoFieldType as ES_GEO_FIELD_TYPE, - searchSessionId: query.searchSessionId, - abortSignal: abortController.signal, }); return sendResponse(response, tile); diff --git a/x-pack/plugins/maps/server/mvt/util.ts b/x-pack/plugins/maps/server/mvt/util.ts deleted file mode 100644 index b3dc606ba3f11f..00000000000000 --- a/x-pack/plugins/maps/server/mvt/util.ts +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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. - */ - -// This implementation: -// - does not include meta-fields -// - does not validate the schema against the index-pattern (e.g. nested fields) -// In the context of .mvt this is sufficient: -// - only fields from the response are packed in the tile (more efficient) -// - query-dsl submitted from the client, which was generated by the IndexPattern -// todo: Ideally, this should adapt/reuse from https://github.com/elastic/kibana/blob/52b42a81faa9dd5c102b9fbb9a645748c3623121/src/plugins/data/common/index_patterns/index_patterns/flatten_hit.ts#L26 - -export function flattenHit( - geometryField: string, - hit: Record -): Record { - const flat: Record = {}; - if (hit) { - flattenSource(flat, '', hit._source as Record, geometryField); - if (hit.fields) { - flattenFields(flat, hit.fields as Array>); - } - - // Attach meta fields - flat._index = hit._index; - flat._id = hit._id; - } - return flat; -} - -function flattenSource( - accum: Record, - path: string, - properties: Record = {}, - geometryField: string -): Record { - accum = accum || {}; - for (const key in properties) { - if (properties.hasOwnProperty(key)) { - const newKey = path ? path + '.' + key : key; - let value; - if (geometryField === newKey) { - value = properties[key]; // do not deep-copy the geometry - } else if (properties[key] !== null && typeof value === 'object' && !Array.isArray(value)) { - value = flattenSource( - accum, - newKey, - properties[key] as Record, - geometryField - ); - } else { - value = properties[key]; - } - accum[newKey] = value; - } - } - return accum; -} - -function flattenFields(accum: Record = {}, fields: Array>) { - accum = accum || {}; - for (const key in fields) { - if (fields.hasOwnProperty(key)) { - const value = fields[key]; - if (Array.isArray(value)) { - accum[key] = value[0]; - } else { - accum[key] = value; - } - } - } -} diff --git a/x-pack/test/api_integration/apis/maps/get_grid_tile.js b/x-pack/test/api_integration/apis/maps/get_grid_tile.js index fdb8b2187bbbbe..c37dc9770693cc 100644 --- a/x-pack/test/api_integration/apis/maps/get_grid_tile.js +++ b/x-pack/test/api_integration/apis/maps/get_grid_tile.js @@ -8,10 +8,6 @@ import { VectorTile } from '@mapbox/vector-tile'; import Protobuf from 'pbf'; import expect from '@kbn/expect'; -import { - KBN_IS_CENTROID_FEATURE, - MVT_SOURCE_LAYER_NAME, -} from '../../../../plugins/maps/common/constants'; export default function ({ getService }) { const supertest = getService('supertest'); @@ -23,45 +19,53 @@ export default function ({ getService }) { `/api/maps/mvt/getGridTile/3/2/3.pbf\ ?geometryFieldName=geo.coordinates\ &index=logstash-*\ -&requestBody=(_source:(excludes:!()),aggs:(gridSplit:(aggs:(avg_of_bytes:(avg:(field:bytes)),gridCentroid:(geo_centroid:(field:geo.coordinates))),geotile_grid:(bounds:!n,field:geo.coordinates,precision:!n,shard_size:65535,size:65535))),fields:!((field:%27@timestamp%27,format:date_time),(field:%27relatedContent.article:modified_time%27,format:date_time),(field:%27relatedContent.article:published_time%27,format:date_time),(field:utc_time,format:date_time)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(hour_of_day:(script:(lang:painless,source:%27doc[!%27@timestamp!%27].value.getHour()%27))),size:0,stored_fields:!(%27*%27))\ -&requestType=point\ -&geoFieldType=geo_point` +&requestBody=(_source:(excludes:!()),aggs:(avg_of_bytes:(avg:(field:bytes))),fields:!((field:%27@timestamp%27,format:date_time),(field:%27relatedContent.article:modified_time%27,format:date_time),(field:%27relatedContent.article:published_time%27,format:date_time),(field:utc_time,format:date_time)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(hour_of_day:(script:(lang:painless,source:%27doc[!%27@timestamp!%27].value.getHour()%27))),size:0,stored_fields:!(%27*%27))\ +&requestType=point` ) .set('kbn-xsrf', 'kibana') .responseType('blob') .expect(200); const jsonTile = new VectorTile(new Protobuf(resp.body)); - const layer = jsonTile.layers[MVT_SOURCE_LAYER_NAME]; - expect(layer.length).to.be(2); // Cluster feature + const layer = jsonTile.layers.aggs; + expect(layer.length).to.be(1); const clusterFeature = layer.feature(0); expect(clusterFeature.type).to.be(1); expect(clusterFeature.extent).to.be(4096); expect(clusterFeature.id).to.be(undefined); - expect(clusterFeature.properties).to.eql({ doc_count: 1, avg_of_bytes: 9252 }); + expect(clusterFeature.properties).to.eql({ _count: 1, 'avg_of_bytes.value': 9252 }); expect(clusterFeature.loadGeometry()).to.eql([[{ x: 87, y: 667 }]]); // Metadata feature - const metadataFeature = layer.feature(1); + const metaDataLayer = jsonTile.layers.meta; + expect(metaDataLayer.length).to.be(1); + const metadataFeature = metaDataLayer.feature(0); expect(metadataFeature.type).to.be(3); expect(metadataFeature.extent).to.be(4096); - expect(metadataFeature.properties).to.eql({ - __kbn_metadata_feature__: true, - __kbn_feature_count__: 1, - __kbn_is_tile_complete__: true, - __kbn_vector_shape_type_counts__: '{"POINT":1,"LINE":0,"POLYGON":0}', - fieldMeta: - '{"doc_count":{"range":{"min":1,"max":1,"delta":0},"categories":{"categories":[{"key":1,"count":1}]}},"avg_of_bytes":{"range":{"min":9252,"max":9252,"delta":0},"categories":{"categories":[{"key":9252,"count":1}]}}}', - }); + + expect(metadataFeature.properties['aggregations._count.avg']).to.eql(1); + expect(metadataFeature.properties['aggregations._count.count']).to.eql(1); + expect(metadataFeature.properties['aggregations._count.min']).to.eql(1); + expect(metadataFeature.properties['aggregations._count.sum']).to.eql(1); + + expect(metadataFeature.properties['aggregations.avg_of_bytes.avg']).to.eql(9252); + expect(metadataFeature.properties['aggregations.avg_of_bytes.count']).to.eql(1); + expect(metadataFeature.properties['aggregations.avg_of_bytes.max']).to.eql(9252); + expect(metadataFeature.properties['aggregations.avg_of_bytes.min']).to.eql(9252); + expect(metadataFeature.properties['aggregations.avg_of_bytes.sum']).to.eql(9252); + + expect(metadataFeature.properties['hits.total.relation']).to.eql('eq'); + expect(metadataFeature.properties['hits.total.value']).to.eql(1); + expect(metadataFeature.loadGeometry()).to.eql([ [ - { x: 0, y: 0 }, - { x: 4096, y: 0 }, - { x: 4096, y: 4096 }, { x: 0, y: 4096 }, + { x: 4096, y: 4096 }, + { x: 4096, y: 0 }, { x: 0, y: 0 }, + { x: 0, y: 4096 }, ], ]); }); @@ -72,65 +76,62 @@ export default function ({ getService }) { `/api/maps/mvt/getGridTile/3/2/3.pbf\ ?geometryFieldName=geo.coordinates\ &index=logstash-*\ -&requestBody=(_source:(excludes:!()),aggs:(gridSplit:(aggs:(avg_of_bytes:(avg:(field:bytes)),gridCentroid:(geo_centroid:(field:geo.coordinates))),geotile_grid:(bounds:!n,field:geo.coordinates,precision:!n,shard_size:65535,size:65535))),fields:!((field:%27@timestamp%27,format:date_time),(field:%27relatedContent.article:modified_time%27,format:date_time),(field:%27relatedContent.article:published_time%27,format:date_time),(field:utc_time,format:date_time)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(hour_of_day:(script:(lang:painless,source:%27doc[!%27@timestamp!%27].value.getHour()%27))),size:0,stored_fields:!(%27*%27))\ -&requestType=grid\ -&geoFieldType=geo_point` +&requestBody=(_source:(excludes:!()),aggs:(avg_of_bytes:(avg:(field:bytes))),fields:!((field:%27@timestamp%27,format:date_time),(field:%27relatedContent.article:modified_time%27,format:date_time),(field:%27relatedContent.article:published_time%27,format:date_time),(field:utc_time,format:date_time)),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(hour_of_day:(script:(lang:painless,source:%27doc[!%27@timestamp!%27].value.getHour()%27))),size:0,stored_fields:!(%27*%27))\ +&requestType=grid` ) .set('kbn-xsrf', 'kibana') .responseType('blob') .expect(200); const jsonTile = new VectorTile(new Protobuf(resp.body)); - const layer = jsonTile.layers[MVT_SOURCE_LAYER_NAME]; - expect(layer.length).to.be(3); + const layer = jsonTile.layers.aggs; + expect(layer.length).to.be(1); const gridFeature = layer.feature(0); expect(gridFeature.type).to.be(3); expect(gridFeature.extent).to.be(4096); expect(gridFeature.id).to.be(undefined); - expect(gridFeature.properties).to.eql({ doc_count: 1, avg_of_bytes: 9252 }); + expect(gridFeature.properties).to.eql({ _count: 1, 'avg_of_bytes.value': 9252 }); expect(gridFeature.loadGeometry()).to.eql([ [ - { x: 96, y: 640 }, - { x: 96, y: 672 }, { x: 64, y: 672 }, - { x: 64, y: 640 }, + { x: 96, y: 672 }, { x: 96, y: 640 }, + { x: 64, y: 640 }, + { x: 64, y: 672 }, ], ]); // Metadata feature - const metadataFeature = layer.feature(1); + const metaDataLayer = jsonTile.layers.meta; + expect(metaDataLayer.length).to.be(1); + const metadataFeature = metaDataLayer.feature(0); expect(metadataFeature.type).to.be(3); expect(metadataFeature.extent).to.be(4096); - expect(metadataFeature.properties).to.eql({ - __kbn_metadata_feature__: true, - __kbn_feature_count__: 1, - __kbn_is_tile_complete__: true, - __kbn_vector_shape_type_counts__: '{"POINT":0,"LINE":0,"POLYGON":1}', - fieldMeta: - '{"doc_count":{"range":{"min":1,"max":1,"delta":0},"categories":{"categories":[{"key":1,"count":1}]}},"avg_of_bytes":{"range":{"min":9252,"max":9252,"delta":0},"categories":{"categories":[{"key":9252,"count":1}]}}}', - }); + + expect(metadataFeature.properties['aggregations._count.avg']).to.eql(1); + expect(metadataFeature.properties['aggregations._count.count']).to.eql(1); + expect(metadataFeature.properties['aggregations._count.min']).to.eql(1); + expect(metadataFeature.properties['aggregations._count.sum']).to.eql(1); + + expect(metadataFeature.properties['aggregations.avg_of_bytes.avg']).to.eql(9252); + expect(metadataFeature.properties['aggregations.avg_of_bytes.count']).to.eql(1); + expect(metadataFeature.properties['aggregations.avg_of_bytes.max']).to.eql(9252); + expect(metadataFeature.properties['aggregations.avg_of_bytes.min']).to.eql(9252); + expect(metadataFeature.properties['aggregations.avg_of_bytes.sum']).to.eql(9252); + + expect(metadataFeature.properties['hits.total.relation']).to.eql('eq'); + expect(metadataFeature.properties['hits.total.value']).to.eql(1); + expect(metadataFeature.loadGeometry()).to.eql([ [ - { x: 0, y: 0 }, - { x: 4096, y: 0 }, - { x: 4096, y: 4096 }, { x: 0, y: 4096 }, + { x: 4096, y: 4096 }, + { x: 4096, y: 0 }, { x: 0, y: 0 }, + { x: 0, y: 4096 }, ], ]); - - const clusterFeature = layer.feature(2); - expect(clusterFeature.type).to.be(1); - expect(clusterFeature.extent).to.be(4096); - expect(clusterFeature.id).to.be(undefined); - expect(clusterFeature.properties).to.eql({ - doc_count: 1, - avg_of_bytes: 9252, - [KBN_IS_CENTROID_FEATURE]: true, - }); - expect(clusterFeature.loadGeometry()).to.eql([[{ x: 80, y: 656 }]]); }); }); } diff --git a/x-pack/test/api_integration/apis/maps/get_tile.js b/x-pack/test/api_integration/apis/maps/get_tile.js index 9705064464843c..699ff145aa1b17 100644 --- a/x-pack/test/api_integration/apis/maps/get_tile.js +++ b/x-pack/test/api_integration/apis/maps/get_tile.js @@ -8,7 +8,6 @@ import { VectorTile } from '@mapbox/vector-tile'; import Protobuf from 'pbf'; import expect from '@kbn/expect'; -import { MVT_SOURCE_LAYER_NAME } from '../../../../plugins/maps/common/constants'; function findFeature(layer, callbackFn) { for (let i = 0; i < layer.length; i++) { @@ -23,22 +22,21 @@ export default function ({ getService }) { const supertest = getService('supertest'); describe('getTile', () => { - it('should return vector tile containing document', async () => { + it('should return ES vector tile containing documents and metadata', async () => { const resp = await supertest .get( `/api/maps/mvt/getTile/2/1/1.pbf\ ?geometryFieldName=geo.coordinates\ &index=logstash-*\ -&requestBody=(_source:!f,docvalue_fields:!(bytes,geo.coordinates,machine.os.raw),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:10000,stored_fields:!(bytes,geo.coordinates,machine.os.raw))\ -&geoFieldType=geo_point` +&requestBody=(_source:!f,docvalue_fields:!(bytes,geo.coordinates,machine.os.raw),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:10000,stored_fields:!(bytes,geo.coordinates,machine.os.raw))` ) .set('kbn-xsrf', 'kibana') .responseType('blob') .expect(200); const jsonTile = new VectorTile(new Protobuf(resp.body)); - const layer = jsonTile.layers[MVT_SOURCE_LAYER_NAME]; - expect(layer.length).to.be(3); // 2 docs + the metadata feature + const layer = jsonTile.layers.hits; + expect(layer.length).to.be(2); // 2 docs // Verify ES document @@ -50,82 +48,32 @@ export default function ({ getService }) { expect(feature.extent).to.be(4096); expect(feature.id).to.be(undefined); expect(feature.properties).to.eql({ - __kbn__feature_id__: 'logstash-2015.09.20:AU_x3_BsGFA8no6Qjjug:0', _id: 'AU_x3_BsGFA8no6Qjjug', _index: 'logstash-2015.09.20', bytes: 9252, - ['machine.os.raw']: 'ios', + 'machine.os.raw': 'ios', }); expect(feature.loadGeometry()).to.eql([[{ x: 44, y: 2382 }]]); // Verify metadata feature - const metadataFeature = findFeature(layer, (feature) => { - return feature.properties.__kbn_metadata_feature__; - }); + const metaDataLayer = jsonTile.layers.meta; + const metadataFeature = metaDataLayer.feature(0); expect(metadataFeature).not.to.be(undefined); expect(metadataFeature.type).to.be(3); expect(metadataFeature.extent).to.be(4096); expect(metadataFeature.id).to.be(undefined); - const fieldMeta = JSON.parse(metadataFeature.properties.fieldMeta); - delete metadataFeature.properties.fieldMeta; - expect(metadataFeature.properties).to.eql({ - __kbn_feature_count__: 2, - __kbn_is_tile_complete__: true, - __kbn_metadata_feature__: true, - __kbn_vector_shape_type_counts__: '{"POINT":2,"LINE":0,"POLYGON":0}', - }); - expect(fieldMeta.bytes.range).to.eql({ - min: 9252, - max: 9583, - delta: 331, - }); - expect(fieldMeta.bytes.categories.categories.length).to.be(2); - expect(fieldMeta['machine.os.raw'].categories.categories.length).to.be(2); - expect(metadataFeature.loadGeometry()).to.eql([ - [ - { x: 0, y: 4096 }, - { x: 0, y: 0 }, - { x: 4096, y: 0 }, - { x: 4096, y: 4096 }, - { x: 0, y: 4096 }, - ], - ]); - }); - it('should return vector tile containing bounds when count exceeds size', async () => { - const resp = await supertest - // requestBody sets size=1 to force count exceeded - .get( - `/api/maps/mvt/getTile/2/1/1.pbf\ -?geometryFieldName=geo.coordinates\ -&index=logstash-*\ -&requestBody=(_source:!f,docvalue_fields:!(bytes,geo.coordinates,machine.os.raw),query:(bool:(filter:!((match_all:()),(range:(%27@timestamp%27:(format:strict_date_optional_time,gte:%272015-09-20T00:00:00.000Z%27,lte:%272015-09-20T01:00:00.000Z%27)))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:1,stored_fields:!(bytes,geo.coordinates,machine.os.raw))\ -&geoFieldType=geo_point` - ) - .set('kbn-xsrf', 'kibana') - .responseType('blob') - .expect(200); + // This is dropping some irrelevant properties from the comparison + expect(metadataFeature.properties['hits.total.relation']).to.eql('eq'); + expect(metadataFeature.properties['hits.total.value']).to.eql(2); + expect(metadataFeature.properties.timed_out).to.eql(false); - const jsonTile = new VectorTile(new Protobuf(resp.body)); - const layer = jsonTile.layers[MVT_SOURCE_LAYER_NAME]; - expect(layer.length).to.be(1); - - const metadataFeature = layer.feature(0); - expect(metadataFeature.type).to.be(3); - expect(metadataFeature.extent).to.be(4096); - expect(metadataFeature.id).to.be(undefined); - expect(metadataFeature.properties).to.eql({ - __kbn_metadata_feature__: true, - __kbn_feature_count__: 0, - __kbn_is_tile_complete__: false, - __kbn_vector_shape_type_counts__: '{"POINT":0,"LINE":0,"POLYGON":0}', - }); expect(metadataFeature.loadGeometry()).to.eql([ [ { x: 44, y: 2382 }, - { x: 44, y: 1913 }, - { x: 550, y: 1913 }, { x: 550, y: 2382 }, + { x: 550, y: 1913 }, + { x: 44, y: 1913 }, { x: 44, y: 2382 }, ], ]); diff --git a/x-pack/test/functional/apps/maps/mapbox_styles.js b/x-pack/test/functional/apps/maps/mapbox_styles.js index 58c69950590cf6..471e7440822c5d 100644 --- a/x-pack/test/functional/apps/maps/mapbox_styles.js +++ b/x-pack/test/functional/apps/maps/mapbox_styles.js @@ -6,10 +6,6 @@ */ import expect from '@kbn/expect'; -import { - KBN_IS_TILE_COMPLETE, - KBN_METADATA_FEATURE, -} from '../../../../plugins/maps/common/constants'; export default function ({ getPageObjects, getService }) { const PageObjects = getPageObjects(['maps']); @@ -44,7 +40,6 @@ export default function ({ getPageObjects, getService }) { maxzoom: 24, filter: [ 'all', - ['!=', ['get', '__kbn_metadata_feature__'], true], ['!=', ['get', '__kbn_is_centroid_feature__'], true], ['any', ['==', ['geometry-type'], 'Point'], ['==', ['geometry-type'], 'MultiPoint']], ['==', ['get', '__kbn_isvisibleduetojoin__'], true], @@ -125,7 +120,6 @@ export default function ({ getPageObjects, getService }) { maxzoom: 24, filter: [ 'all', - ['!=', ['get', '__kbn_metadata_feature__'], true], ['!=', ['get', '__kbn_is_centroid_feature__'], true], ['any', ['==', ['geometry-type'], 'Polygon'], ['==', ['geometry-type'], 'MultiPolygon']], ['==', ['get', '__kbn_isvisibleduetojoin__'], true], @@ -202,7 +196,6 @@ export default function ({ getPageObjects, getService }) { maxzoom: 24, filter: [ 'all', - ['!=', ['get', '__kbn_metadata_feature__'], true], ['!=', ['get', '__kbn_is_centroid_feature__'], true], [ 'any', @@ -217,26 +210,5 @@ export default function ({ getPageObjects, getService }) { paint: { 'line-color': '#41937c', 'line-opacity': 0.75, 'line-width': 1 }, }); }); - - it('should style incomplete data layer as expected', async () => { - const layer = mapboxStyle.layers.find((mbLayer) => { - return mbLayer.id === 'n1t6f_toomanyfeatures'; - }); - - expect(layer).to.eql({ - id: 'n1t6f_toomanyfeatures', - type: 'fill', - source: 'n1t6f', - minzoom: 0, - maxzoom: 24, - filter: [ - 'all', - ['==', ['get', KBN_METADATA_FEATURE], true], - ['==', ['get', KBN_IS_TILE_COMPLETE], false], - ], - layout: { visibility: 'visible' }, - paint: { 'fill-pattern': '__kbn_too_many_features_image_id__', 'fill-opacity': 0.75 }, - }); - }); }); } diff --git a/x-pack/test/functional/apps/maps/mvt_scaling.js b/x-pack/test/functional/apps/maps/mvt_scaling.js index 66a511f6e9fecb..d9b660ba0d7308 100644 --- a/x-pack/test/functional/apps/maps/mvt_scaling.js +++ b/x-pack/test/functional/apps/maps/mvt_scaling.js @@ -31,7 +31,7 @@ export default function ({ getPageObjects, getService }) { //Source should be correct expect( mapboxStyle.sources[VECTOR_SOURCE_ID].tiles[0].startsWith( - `/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=geometry&index=geo_shapes*&requestBody=(_source:!(geometry),docvalue_fields:!(prop1),query:(bool:(filter:!(),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:10001,stored_fields:!(geometry,prop1))&geoFieldType=geo_shape` + `/api/maps/mvt/getTile/{z}/{x}/{y}.pbf?geometryFieldName=geometry&index=geo_shapes*&requestBody=(_source:!(geometry),docvalue_fields:!(prop1),query:(bool:(filter:!(),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(),size:10001,stored_fields:!(geometry,prop1))` ) ).to.equal(true); @@ -77,5 +77,34 @@ export default function ({ getPageObjects, getService }) { 'fill-opacity': 1, }); }); + + it('Style should include toomanyfeatures layer', async () => { + const mapboxStyle = await PageObjects.maps.getMapboxStyle(); + + const layer = mapboxStyle.layers.find((mbLayer) => { + return mbLayer.id === `${VECTOR_SOURCE_ID}_toomanyfeatures`; + }); + + expect(layer).to.eql({ + id: 'caffa63a-ebfb-466d-8ff6-d797975b88ab_toomanyfeatures', + type: 'line', + source: 'caffa63a-ebfb-466d-8ff6-d797975b88ab', + 'source-layer': 'meta', + minzoom: 0, + maxzoom: 24, + filter: [ + 'all', + ['==', ['get', 'hits.total.relation'], 'gte'], + ['>=', ['get', 'hits.total.value'], 10002], + ], + layout: { visibility: 'visible' }, + paint: { + 'line-color': '#fec514', + 'line-width': 3, + 'line-dasharray': [2, 1], + 'line-opacity': 1, + }, + }); + }); }); } diff --git a/x-pack/test/functional/apps/maps/mvt_super_fine.js b/x-pack/test/functional/apps/maps/mvt_super_fine.js index dcd2923cb93350..6c5065a77c1d29 100644 --- a/x-pack/test/functional/apps/maps/mvt_super_fine.js +++ b/x-pack/test/functional/apps/maps/mvt_super_fine.js @@ -34,7 +34,7 @@ export default function ({ getPageObjects, getService }) { //Source should be correct expect( mapboxStyle.sources[MB_VECTOR_SOURCE_ID].tiles[0].startsWith( - `/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=geo.coordinates&index=logstash-*&requestBody=(_source:(excludes:!()),aggs:(gridSplit:(aggs:(gridCentroid:(geo_centroid:(field:geo.coordinates)),max_of_bytes:(max:(field:bytes))),geotile_grid:(bounds:!n,field:geo.coordinates,precision:!n,shard_size:65535,size:65535))),fields:!((field:'@timestamp',format:date_time),(field:'relatedContent.article:modified_time',format:date_time),(field:'relatedContent.article:published_time',format:date_time),(field:utc_time,format:date_time)),query:(bool:(filter:!((range:('@timestamp':(format:strict_date_optional_time,gte:'2015-09-20T00:00:00.000Z',lte:'2015-09-20T01:00:00.000Z')))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(hour_of_day:(script:(lang:painless,source:'doc[!'@timestamp!'].value.getHour()'))),size:0,stored_fields:!('*'))&requestType=grid&geoFieldType=geo_point` + `/api/maps/mvt/getGridTile/{z}/{x}/{y}.pbf?geometryFieldName=geo.coordinates&index=logstash-*&requestBody=(_source:(excludes:!()),aggs:(max_of_bytes:(max:(field:bytes))),fields:!((field:'@timestamp',format:date_time),(field:'relatedContent.article:modified_time',format:date_time),(field:'relatedContent.article:published_time',format:date_time),(field:utc_time,format:date_time)),query:(bool:(filter:!((range:('@timestamp':(format:strict_date_optional_time,gte:'2015-09-20T00:00:00.000Z',lte:'2015-09-20T01:00:00.000Z')))),must:!(),must_not:!(),should:!())),runtime_mappings:(),script_fields:(hour_of_day:(script:(lang:painless,source:'doc[!'@timestamp!'].value.getHour()'))),size:0,stored_fields:!('*'))&requestType=grid` ) ).to.equal(true); @@ -51,9 +51,9 @@ export default function ({ getPageObjects, getService }) { 'coalesce', [ 'case', - ['==', ['get', 'max_of_bytes'], null], + ['==', ['get', 'max_of_bytes.value'], null], 1622, - ['max', ['min', ['to-number', ['get', 'max_of_bytes']], 9790], 1623], + ['max', ['min', ['to-number', ['get', 'max_of_bytes.value']], 9790], 1623], ], 1622, ], From b1dab1f0299ccc4d7aaee494aab266f805ace2ff Mon Sep 17 00:00:00 2001 From: Jason Stoltzfus Date: Mon, 25 Oct 2021 12:42:25 -0400 Subject: [PATCH 30/66] Suggestions enabled check (#116136) --- .../suggested_documents_callout.test.tsx | 15 ++++++- .../curation/suggested_documents_callout.tsx | 13 ++++-- .../curations/views/curations.test.tsx | 41 ++++++------------- .../components/curations/views/curations.tsx | 15 ++++--- .../views/curations_overview.test.tsx | 36 ++++------------ .../curations/views/curations_overview.tsx | 12 ++---- .../curations_settings_logic.test.ts | 16 ++++++++ .../curations_settings_logic.ts | 5 +++ .../components/engine/engine_logic.test.ts | 1 + .../app_search/components/engine/types.ts | 1 + .../suggested_curations_callout.test.tsx | 20 +++++---- .../suggested_curations_callout.tsx | 9 ++-- 12 files changed, 95 insertions(+), 89 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/suggested_documents_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/suggested_documents_callout.test.tsx index 29418d09218f46..b1f02b960aa8a1 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/suggested_documents_callout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/suggested_documents_callout.test.tsx @@ -26,6 +26,10 @@ const MOCK_VALUES = { }, queries: ['some query'], }, + // EngineLogic + engine: { + search_relevance_suggestions_active: true, + }, }; describe('SuggestedDocumentsCallout', () => { @@ -40,7 +44,7 @@ describe('SuggestedDocumentsCallout', () => { expect(wrapper.is(SuggestionsCallout)); }); - it('is empty when the suggested is undefined', () => { + it('is empty when the suggestion is undefined', () => { setMockValues({ ...MOCK_VALUES, curation: {} }); const wrapper = shallow(); @@ -48,6 +52,15 @@ describe('SuggestedDocumentsCallout', () => { expect(wrapper.isEmptyRender()).toBe(true); }); + it('is empty when suggestions are not active', () => { + const values = set('engine.search_relevance_suggestions_active', false, MOCK_VALUES); + setMockValues(values); + + const wrapper = shallow(); + + expect(wrapper.isEmptyRender()).toBe(true); + }); + it('is empty when curation status is not pending', () => { const values = set('curation.suggestion.status', 'applied', MOCK_VALUES); setMockValues(values); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/suggested_documents_callout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/suggested_documents_callout.tsx index e443e77d761900..af76ebee16bad3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/suggested_documents_callout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curation/suggested_documents_callout.tsx @@ -11,7 +11,7 @@ import { useValues } from 'kea'; import { i18n } from '@kbn/i18n'; import { ENGINE_CURATION_SUGGESTION_PATH } from '../../../routes'; -import { generateEnginePath } from '../../engine'; +import { EngineLogic, generateEnginePath } from '../../engine'; import { SuggestionsCallout } from '../components/suggestions_callout'; @@ -21,8 +21,15 @@ export const SuggestedDocumentsCallout: React.FC = () => { const { curation: { suggestion, queries }, } = useValues(CurationLogic); - - if (typeof suggestion === 'undefined' || suggestion.status !== 'pending') { + const { + engine: { search_relevance_suggestions_active: searchRelevanceSuggestionsActive }, + } = useValues(EngineLogic); + + if ( + typeof suggestion === 'undefined' || + suggestion.status !== 'pending' || + searchRelevanceSuggestionsActive === false + ) { return null; } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx index 4e09dadc6c8367..49d48c8c05ba65 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.test.tsx @@ -14,6 +14,8 @@ import React from 'react'; import { shallow } from 'enzyme'; +import { set } from 'lodash/fp'; + import { EuiTab } from '@elastic/eui'; import { getPageHeaderTabs, getPageTitle } from '../../../../test_helpers'; @@ -51,8 +53,10 @@ describe('Curations', () => { curationsSettings: { enabled: true, }, - // LicensingLogic - hasPlatinumLicense: true, + // EngineLogic + engine: { + search_relevance_suggestions_active: true, + }, }; const actions = { @@ -84,8 +88,8 @@ describe('Curations', () => { expect(actions.onSelectPageTab).toHaveBeenNthCalledWith(3, 'settings'); }); - it('renders less tabs when less than platinum license', () => { - setMockValues({ ...values, hasPlatinumLicense: false }); + it('renders less tabs when suggestions are not active', () => { + setMockValues(set('engine.search_relevance_suggestions_active', false, values)); const wrapper = shallow(); expect(getPageTitle(wrapper)).toEqual('Curated results'); @@ -94,8 +98,8 @@ describe('Curations', () => { expect(tabs.length).toBe(2); }); - it('renders a New! badge when less than platinum license', () => { - setMockValues({ ...values, hasPlatinumLicense: false }); + it('renders a New! badge when suggestions are not active', () => { + setMockValues(set('engine.search_relevance_suggestions_active', false, values)); const wrapper = shallow(); expect(getPageTitle(wrapper)).toEqual('Curated results'); @@ -104,29 +108,8 @@ describe('Curations', () => { expect(tabs.at(1).prop('append')).not.toBeUndefined(); }); - it('renders a New! badge when suggestions are disabled', () => { - setMockValues({ - ...values, - curationsSettings: { - enabled: false, - }, - }); - const wrapper = shallow(); - - expect(getPageTitle(wrapper)).toEqual('Curated results'); - - const tabs = getPageHeaderTabs(wrapper).find(EuiTab); - expect(tabs.at(2).prop('append')).not.toBeUndefined(); - }); - - it('hides the badge when suggestions are enabled and the user has a platinum license', () => { - setMockValues({ - ...values, - hasPlatinumLicense: true, - curationsSettings: { - enabled: true, - }, - }); + it('hides the badge when suggestions are active', () => { + setMockValues(set('engine.search_relevance_suggestions_active', true, values)); const wrapper = shallow(); expect(getPageTitle(wrapper)).toEqual('Curated results'); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx index 1cd83137435367..2207555772b5bf 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations.tsx @@ -12,11 +12,10 @@ import { useValues, useActions } from 'kea'; import { EuiBadge } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { LicensingLogic } from '../../../../shared/licensing'; import { EuiButtonTo } from '../../../../shared/react_router_helpers'; import { ENGINE_CURATIONS_NEW_PATH } from '../../../routes'; -import { generateEnginePath } from '../../engine'; +import { EngineLogic, generateEnginePath } from '../../engine'; import { AppSearchPageTemplate } from '../../layout'; import { CURATIONS_OVERVIEW_TITLE, CREATE_NEW_CURATION_TITLE } from '../constants'; @@ -30,13 +29,13 @@ import { CurationsSettings, CurationsSettingsLogic } from './curations_settings' export const Curations: React.FC = () => { const { dataLoading: curationsDataLoading, meta, selectedPageTab } = useValues(CurationsLogic); const { loadCurations, onSelectPageTab } = useActions(CurationsLogic); - const { hasPlatinumLicense } = useValues(LicensingLogic); const { - dataLoading: curationsSettingsDataLoading, - curationsSettings: { enabled: curationsSettingsEnabled }, - } = useValues(CurationsSettingsLogic); + engine: { search_relevance_suggestions_active: searchRelevanceSuggestionsActive }, + } = useValues(EngineLogic); - const suggestionsEnabled = hasPlatinumLicense && curationsSettingsEnabled; + const { dataLoading: curationsSettingsDataLoading } = useValues(CurationsSettingsLogic); + + const suggestionsEnabled = searchRelevanceSuggestionsActive; const OVERVIEW_TAB = { label: i18n.translate( @@ -75,7 +74,7 @@ export const Curations: React.FC = () => { ), }; - const pageTabs = hasPlatinumLicense + const pageTabs = searchRelevanceSuggestionsActive ? [OVERVIEW_TAB, HISTORY_TAB, SETTINGS_TAB] : [OVERVIEW_TAB, SETTINGS_TAB]; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_overview.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_overview.test.tsx index 809157704a14e9..43ef9dfd7ad2bb 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_overview.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_overview.test.tsx @@ -12,6 +12,7 @@ import '../../../__mocks__/engine_logic.mock'; import React from 'react'; import { shallow } from 'enzyme'; +import { set } from 'lodash/fp'; import { CurationsTable, EmptyState } from '../components'; @@ -33,8 +34,10 @@ const MOCK_VALUES = { id: 'cur-id-2', }, ], - // LicensingLogics - hasPlatinumLicense: true, + // EngineLogic + engine: { + search_relevance_suggestions_active: true, + }, }; describe('CurationsOverview', () => { @@ -67,36 +70,15 @@ describe('CurationsOverview', () => { expect(wrapper.find(CurationsTable)).toHaveLength(1); }); - it('renders a suggestions table when the user has a platinum license and curations suggestions enabled', () => { - setMockValues({ - ...MOCK_VALUES, - hasPlatinumLicense: true, - curationsSettings: { - enabled: true, - }, - }); + it('renders a suggestions table when suggestions are active', () => { + setMockValues(set('engine.search_relevance_suggestions_active', true, MOCK_VALUES)); const wrapper = shallow(); expect(wrapper.find(SuggestionsTable).exists()).toBe(true); }); - it('doesn\t render a suggestions table when the user has no platinum license', () => { - setMockValues({ - ...MOCK_VALUES, - hasPlatinumLicense: false, - }); - const wrapper = shallow(); - - expect(wrapper.find(SuggestionsTable).exists()).toBe(false); - }); - - it('doesn\t render a suggestions table when the user has disabled suggestions', () => { - setMockValues({ - ...MOCK_VALUES, - curationsSettings: { - enabled: false, - }, - }); + it('doesn\t render a suggestions table when suggestions are not active', () => { + setMockValues(set('engine.search_relevance_suggestions_active', false, MOCK_VALUES)); const wrapper = shallow(); expect(wrapper.find(SuggestionsTable).exists()).toBe(false); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_overview.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_overview.tsx index 00593403b08cf0..a611ca88cefd43 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_overview.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_overview.tsx @@ -11,22 +11,18 @@ import { useValues } from 'kea'; import { EuiSpacer } from '@elastic/eui'; -import { LicensingLogic } from '../../../../shared/licensing'; +import { EngineLogic } from '../../engine'; import { CurationsTable, EmptyState } from '../components'; import { SuggestionsTable } from '../components/suggestions_table'; import { CurationsLogic } from '../curations_logic'; -import { CurationsSettingsLogic } from './curations_settings'; - export const CurationsOverview: React.FC = () => { const { curations } = useValues(CurationsLogic); - const { hasPlatinumLicense } = useValues(LicensingLogic); - const { - curationsSettings: { enabled }, - } = useValues(CurationsSettingsLogic); + engine: { search_relevance_suggestions_active: searchRelevanceSuggestionsActive }, + } = useValues(EngineLogic); - const shouldShowSuggestions = enabled && hasPlatinumLicense; + const shouldShowSuggestions = searchRelevanceSuggestionsActive; return ( <> diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings_logic.test.ts index 818fac3d0706ef..b8aae9c39174d0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings_logic.test.ts @@ -12,8 +12,20 @@ import { } from '../../../../../__mocks__/kea_logic'; import '../../../../__mocks__/engine_logic.mock'; +jest.mock('../../curations_logic', () => ({ + CurationsLogic: { + values: {}, + actions: { + loadCurations: jest.fn(), + }, + }, +})); + import { nextTick } from '@kbn/test/jest'; +import { CurationsLogic } from '../..'; +import { EngineLogic } from '../../../engine'; + import { CurationsSettingsLogic } from './curations_settings_logic'; const DEFAULT_VALUES = { @@ -205,6 +217,10 @@ describe('CurationsSettingsLogic', () => { enabled: true, mode: 'automatic', }); + + // data should have been reloaded + expect(EngineLogic.actions.initializeEngine).toHaveBeenCalled(); + expect(CurationsLogic.actions.loadCurations).toHaveBeenCalled(); }); it('presents any API errors to the user', async () => { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings_logic.ts index d79ad64a697882..3984cbd024da46 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curations_settings/curations_settings_logic.ts @@ -10,6 +10,7 @@ import { kea, MakeLogicType } from 'kea'; import { flashAPIErrors } from '../../../../../shared/flash_messages'; import { HttpLogic } from '../../../../../shared/http'; import { EngineLogic } from '../../../engine'; +import { CurationsLogic } from '../../curations_logic'; export interface CurationsSettings { enabled: boolean; @@ -101,6 +102,10 @@ export const CurationsSettingsLogic = kea< } ); actions.onCurationsSettingsLoad(response.curation); + + // Re-fetch data so that UI updates to new settings + CurationsLogic.actions.loadCurations(); + EngineLogic.actions.initializeEngine(); } catch (e) { flashAPIErrors(e); } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts index 28739a27993325..bb30190833dd31 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/engine_logic.test.ts @@ -43,6 +43,7 @@ describe('EngineLogic', () => { schema: { test: SchemaType.Text }, apiTokens: [], apiKey: 'some-key', + search_relevance_suggestions_active: true, }; const DEFAULT_VALUES = { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/types.ts index d4c652ab9c7a7b..0bfbc185b85f32 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine/types.ts @@ -54,6 +54,7 @@ export interface EngineDetails extends Engine { engine_count?: number; includedEngines?: EngineDetails[]; search_relevance_suggestions?: SearchRelevanceSuggestionDetails; + search_relevance_suggestions_active: boolean; } interface ResultField { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/suggested_curations_callout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/suggested_curations_callout.test.tsx index 58e2cd8cf4c9b0..c65d95a5254ee4 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/suggested_curations_callout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/suggested_curations_callout.test.tsx @@ -18,16 +18,14 @@ import { SuggestionsCallout } from '../../curations/components/suggestions_callo import { SuggestedCurationsCallout } from './suggested_curations_callout'; const MOCK_VALUES = { - // EngineLogic engine: { search_relevance_suggestions: { curation: { pending: 1, }, }, + search_relevance_suggestions_active: true, }, - // LicensingLogic - hasPlatinumLicense: true, }; describe('SuggestedCurationsCallout', () => { @@ -43,15 +41,20 @@ describe('SuggestedCurationsCallout', () => { }); it('is empty when the suggestions are undefined', () => { - setMockValues({ ...MOCK_VALUES, engine: {} }); + setMockValues({ + ...MOCK_VALUES, + engine: { + search_relevance_suggestions_active: true, + }, + }); const wrapper = shallow(); expect(wrapper.isEmptyRender()).toBe(true); }); - it('is empty when no pending curations', () => { - const values = set('engine.search_relevance_suggestions.curation.pending', 0, MOCK_VALUES); + it('is empty when suggestions are not active', () => { + const values = set('engine.search_relevance_suggestions_active', false, MOCK_VALUES); setMockValues(values); const wrapper = shallow(); @@ -59,9 +62,8 @@ describe('SuggestedCurationsCallout', () => { expect(wrapper.isEmptyRender()).toBe(true); }); - it('is empty when the user has no platinum license', () => { - // This would happen if the user *had* suggestions and then downgraded from platinum to gold or something - const values = set('hasPlatinumLicense', false, MOCK_VALUES); + it('is empty when no pending curations', () => { + const values = set('engine.search_relevance_suggestions.curation.pending', 0, MOCK_VALUES); setMockValues(values); const wrapper = shallow(); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/suggested_curations_callout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/suggested_curations_callout.tsx index 046cc2d744b009..04b2d2b207e94a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/suggested_curations_callout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/suggested_curations_callout.tsx @@ -10,23 +10,24 @@ import { useValues } from 'kea'; import { i18n } from '@kbn/i18n'; -import { LicensingLogic } from '../../../../shared/licensing'; import { ENGINE_CURATIONS_PATH } from '../../../routes'; import { SuggestionsCallout } from '../../curations/components/suggestions_callout'; import { EngineLogic, generateEnginePath } from '../../engine'; export const SuggestedCurationsCallout: React.FC = () => { const { - engine: { search_relevance_suggestions: searchRelevanceSuggestions }, + engine: { + search_relevance_suggestions: searchRelevanceSuggestions, + search_relevance_suggestions_active: searchRelevanceSuggestionsActive, + }, } = useValues(EngineLogic); - const { hasPlatinumLicense } = useValues(LicensingLogic); const pendingCount = searchRelevanceSuggestions?.curation.pending; if ( typeof searchRelevanceSuggestions === 'undefined' || pendingCount === 0 || - hasPlatinumLicense === false + searchRelevanceSuggestionsActive === false ) { return null; } From 14ac1643e6d12ab37f4f347adcd623dc5495ac2e Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Mon, 25 Oct 2021 19:51:26 +0300 Subject: [PATCH 31/66] [Cases] Add another newline after a quote message (#116104) --- .../components/add_comment/index.test.tsx | 34 +++++++++++- .../public/components/add_comment/index.tsx | 53 +++++++++++++++++-- .../components/markdown_editor/editor.tsx | 2 +- .../user_action_tree/index.test.tsx | 2 +- .../components/user_action_tree/index.tsx | 4 +- 5 files changed, 84 insertions(+), 11 deletions(-) diff --git a/x-pack/plugins/cases/public/components/add_comment/index.test.tsx b/x-pack/plugins/cases/public/components/add_comment/index.test.tsx index 06a38976879215..c15722a3ec3547 100644 --- a/x-pack/plugins/cases/public/components/add_comment/index.test.tsx +++ b/x-pack/plugins/cases/public/components/add_comment/index.test.tsx @@ -120,7 +120,7 @@ describe('AddComment ', () => { }); it('should insert a quote', async () => { - const sampleQuote = 'what a cool quote'; + const sampleQuote = 'what a cool quote \n with new lines'; const ref = React.createRef(); const wrapper = mount( @@ -138,10 +138,40 @@ describe('AddComment ', () => { }); expect(wrapper.find(`[data-test-subj="add-comment"] textarea`).text()).toBe( - `${sampleData.comment}\n\n${sampleQuote}` + `${sampleData.comment}\n\n> what a cool quote \n> with new lines \n\n` ); }); + it('should call onFocus when adding a quote', async () => { + const ref = React.createRef(); + + mount( + + + + ); + + ref.current!.editor!.textarea!.focus = jest.fn(); + await act(async () => { + ref.current!.addQuote('a comment'); + }); + + expect(ref.current!.editor!.textarea!.focus).toHaveBeenCalled(); + }); + + it('should NOT call onFocus on mount', async () => { + const ref = React.createRef(); + + mount( + + + + ); + + ref.current!.editor!.textarea!.focus = jest.fn(); + expect(ref.current!.editor!.textarea!.focus).not.toHaveBeenCalled(); + }); + it('it should insert a timeline', async () => { const useInsertTimelineMock = jest.fn(); let attachTimeline = noop; diff --git a/x-pack/plugins/cases/public/components/add_comment/index.tsx b/x-pack/plugins/cases/public/components/add_comment/index.tsx index f788456a30dfff..3ee7c1604b24d8 100644 --- a/x-pack/plugins/cases/public/components/add_comment/index.tsx +++ b/x-pack/plugins/cases/public/components/add_comment/index.tsx @@ -5,14 +5,22 @@ * 2.0. */ +import React, { + useCallback, + useRef, + forwardRef, + useImperativeHandle, + useEffect, + useState, +} from 'react'; import { EuiButton, EuiFlexItem, EuiFlexGroup, EuiLoadingSpinner } from '@elastic/eui'; -import React, { useCallback, useRef, forwardRef, useImperativeHandle } from 'react'; import styled from 'styled-components'; +import { isEmpty } from 'lodash'; import { CommentType } from '../../../common'; import { usePostComment } from '../../containers/use_post_comment'; import { Case } from '../../containers/types'; -import { MarkdownEditorForm } from '../markdown_editor'; +import { EuiMarkdownEditorRef, MarkdownEditorForm } from '../markdown_editor'; import { Form, useForm, UseField, useFormData } from '../../common/shared_imports'; import * as i18n from './translations'; @@ -33,6 +41,7 @@ const initialCommentValue: AddCommentFormSchema = { export interface AddCommentRefObject { addQuote: (quote: string) => void; setComment: (newComment: string) => void; + editor: EuiMarkdownEditorRef | null; } export interface AddCommentProps { @@ -61,7 +70,8 @@ export const AddComment = React.memo( }, ref ) => { - const editorRef = useRef(); + const editorRef = useRef(null); + const [focusOnContext, setFocusOnContext] = useState(false); const owner = useOwnerContext(); const { isLoading, postComment } = usePostComment(); @@ -77,7 +87,10 @@ export const AddComment = React.memo( const addQuote = useCallback( (quote) => { - setFieldValue(fieldName, `${comment}${comment.length > 0 ? '\n\n' : ''}${quote}`); + const addCarrots = quote.replace(new RegExp('\r?\n', 'g'), '\n> '); + const val = `> ${addCarrots} \n\n`; + setFieldValue(fieldName, `${comment}${comment.length > 0 ? '\n\n' : ''}${val}`); + setFocusOnContext(true); }, [comment, setFieldValue] ); @@ -111,6 +124,38 @@ export const AddComment = React.memo( } }, [submit, onCommentSaving, postComment, caseId, owner, onCommentPosted, subCaseId, reset]); + /** + * Focus on the text area when a quote has been added. + * + * The useEffect will run only when focusOnContext + * changes. + * + * The useEffect is also called once one mount + * where the comment is empty. We do not want to focus + * in this scenario. + * + * Ideally we would like to put the + * editorRef.current?.textarea?.focus(); inside the if (focusOnContext). + * The reason this is not feasible is because when it sets the + * focusOnContext to false a render will occur again and the + * focus will be lost. + * + * We do not put the comment in the dependency list + * because we do not want to focus when the user + * is typing. + */ + + useEffect(() => { + if (!isEmpty(comment)) { + editorRef.current?.textarea?.focus(); + } + + if (focusOnContext) { + setFocusOnContext(false); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [focusOnContext]); + return ( {isLoading && showLoading && } diff --git a/x-pack/plugins/cases/public/components/markdown_editor/editor.tsx b/x-pack/plugins/cases/public/components/markdown_editor/editor.tsx index f2351a2b2d793b..4bf25b23403e16 100644 --- a/x-pack/plugins/cases/public/components/markdown_editor/editor.tsx +++ b/x-pack/plugins/cases/public/components/markdown_editor/editor.tsx @@ -37,7 +37,7 @@ interface MarkdownEditorProps { value: string; } -type EuiMarkdownEditorRef = ElementRef; +export type EuiMarkdownEditorRef = ElementRef; export interface MarkdownEditorRef { textarea: HTMLTextAreaElement | null; diff --git a/x-pack/plugins/cases/public/components/user_action_tree/index.test.tsx b/x-pack/plugins/cases/public/components/user_action_tree/index.test.tsx index dd5c993939b82e..5241b0e66fb381 100644 --- a/x-pack/plugins/cases/public/components/user_action_tree/index.test.tsx +++ b/x-pack/plugins/cases/public/components/user_action_tree/index.test.tsx @@ -348,7 +348,7 @@ describe(`UserActionTree`, () => { .first() .simulate('click'); await waitFor(() => { - expect(setFieldValue).toBeCalledWith('comment', `> ${props.data.description} \n`); + expect(setFieldValue).toBeCalledWith('comment', `> ${props.data.description} \n\n`); }); }); diff --git a/x-pack/plugins/cases/public/components/user_action_tree/index.tsx b/x-pack/plugins/cases/public/components/user_action_tree/index.tsx index 7ea415324194c3..92640a34548e8b 100644 --- a/x-pack/plugins/cases/public/components/user_action_tree/index.tsx +++ b/x-pack/plugins/cases/public/components/user_action_tree/index.tsx @@ -226,10 +226,8 @@ export const UserActionTree = React.memo( const handleManageQuote = useCallback( (quote: string) => { - const addCarrots = quote.replace(new RegExp('\r?\n', 'g'), ' \n> '); - if (commentRefs.current[NEW_ID]) { - commentRefs.current[NEW_ID].addQuote(`> ${addCarrots} \n`); + commentRefs.current[NEW_ID].addQuote(quote); } handleOutlineComment('add-comment'); From 59815a06813a10a1fddbb8a762cdf651ad962c4b Mon Sep 17 00:00:00 2001 From: Greg Thompson Date: Mon, 25 Oct 2021 11:54:37 -0500 Subject: [PATCH 32/66] Upgrade EUI to v40.0.0 (#115639) * eui to v40.0.0 * tokenKeyword -> tokenTag * mobileOptions type * snapshot updates * Revert "tokenKeyword -> tokenTag" This reverts commit 0e5eae64e773ffa7e744de5da5e1c277423cd890. * token snapshot --- package.json | 2 +- .../collapsible_nav.test.tsx.snap | 315 +++++++++++++----- .../chrome/ui/header/collapsible_nav.test.tsx | 5 +- src/dev/license_checker/config.ts | 2 +- .../__snapshots__/agg.test.tsx.snap | 2 + .../value_axes_panel.test.tsx.snap | 4 + .../value_axis_options.test.tsx.snap | 2 + .../var_config.stories.storyshot | 29 +- .../curations/components/curations_table.tsx | 3 - .../components/tables/shared_columns.tsx | 3 - .../edit_layer_panel.test.tsx.snap | 2 + .../__snapshots__/ccr_shard.test.js.snap | 2 + ...screen_capture_panel_content.test.tsx.snap | 132 ++++++-- .../modal_all_errors.test.tsx.snap | 2 + .../__snapshots__/index.test.tsx.snap | 8 + .../__snapshots__/index.test.tsx.snap | 6 + .../__snapshots__/ping_headers.test.tsx.snap | 2 + yarn.lock | 8 +- 18 files changed, 391 insertions(+), 138 deletions(-) diff --git a/package.json b/package.json index 177b70efd4cc7a..d9dd4912481b9b 100644 --- a/package.json +++ b/package.json @@ -102,7 +102,7 @@ "@elastic/datemath": "link:bazel-bin/packages/elastic-datemath", "@elastic/elasticsearch": "npm:@elastic/elasticsearch-canary@^8.0.0-canary.21", "@elastic/ems-client": "7.16.0", - "@elastic/eui": "39.1.1", + "@elastic/eui": "40.0.0", "@elastic/filesaver": "1.1.2", "@elastic/maki": "6.3.0", "@elastic/node-crypto": "1.2.1", diff --git a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap index 6987b779d5d456..571b564f903298 100644 --- a/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap +++ b/src/core/public/chrome/ui/header/__snapshots__/collapsible_nav.test.tsx.snap @@ -644,6 +644,11 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` > } + buttonElement="button" className="euiCollapsibleNavGroup euiCollapsibleNavGroup--light euiCollapsibleNavGroup--withHeading" data-test-subj="collapsibleNavGroup-recentlyViewed" + element="div" id="generated-id" initialIsOpen={true} isLoading={false} @@ -685,28 +692,13 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` + + +
} + buttonElement="button" className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading" data-test-subj="collapsibleNavGroup-kibana" + element="div" id="generated-id" initialIsOpen={true} isLoading={false} @@ -941,28 +977,13 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` + + +
} + buttonElement="button" className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading" data-test-subj="collapsibleNavGroup-observability" + element="div" id="generated-id" initialIsOpen={true} isLoading={false} @@ -1233,28 +1298,13 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` + + +
} + buttonElement="button" className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading" data-test-subj="collapsibleNavGroup-securitySolution" + element="div" id="generated-id" initialIsOpen={true} isLoading={false} @@ -1486,28 +1580,13 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` + + +
} + buttonElement="button" className="euiCollapsibleNavGroup euiCollapsibleNavGroup--withHeading" data-test-subj="collapsibleNavGroup-management" + element="div" id="generated-id" initialIsOpen={true} isLoading={false} @@ -1700,28 +1823,13 @@ exports[`CollapsibleNav renders links grouped by category 1`] = ` + + +
{ diff --git a/src/dev/license_checker/config.ts b/src/dev/license_checker/config.ts index efa54e74fdf2f9..305eeb9a6a3581 100644 --- a/src/dev/license_checker/config.ts +++ b/src/dev/license_checker/config.ts @@ -75,6 +75,6 @@ export const LICENSE_OVERRIDES = { 'jsts@1.6.2': ['Eclipse Distribution License - v 1.0'], // cf. https://github.com/bjornharrtell/jsts '@mapbox/jsonlint-lines-primitives@2.0.2': ['MIT'], // license in readme https://github.com/tmcw/jsonlint '@elastic/ems-client@7.16.0': ['Elastic License 2.0'], - '@elastic/eui@39.1.1': ['SSPL-1.0 OR Elastic License 2.0'], + '@elastic/eui@40.0.0': ['SSPL-1.0 OR Elastic License 2.0'], 'language-subtag-registry@0.3.21': ['CC-BY-4.0'], // retired ODC‑By license https://github.com/mattcg/language-subtag-registry }; diff --git a/src/plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap b/src/plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap index bc6d28bd5c1c4d..b25444d16c46a2 100644 --- a/src/plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap +++ b/src/plugins/vis_default_editor/public/components/__snapshots__/agg.test.tsx.snap @@ -12,8 +12,10 @@ exports[`DefaultEditorAgg component should init with the default set of props 1` } buttonContentClassName="visEditorSidebar__aggGroupAccordionButtonContent eui-textTruncate" + buttonElement="button" className="visEditorSidebar__section visEditorSidebar__collapsible visEditorSidebar__collapsible--marginBottom" data-test-subj="visEditorAggAccordion1" + element="div" extraAction={
} buttonContentClassName="visEditorSidebar__aggGroupAccordionButtonContent eui-textTruncate" + buttonElement="button" className="visEditorSidebar__section visEditorSidebar__collapsible" data-test-subj="toggleYAxisOptions-ValueAxis-1" + element="div" extraAction={ } buttonContentClassName="visEditorSidebar__aggGroupAccordionButtonContent eui-textTruncate" + buttonElement="button" className="visEditorSidebar__section visEditorSidebar__collapsible" data-test-subj="toggleYAxisOptions-ValueAxis-2" + element="div" extraAction={ + + + + + + +
} + buttonElement="button" + element="div" id="responseHeaderAccord" initialIsOpen={false} isLoading={false} diff --git a/yarn.lock b/yarn.lock index 669f8321fb4fcc..a36d8e9373685d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2412,10 +2412,10 @@ resolved "https://registry.yarnpkg.com/@elastic/eslint-plugin-eui/-/eslint-plugin-eui-0.0.2.tgz#56b9ef03984a05cc213772ae3713ea8ef47b0314" integrity sha512-IoxURM5zraoQ7C8f+mJb9HYSENiZGgRVcG4tLQxE61yHNNRDXtGDWTZh8N1KIHcsqN1CEPETjuzBXkJYF/fDiQ== -"@elastic/eui@39.1.1": - version "39.1.1" - resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-39.1.1.tgz#52e59f1dd6448b2e80047259ca60c6c87e9873f0" - integrity sha512-zYCNitpp6Ds7U6eaa9QkJqc20ZMo2wjpZokNtd1WalFV22vdfiVizFg7DMtDjJrCDLmoXcLOOCMasKlmmJ1cRg== +"@elastic/eui@40.0.0": + version "40.0.0" + resolved "https://registry.yarnpkg.com/@elastic/eui/-/eui-40.0.0.tgz#9556a87fa5eb7d9061e85f71ea9d3e6a9022dc3e" + integrity sha512-Zsz8eczEjthMgU00YhnsNmkKA8j4hxQpWNnrgecMgpcFEIj+Nn5WBofL/TJux/latS/mB4WWmrq4FTiSIyv/+Q== dependencies: "@types/chroma-js" "^2.0.0" "@types/lodash" "^4.14.160" From 62e203818fc1e2489bf03841ad470ff3e526ad7e Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Mon, 25 Oct 2021 20:13:47 +0300 Subject: [PATCH 33/66] [Connectors][ServiceNow] Rename isLegacy configuration property (#115028) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../servicenow/api_sir.test.ts | 16 ++++----- .../servicenow/api_sir.ts | 14 ++++---- .../builtin_action_types/servicenow/schema.ts | 4 +-- .../servicenow/service.ts | 29 +++++++-------- .../saved_objects/actions_migrations.test.ts | 10 +++--- .../saved_objects/actions_migrations.ts | 6 ++-- .../configure_cases/connectors.test.tsx | 4 +-- .../components/configure_cases/connectors.tsx | 4 +-- .../connectors_dropdown.test.tsx | 8 ++--- .../configure_cases/connectors_dropdown.tsx | 6 ++-- .../connectors/deprecated_callout.test.tsx | 4 +-- .../connectors/deprecated_callout.tsx | 14 ++++---- .../servicenow_itsm_case_fields.test.tsx | 12 +++---- .../servicenow_sir_case_fields.test.tsx | 12 +++---- .../connectors/servicenow/validator.test.ts | 8 ++--- .../connectors/servicenow/validator.ts | 6 ++-- .../plugins/cases/public/components/utils.ts | 15 ++++++-- .../cases/public/containers/configure/mock.ts | 4 +-- .../servicenow/helpers.ts | 13 +++++-- .../servicenow/servicenow.test.tsx | 6 ++-- .../servicenow/servicenow.tsx | 2 +- .../servicenow/servicenow_connectors.test.tsx | 10 +++--- .../servicenow/servicenow_connectors.tsx | 35 ++++++++++--------- .../servicenow/servicenow_itsm_params.tsx | 8 ++--- .../servicenow/servicenow_sir_params.tsx | 8 ++--- .../builtin_action_types/servicenow/types.ts | 2 +- .../servicenow/update_connector.test.tsx | 2 +- .../servicenow/use_get_app_info.test.tsx | 2 +- .../components/actions_connectors_list.tsx | 6 ++-- .../builtin_action_types/servicenow_itsm.ts | 20 +++++------ .../builtin_action_types/servicenow_sir.ts | 20 +++++------ .../case_api_integration/common/lib/utils.ts | 4 +-- .../tests/trial/configure/get_connectors.ts | 4 +-- .../tests/trial/configure/get_connectors.ts | 4 +-- 34 files changed, 168 insertions(+), 154 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.test.ts index 358af7cd2e9ef7..e5a161611fcb13 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.test.ts @@ -132,7 +132,7 @@ describe('api_sir', () => { }); describe('prepareParams', () => { - test('it prepares the params correctly when the connector is legacy', async () => { + test('it prepares the params correctly when the connector uses the old API', async () => { expect(prepareParams(true, sirParams)).toEqual({ ...sirParams, incident: { @@ -145,7 +145,7 @@ describe('api_sir', () => { }); }); - test('it prepares the params correctly when the connector is not legacy', async () => { + test('it prepares the params correctly when the connector does not uses the old API', async () => { expect(prepareParams(false, sirParams)).toEqual({ ...sirParams, incident: { @@ -158,7 +158,7 @@ describe('api_sir', () => { }); }); - test('it prepares the params correctly when the connector is legacy and the observables are undefined', async () => { + test('it prepares the params correctly when the connector uses the old API and the observables are undefined', async () => { const { dest_ip: destIp, source_ip: sourceIp, @@ -192,7 +192,7 @@ describe('api_sir', () => { const res = await apiSIR.pushToService({ externalService, params, - config: { isLegacy: false }, + config: { usesTableApi: false }, secrets: {}, logger: mockedLogger, commentFieldKey: 'work_notes', @@ -221,7 +221,7 @@ describe('api_sir', () => { await apiSIR.pushToService({ externalService, params, - config: { isLegacy: false }, + config: { usesTableApi: false }, secrets: {}, logger: mockedLogger, commentFieldKey: 'work_notes', @@ -244,12 +244,12 @@ describe('api_sir', () => { ); }); - test('it does not call bulkAddObservableToIncident if it a legacy connector', async () => { + test('it does not call bulkAddObservableToIncident if the connector uses the old API', async () => { const params = { ...sirParams, incident: { ...sirParams.incident, externalId: null } }; await apiSIR.pushToService({ externalService, params, - config: { isLegacy: true }, + config: { usesTableApi: true }, secrets: {}, logger: mockedLogger, commentFieldKey: 'work_notes', @@ -274,7 +274,7 @@ describe('api_sir', () => { await apiSIR.pushToService({ externalService, params, - config: { isLegacy: false }, + config: { usesTableApi: false }, secrets: {}, logger: mockedLogger, commentFieldKey: 'work_notes', diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.ts index 326bb79a0e708c..4e74d79c6f4a02 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api_sir.ts @@ -59,13 +59,13 @@ const observablesToString = (obs: string | string[] | null | undefined): string }; export const prepareParams = ( - isLegacy: boolean, + usesTableApi: boolean, params: PushToServiceApiParamsSIR ): PushToServiceApiParamsSIR => { - if (isLegacy) { + if (usesTableApi) { /** * The schema has change to accept an array of observables - * or a string. In the case of a legacy connector we need to + * or a string. In the case of connector that uses the old API we need to * convert the observables to a string */ return { @@ -81,8 +81,8 @@ export const prepareParams = ( } /** - * For non legacy connectors the observables - * will be added in a different call. + * For connectors that do not use the old API + * the observables will be added in a different call. * They need to be set to null when sending the fields * to ServiceNow */ @@ -108,7 +108,7 @@ const pushToServiceHandler = async ({ }: PushToServiceApiHandlerArgs): Promise => { const res = await api.pushToService({ externalService, - params: prepareParams(!!config.isLegacy, params as PushToServiceApiParamsSIR), + params: prepareParams(!!config.usesTableApi, params as PushToServiceApiParamsSIR), config, secrets, commentFieldKey, @@ -130,7 +130,7 @@ const pushToServiceHandler = async ({ * through the pushToService call. */ - if (!config.isLegacy) { + if (!config.usesTableApi) { const sirExternalService = externalService as ExternalServiceSIR; const obsWithType: Array<[string[], ObservableTypes]> = [ diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts index af8d1b9f38b17d..e41eea24834c7b 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts @@ -14,7 +14,7 @@ export const ExternalIncidentServiceConfigurationBase = { export const ExternalIncidentServiceConfiguration = { ...ExternalIncidentServiceConfigurationBase, - isLegacy: schema.boolean({ defaultValue: true }), + usesTableApi: schema.boolean({ defaultValue: true }), }; export const ExternalIncidentServiceConfigurationBaseSchema = schema.object( @@ -49,7 +49,7 @@ const CommonAttributes = { externalId: schema.nullable(schema.string()), category: schema.nullable(schema.string()), subcategory: schema.nullable(schema.string()), - correlation_id: schema.nullable(schema.string()), + correlation_id: schema.nullable(schema.string({ defaultValue: DEFAULT_ALERTS_GROUPING_KEY })), correlation_display: schema.nullable(schema.string()), }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts index cb030c7bb69336..c90a7222ba10be 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts @@ -35,7 +35,8 @@ export const createExternalService: ServiceFactory = ( configurationUtilities: ActionsConfigurationUtilities, { table, importSetTable, useImportAPI, appScope }: SNProductsConfigValue ): ExternalService => { - const { apiUrl: url, isLegacy } = config as ServiceNowPublicConfigurationType; + const { apiUrl: url, usesTableApi: usesTableApiConfigValue } = + config as ServiceNowPublicConfigurationType; const { username, password } = secrets as ServiceNowSecretConfigurationType; if (!url || !username || !password) { @@ -57,11 +58,11 @@ export const createExternalService: ServiceFactory = ( auth: { username, password }, }); - const useOldApi = !useImportAPI || isLegacy; + const useTableApi = !useImportAPI || usesTableApiConfigValue; - const getCreateIncidentUrl = () => (useOldApi ? tableApiIncidentUrl : importSetTableUrl); + const getCreateIncidentUrl = () => (useTableApi ? tableApiIncidentUrl : importSetTableUrl); const getUpdateIncidentUrl = (incidentId: string) => - useOldApi ? `${tableApiIncidentUrl}/${incidentId}` : importSetTableUrl; + useTableApi ? `${tableApiIncidentUrl}/${incidentId}` : importSetTableUrl; const getIncidentViewURL = (id: string) => { // Based on: https://docs.servicenow.com/bundle/orlando-platform-user-interface/page/use/navigation/reference/r_NavigatingByURLExamples.html @@ -105,7 +106,7 @@ export const createExternalService: ServiceFactory = ( /** * Gets the Elastic SN Application information including the current version. - * It should not be used on legacy connectors. + * It should not be used on connectors that use the old API. */ const getApplicationInformation = async (): Promise => { try { @@ -129,7 +130,7 @@ export const createExternalService: ServiceFactory = ( logger.debug(`Create incident: Application scope: ${scope}: Application version${version}`); const checkIfApplicationIsInstalled = async () => { - if (!useOldApi) { + if (!useTableApi) { const { version, scope } = await getApplicationInformation(); logApplicationInfo(scope, version); } @@ -180,17 +181,17 @@ export const createExternalService: ServiceFactory = ( url: getCreateIncidentUrl(), logger, method: 'post', - data: prepareIncident(useOldApi, incident), + data: prepareIncident(useTableApi, incident), configurationUtilities, }); checkInstance(res); - if (!useOldApi) { + if (!useTableApi) { throwIfImportSetApiResponseIsAnError(res.data); } - const incidentId = useOldApi ? res.data.result.sys_id : res.data.result[0].sys_id; + const incidentId = useTableApi ? res.data.result.sys_id : res.data.result[0].sys_id; const insertedIncident = await getIncident(incidentId); return { @@ -212,23 +213,23 @@ export const createExternalService: ServiceFactory = ( axios: axiosInstance, url: getUpdateIncidentUrl(incidentId), // Import Set API supports only POST. - method: useOldApi ? 'patch' : 'post', + method: useTableApi ? 'patch' : 'post', logger, data: { - ...prepareIncident(useOldApi, incident), + ...prepareIncident(useTableApi, incident), // elastic_incident_id is used to update the incident when using the Import Set API. - ...(useOldApi ? {} : { elastic_incident_id: incidentId }), + ...(useTableApi ? {} : { elastic_incident_id: incidentId }), }, configurationUtilities, }); checkInstance(res); - if (!useOldApi) { + if (!useTableApi) { throwIfImportSetApiResponseIsAnError(res.data); } - const id = useOldApi ? res.data.result.sys_id : res.data.result[0].sys_id; + const id = useTableApi ? res.data.result.sys_id : res.data.result[0].sys_id; const updatedIncident = await getIncident(id); return { diff --git a/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts b/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts index 9f8e62c77e3a73..6c61d9849c72c1 100644 --- a/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts +++ b/x-pack/plugins/actions/server/saved_objects/actions_migrations.test.ts @@ -166,7 +166,7 @@ describe('successful migrations', () => { expect(migratedAction).toEqual(action); }); - test('set isLegacy config property for .servicenow', () => { + test('set usesTableApi config property for .servicenow', () => { const migration716 = getActionsMigrations(encryptedSavedObjectsSetup)['7.16.0']; const action = getMockDataForServiceNow(); const migratedAction = migration716(action, context); @@ -177,13 +177,13 @@ describe('successful migrations', () => { ...action.attributes, config: { apiUrl: 'https://example.com', - isLegacy: true, + usesTableApi: true, }, }, }); }); - test('set isLegacy config property for .servicenow-sir', () => { + test('set usesTableApi config property for .servicenow-sir', () => { const migration716 = getActionsMigrations(encryptedSavedObjectsSetup)['7.16.0']; const action = getMockDataForServiceNow({ actionTypeId: '.servicenow-sir' }); const migratedAction = migration716(action, context); @@ -194,13 +194,13 @@ describe('successful migrations', () => { ...action.attributes, config: { apiUrl: 'https://example.com', - isLegacy: true, + usesTableApi: true, }, }, }); }); - test('it does not set isLegacy config for other connectors', () => { + test('it does not set usesTableApi config for other connectors', () => { const migration716 = getActionsMigrations(encryptedSavedObjectsSetup)['7.16.0']; const action = getMockData(); const migratedAction = migration716(action, context); diff --git a/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts b/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts index 688839eb898581..2e5b1b5d916fe5 100644 --- a/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts +++ b/x-pack/plugins/actions/server/saved_objects/actions_migrations.ts @@ -68,7 +68,7 @@ export function getActionsMigrations( doc.attributes.actionTypeId === '.servicenow' || doc.attributes.actionTypeId === '.servicenow-sir' || doc.attributes.actionTypeId === '.email', - pipeMigrations(markOldServiceNowITSMConnectorAsLegacy, setServiceConfigIfNotSet) + pipeMigrations(addUsesTableApiToServiceNowConnectors, setServiceConfigIfNotSet) ); const migrationActions800 = createEsoMigration( @@ -197,7 +197,7 @@ const addIsMissingSecretsField = ( }; }; -const markOldServiceNowITSMConnectorAsLegacy = ( +const addUsesTableApiToServiceNowConnectors = ( doc: SavedObjectUnsanitizedDoc ): SavedObjectUnsanitizedDoc => { if ( @@ -213,7 +213,7 @@ const markOldServiceNowITSMConnectorAsLegacy = ( ...doc.attributes, config: { ...doc.attributes.config, - isLegacy: true, + usesTableApi: true, }, }, }; diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx index 4e0f1689bd4d1d..9bbddfae2f9bd7 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors.test.tsx @@ -123,11 +123,11 @@ describe('Connectors', () => { ).toBe('Update My Connector'); }); - test('it shows the deprecated callout when the connector is legacy', async () => { + test('it shows the deprecated callout when the connector is deprecated', async () => { render( , { // wrapper: TestProviders produces a TS error diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors.tsx index 1b575e3ba93340..b7bf7c322f76e7 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors.tsx @@ -23,7 +23,7 @@ import { ActionConnector, CaseConnectorMapping } from '../../containers/configur import { Mapping } from './mapping'; import { ActionTypeConnector, ConnectorTypes } from '../../../common'; import { DeprecatedCallout } from '../connectors/deprecated_callout'; -import { isLegacyConnector } from '../utils'; +import { isDeprecatedConnector } from '../utils'; const EuiFormRowExtended = styled(EuiFormRow)` .euiFormRow__labelWrapper { @@ -111,7 +111,7 @@ const ConnectorsComponent: React.FC = ({ appendAddConnectorButton={true} /> - {selectedConnector.type !== ConnectorTypes.none && isLegacyConnector(connector) && ( + {selectedConnector.type !== ConnectorTypes.none && isDeprecatedConnector(connector) && ( diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx index 6f05f9f940d25c..03ed3d65126387 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.test.tsx @@ -171,7 +171,7 @@ describe('ConnectorsDropdown', () => { "value": "servicenow-sir", }, Object { - "data-test-subj": "dropdown-connector-servicenow-legacy", + "data-test-subj": "dropdown-connector-servicenow-uses-table-api", "inputDisplay": { /> , - "value": "servicenow-legacy", + "value": "servicenow-uses-table-api", }, ] `); @@ -288,8 +288,8 @@ describe('ConnectorsDropdown', () => { ).not.toThrowError(); }); - test('it shows the deprecated tooltip when the connector is legacy', () => { - render(, { + test('it shows the deprecated tooltip when the connector is deprecated', () => { + render(, { wrapper: ({ children }) => {children}, }); diff --git a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx index c5fe9c7470745e..c7ce3c5b3c4b67 100644 --- a/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx +++ b/x-pack/plugins/cases/public/components/configure_cases/connectors_dropdown.tsx @@ -13,7 +13,7 @@ import { ConnectorTypes } from '../../../common'; import { ActionConnector } from '../../containers/configure/types'; import * as i18n from './translations'; import { useKibana } from '../../common/lib/kibana'; -import { getConnectorIcon, isLegacyConnector } from '../utils'; +import { getConnectorIcon, isDeprecatedConnector } from '../utils'; import { euiStyled } from '../../../../../../src/plugins/kibana_react/common'; export interface Props { @@ -95,10 +95,10 @@ const ConnectorsDropdownComponent: React.FC = ({ {connector.name} - {isLegacyConnector(connector) && ` (${i18n.DEPRECATED_TOOLTIP_TEXT})`} + {isDeprecatedConnector(connector) && ` (${i18n.DEPRECATED_TOOLTIP_TEXT})`} - {isLegacyConnector(connector) && ( + {isDeprecatedConnector(connector) && ( { render(); expect(screen.getByText('This connector type is deprecated')).toBeInTheDocument(); expect(screen.getByText('Update this connector, or create a new one.')).toBeInTheDocument(); - expect(screen.getByTestId('legacy-connector-warning-callout')).toHaveClass( + expect(screen.getByTestId('deprecated-connector-warning-callout')).toHaveClass( 'euiCallOut euiCallOut--warning' ); }); test('it renders a danger flyout correctly', () => { render(); - expect(screen.getByTestId('legacy-connector-warning-callout')).toHaveClass( + expect(screen.getByTestId('deprecated-connector-warning-callout')).toHaveClass( 'euiCallOut euiCallOut--danger' ); }); diff --git a/x-pack/plugins/cases/public/components/connectors/deprecated_callout.tsx b/x-pack/plugins/cases/public/components/connectors/deprecated_callout.tsx index 9337f2843506b2..195b2deb84d6e8 100644 --- a/x-pack/plugins/cases/public/components/connectors/deprecated_callout.tsx +++ b/x-pack/plugins/cases/public/components/connectors/deprecated_callout.tsx @@ -9,15 +9,15 @@ import React from 'react'; import { EuiCallOut, EuiCallOutProps } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -const LEGACY_CONNECTOR_WARNING_TITLE = i18n.translate( - 'xpack.cases.connectors.serviceNow.legacyConnectorWarningTitle', +const DEPRECATED_CONNECTOR_WARNING_TITLE = i18n.translate( + 'xpack.cases.connectors.serviceNow.deprecatedConnectorWarningTitle', { defaultMessage: 'This connector type is deprecated', } ); -const LEGACY_CONNECTOR_WARNING_DESC = i18n.translate( - 'xpack.cases.connectors.serviceNow.legacyConnectorWarningDesc', +const DEPRECATED_CONNECTOR_WARNING_DESC = i18n.translate( + 'xpack.cases.connectors.serviceNow.deprecatedConnectorWarningDesc', { defaultMessage: 'Update this connector, or create a new one.', } @@ -29,12 +29,12 @@ interface Props { const DeprecatedCalloutComponent: React.FC = ({ type = 'warning' }) => ( - {LEGACY_CONNECTOR_WARNING_DESC} + {DEPRECATED_CONNECTOR_WARNING_DESC} ); diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx index 008340b6b7e978..324dcef8ba3977 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_itsm_case_fields.test.tsx @@ -127,15 +127,15 @@ describe('ServiceNowITSM Fields', () => { ); }); - test('it shows the deprecated callout when the connector is legacy', async () => { - const legacyConnector = { ...connector, config: { isLegacy: true } }; - render(); - expect(screen.getByTestId('legacy-connector-warning-callout')).toBeInTheDocument(); + test('it shows the deprecated callout when the connector uses the table API', async () => { + const tableApiConnector = { ...connector, config: { usesTableApi: true } }; + render(); + expect(screen.getByTestId('deprecated-connector-warning-callout')).toBeInTheDocument(); }); - test('it does not show the deprecated callout when the connector is not legacy', async () => { + test('it does not show the deprecated callout when the connector does not uses the table API', async () => { render(); - expect(screen.queryByTestId('legacy-connector-warning-callout')).not.toBeInTheDocument(); + expect(screen.queryByTestId('deprecated-connector-warning-callout')).not.toBeInTheDocument(); }); describe('onChange calls', () => { diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx index aac78b8266fb53..cd8f5f4abf7b55 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/servicenow_sir_case_fields.test.tsx @@ -161,15 +161,15 @@ describe('ServiceNowSIR Fields', () => { ]); }); - test('it shows the deprecated callout when the connector is legacy', async () => { - const legacyConnector = { ...connector, config: { isLegacy: true } }; - render(); - expect(screen.getByTestId('legacy-connector-warning-callout')).toBeInTheDocument(); + test('it shows the deprecated callout when the connector uses the table API', async () => { + const tableApiConnector = { ...connector, config: { usesTableApi: true } }; + render(); + expect(screen.getByTestId('deprecated-connector-warning-callout')).toBeInTheDocument(); }); - test('it does not show the deprecated callout when the connector is not legacy', async () => { + test('it does not show the deprecated callout when the connector does not uses the table API', async () => { render(); - expect(screen.queryByTestId('legacy-connector-warning-callout')).not.toBeInTheDocument(); + expect(screen.queryByTestId('deprecated-connector-warning-callout')).not.toBeInTheDocument(); }); describe('onChange calls', () => { diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts index c098d803276bc6..aa643191ac62ee 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.test.ts @@ -10,24 +10,24 @@ import { connectorValidator } from './validator'; describe('ServiceNow validator', () => { describe('connectorValidator', () => { - test('it returns an error message if the connector is legacy', () => { + test('it returns an error message if the connector uses the table API', () => { const invalidConnector = { ...connector, config: { ...connector.config, - isLegacy: true, + usesTableApi: true, }, }; expect(connectorValidator(invalidConnector)).toEqual({ message: 'Deprecated connector' }); }); - test('it does not returns an error message if the connector is not legacy', () => { + test('it does not returns an error message if the connector does not uses the table API', () => { const invalidConnector = { ...connector, config: { ...connector.config, - isLegacy: false, + usesTableApi: false, }, }; diff --git a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts index 3f67f255493434..7d56163c483508 100644 --- a/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts +++ b/x-pack/plugins/cases/public/components/connectors/servicenow/validator.ts @@ -9,16 +9,16 @@ import { ValidationConfig } from '../../../common/shared_imports'; import { CaseActionConnector } from '../../types'; /** - * The user can not use a legacy connector + * The user can not create cases with connectors that use the table API */ export const connectorValidator = ( connector: CaseActionConnector ): ReturnType => { const { - config: { isLegacy }, + config: { usesTableApi }, } = connector; - if (isLegacy) { + if (usesTableApi) { return { message: 'Deprecated connector', }; diff --git a/x-pack/plugins/cases/public/components/utils.ts b/x-pack/plugins/cases/public/components/utils.ts index ac5f4dbdd298e9..74137789958a46 100644 --- a/x-pack/plugins/cases/public/components/utils.ts +++ b/x-pack/plugins/cases/public/components/utils.ts @@ -78,7 +78,7 @@ export const getConnectorIcon = ( }; // TODO: Remove when the applications are certified -export const isLegacyConnector = (connector?: CaseActionConnector) => { +export const isDeprecatedConnector = (connector?: CaseActionConnector): boolean => { if (connector == null) { return true; } @@ -91,5 +91,16 @@ export const isLegacyConnector = (connector?: CaseActionConnector) => { return true; } - return connector.config.isLegacy; + /** + * Connector's prior to the Elastic ServiceNow application + * use the Table API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_TableAPI) + * Connectors after the Elastic ServiceNow application use the + * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) + * A ServiceNow connector is considered deprecated if it uses the Table API. + * + * All other connectors do not have the usesTableApi config property + * so the function will always return false for them. + */ + + return !!connector.config.usesTableApi; }; diff --git a/x-pack/plugins/cases/public/containers/configure/mock.ts b/x-pack/plugins/cases/public/containers/configure/mock.ts index d1ae7f310a7195..a5483e524e92dc 100644 --- a/x-pack/plugins/cases/public/containers/configure/mock.ts +++ b/x-pack/plugins/cases/public/containers/configure/mock.ts @@ -72,12 +72,12 @@ export const connectorsMock: ActionConnector[] = [ isPreconfigured: false, }, { - id: 'servicenow-legacy', + id: 'servicenow-uses-table-api', actionTypeId: '.servicenow', name: 'My Connector', config: { apiUrl: 'https://instance1.service-now.com', - isLegacy: true, + usesTableApi: true, }, isPreconfigured: false, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts index e6acb2e0976a8a..755923acc25cb4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts @@ -28,7 +28,7 @@ export const isFieldInvalid = ( ): boolean => error !== undefined && error.length > 0 && field != null; // TODO: Remove when the applications are certified -export const isLegacyConnector = (connector: ServiceNowActionConnector) => { +export const isDeprecatedConnector = (connector: ServiceNowActionConnector): boolean => { if (connector == null) { return true; } @@ -41,5 +41,14 @@ export const isLegacyConnector = (connector: ServiceNowActionConnector) => { return true; } - return connector.config.isLegacy; + /** + * Connectors after the Elastic ServiceNow application use the + * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) + * A ServiceNow connector is considered deprecated if it uses the Table API. + * + * All other connectors do not have the usesTableApi config property + * so the function will always return false for them. + */ + + return !!connector.config.usesTableApi; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx index eb3e1c01887c9c..3f22a51b5bd53e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx @@ -52,7 +52,7 @@ describe('servicenow connector validation', () => { isPreconfigured: false, config: { apiUrl: 'https://dev94428.service-now.com/', - isLegacy: false, + usesTableApi: false, }, } as ServiceNowActionConnector; @@ -60,7 +60,7 @@ describe('servicenow connector validation', () => { config: { errors: { apiUrl: [], - isLegacy: [], + usesTableApi: [], }, }, secrets: { @@ -88,7 +88,7 @@ describe('servicenow connector validation', () => { config: { errors: { apiUrl: ['URL is required.'], - isLegacy: [], + usesTableApi: [], }, }, secrets: { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index 6b6d536ff303b1..7267e11ae73272 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -28,7 +28,7 @@ const validateConnector = async ( const translations = await import('./translations'); const configErrors = { apiUrl: new Array(), - isLegacy: new Array(), + usesTableApi: new Array(), }; const secretsErrors = { username: new Array(), diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx index f491376e5078c2..03acb673bf5a46 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx @@ -36,7 +36,7 @@ describe('ServiceNowActionConnectorFields renders', () => { name: 'SN', config: { apiUrl: 'https://test/', - isLegacy: true, + usesTableApi: true, }, } as ServiceNowActionConnector; @@ -44,7 +44,7 @@ describe('ServiceNowActionConnectorFields renders', () => { ...usesTableApiConnector, config: { ...usesTableApiConnector.config, - isLegacy: false, + usesTableApi: false, }, } as ServiceNowActionConnector; @@ -350,7 +350,7 @@ describe('ServiceNowActionConnectorFields renders', () => { id: usesTableApiConnector.id, connector: { name: usesTableApiConnector.name, - config: { ...usesTableApiConnector.config, isLegacy: false }, + config: { ...usesTableApiConnector.config, usesTableApi: false }, secrets: usesTableApiConnector.secrets, }, }) @@ -415,7 +415,7 @@ describe('ServiceNowActionConnectorFields renders', () => { ).toBeTruthy(); }); - test('should set the isLegacy to false when creating a connector', async () => { + test('should set the usesTableApi to false when creating a connector', async () => { const newConnector = { ...usesTableApiConnector, config: {}, secrets: {} }; const editActionConfig = jest.fn(); @@ -432,7 +432,7 @@ describe('ServiceNowActionConnectorFields renders', () => { /> ); - expect(editActionConfig).toHaveBeenCalledWith('isLegacy', false); + expect(editActionConfig).toHaveBeenCalledWith('usesTableApi', false); }); test('it should set the legacy attribute if it is not undefined', async () => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index a0b4bdca47ff52..db3c32755f0ed1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -15,7 +15,7 @@ import { useKibana } from '../../../../common/lib/kibana'; import { DeprecatedCallout } from './deprecated_callout'; import { useGetAppInfo } from './use_get_app_info'; import { ApplicationRequiredCallout } from './application_required_callout'; -import { isRESTApiError, isLegacyConnector } from './helpers'; +import { isRESTApiError, isDeprecatedConnector } from './helpers'; import { InstallationCallout } from './installation_callout'; import { UpdateConnector } from './update_connector'; import { updateActionConnector } from '../../../lib/action_connector_api'; @@ -36,9 +36,9 @@ const ServiceNowConnectorFields: React.FC(false); + const [showApplicationRequiredCallout, setShowApplicationRequiredCallout] = + useState(false); const [applicationInfoErrorMsg, setApplicationInfoErrorMsg] = useState(null); const getApplicationInfo = useCallback(async () => { - setApplicationRequired(false); + setShowApplicationRequiredCallout(false); setApplicationInfoErrorMsg(null); try { @@ -61,7 +62,7 @@ const ServiceNowConnectorFields: React.FC { - if (!isOldConnector) { + if (requiresNewApplication) { await getApplicationInfo(); } - }, [getApplicationInfo, isOldConnector]); + }, [getApplicationInfo, requiresNewApplication]); useEffect( () => setCallbacks({ beforeActionConnectorSave }), @@ -90,13 +91,13 @@ const ServiceNowConnectorFields: React.FC { - if (isLegacy == null) { - editActionConfig('isLegacy', false); + if (usesTableApi == null) { + editActionConfig('usesTableApi', false); } }); @@ -150,8 +151,8 @@ const ServiceNowConnectorFields: React.FC )} - {!isOldConnector && } - {isOldConnector && } + {requiresNewApplication && } + {!requiresNewApplication && } - {applicationRequired && !isOldConnector && ( + {showApplicationRequiredCallout && requiresNewApplication && ( )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx index 09b04f0fa3c485..dcfdfe3af0e0e9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_itsm_params.tsx @@ -23,7 +23,7 @@ import { ServiceNowITSMActionParams, Choice, Fields, ServiceNowActionConnector } import { TextAreaWithMessageVariables } from '../../text_area_with_message_variables'; import { TextFieldWithMessageVariables } from '../../text_field_with_message_variables'; import { useGetChoices } from './use_get_choices'; -import { choicesToEuiOptions, DEFAULT_CORRELATION_ID, isLegacyConnector } from './helpers'; +import { choicesToEuiOptions, DEFAULT_CORRELATION_ID, isDeprecatedConnector } from './helpers'; import * as i18n from './translations'; @@ -46,10 +46,6 @@ const ServiceNowParamsFields: React.FunctionComponent< notifications: { toasts }, } = useKibana().services; - const isDeprecatedConnector = isLegacyConnector( - actionConnector as unknown as ServiceNowActionConnector - ); - const actionConnectorRef = useRef(actionConnector?.id ?? ''); const { incident, comments } = useMemo( () => @@ -244,7 +240,7 @@ const ServiceNowParamsFields: React.FunctionComponent< - {!isDeprecatedConnector && ( + {!isDeprecatedConnector(actionConnector as unknown as ServiceNowActionConnector) && ( <> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx index 42758250408d9b..a264ed5421c2ea 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_sir_params.tsx @@ -25,7 +25,7 @@ import { TextFieldWithMessageVariables } from '../../text_field_with_message_var import * as i18n from './translations'; import { useGetChoices } from './use_get_choices'; import { ServiceNowSIRActionParams, Fields, Choice, ServiceNowActionConnector } from './types'; -import { choicesToEuiOptions, isLegacyConnector, DEFAULT_CORRELATION_ID } from './helpers'; +import { choicesToEuiOptions, isDeprecatedConnector, DEFAULT_CORRELATION_ID } from './helpers'; const useGetChoicesFields = ['category', 'subcategory', 'priority']; const defaultFields: Fields = { @@ -43,10 +43,6 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< notifications: { toasts }, } = useKibana().services; - const isDeprecatedConnector = isLegacyConnector( - actionConnector as unknown as ServiceNowActionConnector - ); - const actionConnectorRef = useRef(actionConnector?.id ?? ''); const { incident, comments } = useMemo( () => @@ -229,7 +225,7 @@ const ServiceNowSIRParamsFields: React.FunctionComponent< - {!isDeprecatedConnector && ( + {!isDeprecatedConnector(actionConnector as unknown as ServiceNowActionConnector) && ( <> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index ecbb4f9de726b6..40bb47543a3c8e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -35,7 +35,7 @@ export interface ServiceNowITOMActionParams { export interface ServiceNowConfig { apiUrl: string; - isLegacy: boolean; + usesTableApi: boolean; } export interface ServiceNowSecrets { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.test.tsx index 2d95bfa85ceb99..ecb90051e78c2c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/update_connector.test.tsx @@ -22,7 +22,7 @@ const actionConnector: ServiceNowActionConnector = { name: 'servicenow', config: { apiUrl: 'https://test/', - isLegacy: true, + usesTableApi: true, }, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx index c6b70443ec8fbe..f842f6863676ae 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/use_get_app_info.test.tsx @@ -34,7 +34,7 @@ const actionConnector = { isPreconfigured: false, config: { apiUrl: 'https://test.service-now.com/', - isLegacy: false, + usesTableApi: false, }, } as ServiceNowActionConnector; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index 844f28f0225477..5de21470fc19ab 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -205,8 +205,8 @@ const ActionsConnectorsList: React.FunctionComponent = () => { const itemConfig = ( item as UserConfiguredActionConnector, Record> ).config; - const showLegacyTooltip = - itemConfig?.isLegacy && + const showDeprecatedTooltip = + itemConfig?.usesTableApi && // TODO: Remove when applications are certified ((ENABLE_NEW_SN_ITSM_CONNECTOR && item.actionTypeId === '.servicenow') || (ENABLE_NEW_SN_SIR_CONNECTOR && item.actionTypeId === '.servicenow-sir')); @@ -233,7 +233,7 @@ const ActionsConnectorsList: React.FunctionComponent = () => { position="right" /> ) : null} - {showLegacyTooltip && } + {showDeprecatedTooltip && } ); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts index 97c2a77a8f0740..1308959ebbacff 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_itsm.ts @@ -22,7 +22,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { const mockServiceNow = { config: { apiUrl: 'www.servicenowisinkibanaactions.com', - isLegacy: false, + usesTableApi: false, }, secrets: { password: 'elastic', @@ -91,7 +91,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', config: { apiUrl: serviceNowSimulatorURL, - isLegacy: false, + usesTableApi: false, }, secrets: mockServiceNow.secrets, }) @@ -105,7 +105,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, - isLegacy: false, + usesTableApi: false, }, }); @@ -121,12 +121,12 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, - isLegacy: false, + usesTableApi: false, }, }); }); - it('should set the isLegacy to true when not provided', async () => { + it('should set the usesTableApi to true when not provided', async () => { const { body: createdAction } = await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -144,7 +144,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { .get(`/api/actions/connector/${createdAction.id}`) .expect(200); - expect(fetchedAction.config.isLegacy).to.be(true); + expect(fetchedAction.config.usesTableApi).to.be(true); }); it('should respond with a 400 Bad Request when creating a servicenow action with no apiUrl', async () => { @@ -223,7 +223,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', config: { apiUrl: serviceNowSimulatorURL, - isLegacy: false, + usesTableApi: false, }, secrets: mockServiceNow.secrets, }); @@ -383,7 +383,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { }); describe('Execution', () => { - // New connectors + // Connectors that use the Import set API describe('Import set API', () => { it('should handle creating an incident without comments', async () => { const { body: result } = await supertest @@ -414,7 +414,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { }); }); - // Legacy connectors + // Connectors that use the Table API describe('Table API', () => { before(async () => { const { body } = await supertest @@ -425,7 +425,7 @@ export default function serviceNowITSMTest({ getService }: FtrProviderContext) { connector_type_id: '.servicenow', config: { apiUrl: serviceNowSimulatorURL, - isLegacy: true, + usesTableApi: true, }, secrets: mockServiceNow.secrets, }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts index 3a13e055e7aebb..c27634ecf6aca9 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow_sir.ts @@ -22,7 +22,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { const mockServiceNow = { config: { apiUrl: 'www.servicenowisinkibanaactions.com', - isLegacy: false, + usesTableApi: false, }, secrets: { password: 'elastic', @@ -95,7 +95,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_type_id: '.servicenow-sir', config: { apiUrl: serviceNowSimulatorURL, - isLegacy: false, + usesTableApi: false, }, secrets: mockServiceNow.secrets, }) @@ -109,7 +109,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, - isLegacy: false, + usesTableApi: false, }, }); @@ -125,12 +125,12 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { is_missing_secrets: false, config: { apiUrl: serviceNowSimulatorURL, - isLegacy: false, + usesTableApi: false, }, }); }); - it('should set the isLegacy to true when not provided', async () => { + it('should set the usesTableApi to true when not provided', async () => { const { body: createdAction } = await supertest .post('/api/actions/connector') .set('kbn-xsrf', 'foo') @@ -148,7 +148,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { .get(`/api/actions/connector/${createdAction.id}`) .expect(200); - expect(fetchedAction.config.isLegacy).to.be(true); + expect(fetchedAction.config.usesTableApi).to.be(true); }); it('should respond with a 400 Bad Request when creating a servicenow action with no apiUrl', async () => { @@ -227,7 +227,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_type_id: '.servicenow-sir', config: { apiUrl: serviceNowSimulatorURL, - isLegacy: false, + usesTableApi: false, }, secrets: mockServiceNow.secrets, }); @@ -387,7 +387,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { }); describe('Execution', () => { - // New connectors + // Connectors that use the Import set API describe('Import set API', () => { it('should handle creating an incident without comments', async () => { const { body: result } = await supertest @@ -418,7 +418,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { }); }); - // Legacy connectors + // Connectors that use the Table API describe('Table API', () => { before(async () => { const { body } = await supertest @@ -429,7 +429,7 @@ export default function serviceNowSIRTest({ getService }: FtrProviderContext) { connector_type_id: '.servicenow-sir', config: { apiUrl: serviceNowSimulatorURL, - isLegacy: true, + usesTableApi: true, }, secrets: mockServiceNow.secrets, }); diff --git a/x-pack/test/case_api_integration/common/lib/utils.ts b/x-pack/test/case_api_integration/common/lib/utils.ts index 0a875f9f1e8220..9d48aed32d55c1 100644 --- a/x-pack/test/case_api_integration/common/lib/utils.ts +++ b/x-pack/test/case_api_integration/common/lib/utils.ts @@ -329,7 +329,7 @@ export const getServiceNowConnector = () => ({ }, config: { apiUrl: 'http://some.non.existent.com', - isLegacy: false, + usesTableApi: false, }, }); @@ -386,7 +386,7 @@ export const getServiceNowSIRConnector = () => ({ }, config: { apiUrl: 'http://some.non.existent.com', - isLegacy: false, + usesTableApi: false, }, }); diff --git a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts index c3e737464f19bc..a4e69ab928325d 100644 --- a/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/case_api_integration/security_and_spaces/tests/trial/configure/get_connectors.ts @@ -109,7 +109,7 @@ export default ({ getService }: FtrProviderContext): void => { name: 'ServiceNow Connector', config: { apiUrl: 'http://some.non.existent.com', - isLegacy: false, + usesTableApi: false, }, isPreconfigured: false, isMissingSecrets: false, @@ -121,7 +121,7 @@ export default ({ getService }: FtrProviderContext): void => { name: 'ServiceNow Connector', config: { apiUrl: 'http://some.non.existent.com', - isLegacy: false, + usesTableApi: false, }, isPreconfigured: false, isMissingSecrets: false, diff --git a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_connectors.ts b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_connectors.ts index 7b6848d1f301ea..02b91c9f0b9186 100644 --- a/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_connectors.ts +++ b/x-pack/test/case_api_integration/spaces_only/tests/trial/configure/get_connectors.ts @@ -109,7 +109,7 @@ export default ({ getService }: FtrProviderContext): void => { name: 'ServiceNow Connector', config: { apiUrl: 'http://some.non.existent.com', - isLegacy: false, + usesTableApi: false, }, isPreconfigured: false, isMissingSecrets: false, @@ -121,7 +121,7 @@ export default ({ getService }: FtrProviderContext): void => { name: 'ServiceNow Connector', config: { apiUrl: 'http://some.non.existent.com', - isLegacy: false, + usesTableApi: false, }, isPreconfigured: false, isMissingSecrets: false, From 504896d51fd50c709686a398e24f1b2ae02dab98 Mon Sep 17 00:00:00 2001 From: Josh Dover <1813008+joshdover@users.noreply.github.com> Date: Mon, 25 Oct 2021 19:19:46 +0200 Subject: [PATCH 34/66] [Fleet] Fix showing deployment details callout on Cloud staging (#116123) --- .../integrations/components/header/deployment_details.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx index 48c8fa56fb91ba..79175d241c29ff 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/components/header/deployment_details.tsx @@ -32,7 +32,8 @@ export const DeploymentDetails = () => { !( cname.endsWith('elastic-cloud.com') || cname.endsWith('found.io') || - cname.endsWith('found.no') + cname.endsWith('found.no') || + cname.endsWith('foundit.no') ) ) { return null; From f152787a6802d585e5341613db0677f27dbdd927 Mon Sep 17 00:00:00 2001 From: Thomas Watson Date: Mon, 25 Oct 2021 20:12:05 +0200 Subject: [PATCH 35/66] Remove deprecated xpack.security.enabled config option (#111681) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- docs/settings/security-settings.asciidoc | 14 --------- .../resources/base/bin/kibana-docker | 1 - .../apis/custom_integration/integrations.ts | 2 +- test/common/services/security/test_user.ts | 11 ++++--- test/functional/config.js | 1 - x-pack/plugins/security/server/config.test.ts | 3 -- x-pack/plugins/security/server/config.ts | 1 - .../server/config_deprecations.test.ts | 30 ------------------- .../security/server/config_deprecations.ts | 24 --------------- .../alerting_api_integration/common/config.ts | 4 ++- .../case_api_integration/common/config.ts | 4 ++- .../lists_api_integration/common/config.ts | 4 ++- .../reporting_without_security.config.ts | 2 +- .../reporting_without_security.config.ts | 5 +--- x-pack/test/rule_registry/common/config.ts | 4 ++- .../common/config.ts | 4 ++- .../spaces_api_integration/common/config.ts | 4 ++- x-pack/test/timeline/common/config.ts | 4 ++- x-pack/test/ui_capabilities/common/config.ts | 4 ++- .../spaces_only/tests/catalogue.ts | 15 ++++++++-- .../spaces_only/tests/nav_links.ts | 15 ++++++++-- 21 files changed, 58 insertions(+), 98 deletions(-) diff --git a/docs/settings/security-settings.asciidoc b/docs/settings/security-settings.asciidoc index c291b65c3c35b4..7737745c7cfa85 100644 --- a/docs/settings/security-settings.asciidoc +++ b/docs/settings/security-settings.asciidoc @@ -12,20 +12,6 @@ You do not need to configure any additional settings to use the [[general-security-settings]] ==== General security settings -[cols="2*<"] -|=== -| `xpack.security.enabled` - | deprecated:[7.16.0,"In 8.0 and later, this setting will no longer be supported."] - By default, {kib} automatically detects whether to enable the - {security-features} based on the license and whether {es} {security-features} - are enabled. + - + - Do not set this to `false`; it disables the login form, user and role management - screens, and authorization using <>. To disable - {security-features} entirely, see - {ref}/security-settings.html[{es} security settings]. -|=== - [float] [[authentication-security-settings]] ==== Authentication security settings diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index 235a5fbe1a1a3c..3a38789fbcac65 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -343,7 +343,6 @@ kibana_vars=( xpack.security.authc.saml.realm xpack.security.authc.selector.enabled xpack.security.cookieName - xpack.security.enabled xpack.security.encryptionKey xpack.security.loginAssistanceMessage xpack.security.loginHelp diff --git a/test/api_integration/apis/custom_integration/integrations.ts b/test/api_integration/apis/custom_integration/integrations.ts index e4797b334a8662..0784a86e4b546c 100644 --- a/test/api_integration/apis/custom_integration/integrations.ts +++ b/test/api_integration/apis/custom_integration/integrations.ts @@ -22,7 +22,7 @@ export default function ({ getService }: FtrProviderContext) { expect(resp.body).to.be.an('array'); - expect(resp.body.length).to.be(12); + expect(resp.body.length).to.be(33); // Test for sample data card expect(resp.body.findIndex((c: { id: string }) => c.id === 'sample_data_all')).to.be.above( diff --git a/test/common/services/security/test_user.ts b/test/common/services/security/test_user.ts index 695294f08b02d8..1161e7b493f419 100644 --- a/test/common/services/security/test_user.ts +++ b/test/common/services/security/test_user.ts @@ -71,13 +71,12 @@ export class TestUser extends FtrService { export async function createTestUserService(ctx: FtrProviderContext, role: Role, user: User) { const log = ctx.getService('log'); const config = ctx.getService('config'); - const kibanaServer = ctx.getService('kibanaServer'); - const enabledPlugins = config.get('security.disableTestUser') - ? [] - : await kibanaServer.plugins.getEnabledIds(); - - const enabled = enabledPlugins.includes('security') && !config.get('security.disableTestUser'); + const enabled = + !config + .get('esTestCluster.serverArgs') + .some((arg: string) => arg === 'xpack.security.enabled=false') && + !config.get('security.disableTestUser'); if (enabled) { log.debug('===============creating roles and users==============='); diff --git a/test/functional/config.js b/test/functional/config.js index e0195c4dadc8d5..5b0b79e84e8df3 100644 --- a/test/functional/config.js +++ b/test/functional/config.js @@ -45,7 +45,6 @@ export default async function ({ readConfigFile }) { '--savedObjects.maxImportPayloadBytes=10485760', // to be re-enabled once kibana/issues/102552 is completed - '--xpack.security.enabled=false', '--xpack.reporting.enabled=false', ], }, diff --git a/x-pack/plugins/security/server/config.test.ts b/x-pack/plugins/security/server/config.test.ts index 4034a7a79e6dd9..ababf435af3c98 100644 --- a/x-pack/plugins/security/server/config.test.ts +++ b/x-pack/plugins/security/server/config.test.ts @@ -56,7 +56,6 @@ describe('config schema', () => { "selector": Object {}, }, "cookieName": "sid", - "enabled": true, "encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "loginAssistanceMessage": "", "public": Object {}, @@ -110,7 +109,6 @@ describe('config schema', () => { "selector": Object {}, }, "cookieName": "sid", - "enabled": true, "encryptionKey": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "loginAssistanceMessage": "", "public": Object {}, @@ -164,7 +162,6 @@ describe('config schema', () => { "selector": Object {}, }, "cookieName": "sid", - "enabled": true, "loginAssistanceMessage": "", "public": Object {}, "secureCookies": false, diff --git a/x-pack/plugins/security/server/config.ts b/x-pack/plugins/security/server/config.ts index 23a1fd2efa3827..a9e22448e17258 100644 --- a/x-pack/plugins/security/server/config.ts +++ b/x-pack/plugins/security/server/config.ts @@ -198,7 +198,6 @@ const providersConfigSchema = schema.object( ); export const ConfigSchema = schema.object({ - enabled: schema.boolean({ defaultValue: true }), loginAssistanceMessage: schema.string({ defaultValue: '' }), showInsecureClusterWarning: schema.boolean({ defaultValue: true }), loginHelp: schema.maybe(schema.string()), diff --git a/x-pack/plugins/security/server/config_deprecations.test.ts b/x-pack/plugins/security/server/config_deprecations.test.ts index a629b6d73a682f..3c674de97ad8ef 100644 --- a/x-pack/plugins/security/server/config_deprecations.test.ts +++ b/x-pack/plugins/security/server/config_deprecations.test.ts @@ -357,34 +357,4 @@ describe('Config Deprecations', () => { ] `); }); - - it('warns when the security plugin is disabled', () => { - const config = { - xpack: { - security: { - enabled: false, - }, - }, - }; - const { messages, migrated } = applyConfigDeprecations(cloneDeep(config)); - expect(migrated).toEqual(config); - expect(messages).toMatchInlineSnapshot(` - Array [ - "Disabling the security plugin \\"xpack.security.enabled\\" will only be supported by disable security in Elasticsearch.", - ] - `); - }); - - it('does not warn when the security plugin is enabled', () => { - const config = { - xpack: { - security: { - enabled: true, - }, - }, - }; - const { messages, migrated } = applyConfigDeprecations(cloneDeep(config)); - expect(migrated).toEqual(config); - expect(messages).toHaveLength(0); - }); }); diff --git a/x-pack/plugins/security/server/config_deprecations.ts b/x-pack/plugins/security/server/config_deprecations.ts index 0c76840819b3d5..055818a159a791 100644 --- a/x-pack/plugins/security/server/config_deprecations.ts +++ b/x-pack/plugins/security/server/config_deprecations.ts @@ -157,28 +157,4 @@ export const securityConfigDeprecationProvider: ConfigDeprecationProvider = ({ }); } }, - (settings, fromPath, addDeprecation) => { - if (settings?.xpack?.security?.enabled === false) { - addDeprecation({ - configPath: 'xpack.security.enabled', - title: i18n.translate('xpack.security.deprecations.enabledTitle', { - defaultMessage: 'Disabling the security plugin "xpack.security.enabled" is deprecated', - }), - message: i18n.translate('xpack.security.deprecations.enabledMessage', { - defaultMessage: - 'Disabling the security plugin "xpack.security.enabled" will only be supported by disable security in Elasticsearch.', - }), - correctiveActions: { - manualSteps: [ - i18n.translate('xpack.security.deprecations.enabled.manualStepOneMessage', { - defaultMessage: `Remove "xpack.security.enabled" from your Kibana configuration.`, - }), - i18n.translate('xpack.security.deprecations.enabled.manualStepTwoMessage', { - defaultMessage: `To turn off security features, disable them in Elasticsearch instead.`, - }), - ], - }, - }); - } - }, ]; diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index 3fe5ecb6076e24..7bcec7b11c10e2 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -242,7 +242,9 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) }, }, })}`, - ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + ...disabledPlugins + .filter((k) => k !== 'security') + .map((key) => `--xpack.${key}.enabled=false`), ...plugins.map( (pluginDir) => `--plugin-path=${path.resolve(__dirname, 'fixtures', 'plugins', pluginDir)}` diff --git a/x-pack/test/case_api_integration/common/config.ts b/x-pack/test/case_api_integration/common/config.ts index 2658472a7b84dd..284b4360dacf84 100644 --- a/x-pack/test/case_api_integration/common/config.ts +++ b/x-pack/test/case_api_integration/common/config.ts @@ -118,7 +118,9 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) `--xpack.actions.allowedHosts=${JSON.stringify(['localhost', 'some.non.existent.com'])}`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, '--xpack.eventLog.logEntries=true', - ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + ...disabledPlugins + .filter((k) => k !== 'security') + .map((key) => `--xpack.${key}.enabled=false`), // Actions simulators plugin. Needed for testing push to external services. ...alertingPlugins.map( (pluginDir) => diff --git a/x-pack/test/lists_api_integration/common/config.ts b/x-pack/test/lists_api_integration/common/config.ts index 4983f00cce044a..214f03b6326586 100644 --- a/x-pack/test/lists_api_integration/common/config.ts +++ b/x-pack/test/lists_api_integration/common/config.ts @@ -51,7 +51,9 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ...xPackApiIntegrationTestsConfig.get('kbnTestServer'), serverArgs: [ ...xPackApiIntegrationTestsConfig.get('kbnTestServer.serverArgs'), - ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + ...disabledPlugins + .filter((k) => k !== 'security') + .map((key) => `--xpack.${key}.enabled=false`), `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'alerts')}`, `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'actions')}`, `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'task_manager')}`, diff --git a/x-pack/test/reporting_api_integration/reporting_without_security.config.ts b/x-pack/test/reporting_api_integration/reporting_without_security.config.ts index dfd79916b5ce0c..0779b3b871e363 100644 --- a/x-pack/test/reporting_api_integration/reporting_without_security.config.ts +++ b/x-pack/test/reporting_api_integration/reporting_without_security.config.ts @@ -24,7 +24,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { }, kbnTestServer: { ...apiConfig.get('kbnTestServer'), - serverArgs: [...apiConfig.get('kbnTestServer.serverArgs'), `--xpack.security.enabled=false`], + serverArgs: [...apiConfig.get('kbnTestServer.serverArgs')], }, }; } diff --git a/x-pack/test/reporting_functional/reporting_without_security.config.ts b/x-pack/test/reporting_functional/reporting_without_security.config.ts index 0269f57bf08cb4..7ca7f89a0b709d 100644 --- a/x-pack/test/reporting_functional/reporting_without_security.config.ts +++ b/x-pack/test/reporting_functional/reporting_without_security.config.ts @@ -17,10 +17,7 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { testFiles: [resolve(__dirname, './reporting_without_security')], kbnTestServer: { ...reportingConfig.get('kbnTestServer'), - serverArgs: [ - ...reportingConfig.get('kbnTestServer.serverArgs'), - `--xpack.security.enabled=false`, - ], + serverArgs: [...reportingConfig.get('kbnTestServer.serverArgs')], }, esTestCluster: { ...reportingConfig.get('esTestCluster'), diff --git a/x-pack/test/rule_registry/common/config.ts b/x-pack/test/rule_registry/common/config.ts index 9cce58c30f6e98..6b920a6f5dbf26 100644 --- a/x-pack/test/rule_registry/common/config.ts +++ b/x-pack/test/rule_registry/common/config.ts @@ -79,7 +79,9 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) `--xpack.actions.allowedHosts=${JSON.stringify(['localhost', 'some.non.existent.com'])}`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, '--xpack.eventLog.logEntries=true', - ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + ...disabledPlugins + .filter((k) => k !== 'security') + .map((key) => `--xpack.${key}.enabled=false`), // TO DO: Remove feature flags once we're good to go '--xpack.securitySolution.enableExperimental=["ruleRegistryEnabled"]', '--xpack.ruleRegistry.write.enabled=true', diff --git a/x-pack/test/saved_object_api_integration/common/config.ts b/x-pack/test/saved_object_api_integration/common/config.ts index 9b9e46efa6d5d2..8ca74c7fcea49d 100644 --- a/x-pack/test/saved_object_api_integration/common/config.ts +++ b/x-pack/test/saved_object_api_integration/common/config.ts @@ -54,7 +54,9 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ...config.xpack.api.get('kbnTestServer.serverArgs'), '--server.xsrf.disableProtection=true', `--plugin-path=${path.join(__dirname, 'fixtures', 'saved_object_test_plugin')}`, - ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + ...disabledPlugins + .filter((k) => k !== 'security') + .map((key) => `--xpack.${key}.enabled=false`), ], }, }; diff --git a/x-pack/test/spaces_api_integration/common/config.ts b/x-pack/test/spaces_api_integration/common/config.ts index 7cceb945790d5a..5d135cd05605c4 100644 --- a/x-pack/test/spaces_api_integration/common/config.ts +++ b/x-pack/test/spaces_api_integration/common/config.ts @@ -61,7 +61,9 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) '--status.allowAnonymous=false', '--server.xsrf.disableProtection=true', `--plugin-path=${path.join(__dirname, 'fixtures', 'spaces_test_plugin')}`, - ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + ...disabledPlugins + .filter((k) => k !== 'security') + .map((key) => `--xpack.${key}.enabled=false`), ], }, }; diff --git a/x-pack/test/timeline/common/config.ts b/x-pack/test/timeline/common/config.ts index fa8ddb2ad10a75..211f380b133a55 100644 --- a/x-pack/test/timeline/common/config.ts +++ b/x-pack/test/timeline/common/config.ts @@ -79,7 +79,9 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) `--xpack.actions.allowedHosts=${JSON.stringify(['localhost', 'some.non.existent.com'])}`, `--xpack.actions.enabledActionTypes=${JSON.stringify(enabledActionTypes)}`, '--xpack.eventLog.logEntries=true', - ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + ...disabledPlugins + .filter((k) => k !== 'security') + .map((key) => `--xpack.${key}.enabled=false`), // TO DO: Remove feature flags once we're good to go '--xpack.securitySolution.enableExperimental=["ruleRegistryEnabled"]', '--xpack.ruleRegistry.write.enabled=true', diff --git a/x-pack/test/ui_capabilities/common/config.ts b/x-pack/test/ui_capabilities/common/config.ts index 1f695e562da053..f676a5eeccee11 100644 --- a/x-pack/test/ui_capabilities/common/config.ts +++ b/x-pack/test/ui_capabilities/common/config.ts @@ -42,7 +42,9 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) ...xPackFunctionalTestsConfig.get('kbnTestServer'), serverArgs: [ ...xPackFunctionalTestsConfig.get('kbnTestServer.serverArgs'), - ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), + ...disabledPlugins + .filter((k) => k !== 'security') + .map((key) => `--xpack.${key}.enabled=false`), `--plugin-path=${path.join(__dirname, 'fixtures', 'plugins', 'foo_plugin')}`, ], }, diff --git a/x-pack/test/ui_capabilities/spaces_only/tests/catalogue.ts b/x-pack/test/ui_capabilities/spaces_only/tests/catalogue.ts index b50f11553747c3..e694b5be6e024f 100644 --- a/x-pack/test/ui_capabilities/spaces_only/tests/catalogue.ts +++ b/x-pack/test/ui_capabilities/spaces_only/tests/catalogue.ts @@ -24,6 +24,13 @@ export default function catalogueTests({ getService }: FtrProviderContext) { 'watcher', ]; + const uiCapabilitiesExceptions = [ + // enterprise_search plugin is loaded but disabled because security isn't enabled in ES. That means the following 3 capabilities are disabled + 'enterpriseSearch', + 'appSearch', + 'workplaceSearch', + ]; + describe('catalogue', () => { SpaceScenarios.forEach((scenario) => { it(`${scenario.name}`, async () => { @@ -33,7 +40,10 @@ export default function catalogueTests({ getService }: FtrProviderContext) { expect(uiCapabilities.success).to.be(true); expect(uiCapabilities.value).to.have.property('catalogue'); // everything is enabled - const expected = mapValues(uiCapabilities.value!.catalogue, () => true); + const expected = mapValues( + uiCapabilities.value!.catalogue, + (enabled, catalogueId) => !uiCapabilitiesExceptions.includes(catalogueId) + ); expect(uiCapabilities.value!.catalogue).to.eql(expected); break; } @@ -55,7 +65,8 @@ export default function catalogueTests({ getService }: FtrProviderContext) { // only foo is disabled const expected = mapValues( uiCapabilities.value!.catalogue, - (value, catalogueId) => catalogueId !== 'foo' + (enabled, catalogueId) => + !uiCapabilitiesExceptions.includes(catalogueId) && catalogueId !== 'foo' ); expect(uiCapabilities.value!.catalogue).to.eql(expected); break; diff --git a/x-pack/test/ui_capabilities/spaces_only/tests/nav_links.ts b/x-pack/test/ui_capabilities/spaces_only/tests/nav_links.ts index 17c01888a70241..4ef919ebb46aa8 100644 --- a/x-pack/test/ui_capabilities/spaces_only/tests/nav_links.ts +++ b/x-pack/test/ui_capabilities/spaces_only/tests/nav_links.ts @@ -16,6 +16,13 @@ export default function navLinksTests({ getService }: FtrProviderContext) { const uiCapabilitiesService: UICapabilitiesService = getService('uiCapabilities'); const featuresService: FeaturesService = getService('features'); + const uiCapabilitiesExceptions = [ + // enterprise_search plugin is loaded but disabled because security isn't enabled in ES. That means the following 3 capabilities are disabled + 'enterpriseSearch', + 'appSearch', + 'workplaceSearch', + ]; + describe('navLinks', () => { let navLinksBuilder: NavLinksBuilder; before(async () => { @@ -30,7 +37,9 @@ export default function navLinksTests({ getService }: FtrProviderContext) { case 'everything_space': expect(uiCapabilities.success).to.be(true); expect(uiCapabilities.value).to.have.property('navLinks'); - expect(uiCapabilities.value!.navLinks).to.eql(navLinksBuilder.all()); + expect(uiCapabilities.value!.navLinks).to.eql( + navLinksBuilder.except(...uiCapabilitiesExceptions) + ); break; case 'nothing_space': expect(uiCapabilities.success).to.be(true); @@ -40,7 +49,9 @@ export default function navLinksTests({ getService }: FtrProviderContext) { case 'foo_disabled_space': expect(uiCapabilities.success).to.be(true); expect(uiCapabilities.value).to.have.property('navLinks'); - expect(uiCapabilities.value!.navLinks).to.eql(navLinksBuilder.except('foo')); + expect(uiCapabilities.value!.navLinks).to.eql( + navLinksBuilder.except('foo', ...uiCapabilitiesExceptions) + ); break; default: throw new UnreachableError(scenario); From 1732927fb1004e59bd84bfab4638421818e04402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Marcondes?= <55978943+cauemarcondes@users.noreply.github.com> Date: Mon, 25 Oct 2021 14:13:40 -0400 Subject: [PATCH 36/66] adjusting charts timezone (#116014) --- src/plugins/data/common/constants.ts | 1 + .../alerting/chart_preview/index.tsx | 7 +++++++ .../error_count_alert_trigger/index.tsx | 1 + .../index.tsx | 1 + .../index.tsx | 1 + .../Distribution/index.stories.tsx | 11 ++++++---- .../Distribution/index.tsx | 5 +++++ .../shared/charts/breakdown_chart/index.tsx | 10 +++++---- .../shared/charts/helper/timezone.test.ts | 21 ++++++++++++++++++- .../shared/charts/helper/timezone.ts | 14 +++++++++++++ .../shared/charts/timeseries_chart.tsx | 8 +++++-- 11 files changed, 69 insertions(+), 11 deletions(-) diff --git a/src/plugins/data/common/constants.ts b/src/plugins/data/common/constants.ts index e141bfbef3c89a..1c457fdb64ce25 100644 --- a/src/plugins/data/common/constants.ts +++ b/src/plugins/data/common/constants.ts @@ -35,4 +35,5 @@ export const UI_SETTINGS = { AUTOCOMPLETE_USE_TIMERANGE: 'autocomplete:useTimeRange', AUTOCOMPLETE_VALUE_SUGGESTION_METHOD: 'autocomplete:valueSuggestionMethod', DATE_FORMAT: 'dateFormat', + DATEFORMAT_TZ: 'dateFormat:tz', } as const; diff --git a/x-pack/plugins/apm/public/components/alerting/chart_preview/index.tsx b/x-pack/plugins/apm/public/components/alerting/chart_preview/index.tsx index fb1a99db0bf5be..2015bf2228b6ce 100644 --- a/x-pack/plugins/apm/public/components/alerting/chart_preview/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/chart_preview/index.tsx @@ -23,17 +23,21 @@ import { EuiSpacer } from '@elastic/eui'; import React from 'react'; import { Coordinate } from '../../../../typings/timeseries'; import { useTheme } from '../../../hooks/use_theme'; +import { IUiSettingsClient } from '../../../../../../../src/core/public'; +import { getTimeZone } from '../../shared/charts/helper/timezone'; interface ChartPreviewProps { yTickFormat?: TickFormatter; data?: Coordinate[]; threshold: number; + uiSettings?: IUiSettingsClient; } export function ChartPreview({ data = [], yTickFormat, threshold, + uiSettings, }: ChartPreviewProps) { const theme = useTheme(); const thresholdOpacity = 0.3; @@ -67,6 +71,8 @@ export function ChartPreview({ }, ]; + const timeZone = getTimeZone(uiSettings); + return ( <> @@ -99,6 +105,7 @@ export function ChartPreview({ domain={{ max: yMax, min: NaN }} /> ); diff --git a/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx index 8957dfc823e44e..fa75fcca579e5d 100644 --- a/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/transaction_duration_alert_trigger/index.tsx @@ -139,6 +139,7 @@ export function TransactionDurationAlertTrigger(props: Props) { data={latencyChartPreview} threshold={thresholdMs} yTickFormat={yTickFormat} + uiSettings={services.uiSettings} /> ); diff --git a/x-pack/plugins/apm/public/components/alerting/transaction_error_rate_alert_trigger/index.tsx b/x-pack/plugins/apm/public/components/alerting/transaction_error_rate_alert_trigger/index.tsx index ddddc4bbecbad5..a818218cbf3add 100644 --- a/x-pack/plugins/apm/public/components/alerting/transaction_error_rate_alert_trigger/index.tsx +++ b/x-pack/plugins/apm/public/components/alerting/transaction_error_rate_alert_trigger/index.tsx @@ -131,6 +131,7 @@ export function TransactionErrorRateAlertTrigger(props: Props) { data={data?.errorRateChartPreview} yTickFormat={(d: number | null) => asPercent(d, 1)} threshold={thresholdAsPercent} + uiSettings={services.uiSettings} /> ); diff --git a/x-pack/plugins/apm/public/components/app/error_group_details/Distribution/index.stories.tsx b/x-pack/plugins/apm/public/components/app/error_group_details/Distribution/index.stories.tsx index 4efc00ef71b911..101923a7678fb7 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_details/Distribution/index.stories.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_details/Distribution/index.stories.tsx @@ -19,14 +19,17 @@ export default { component: ErrorDistribution, decorators: [ (Story: ComponentType) => { - const apmPluginContextMock = { - observabilityRuleTypeRegistry: { getFormatter: () => undefined }, - } as unknown as ApmPluginContextValue; - const kibanaContextServices = { uiSettings: { get: () => {} }, }; + const apmPluginContextMock = { + observabilityRuleTypeRegistry: { getFormatter: () => undefined }, + core: { + uiSettings: kibanaContextServices.uiSettings, + }, + } as unknown as ApmPluginContextValue; + return ( diff --git a/x-pack/plugins/apm/public/components/app/error_group_details/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_details/Distribution/index.tsx index 429ad989b97382..6a3157b3c4b7fb 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_details/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_details/Distribution/index.tsx @@ -32,6 +32,7 @@ import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plug import { LazyAlertsFlyout } from '../../../../../../observability/public'; import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; import { Coordinate } from '../../../../../typings/timeseries'; +import { getTimeZone } from '../../../shared/charts/helper/timezone'; const ALERT_RULE_TYPE_ID: typeof ALERT_RULE_TYPE_ID_TYPED = ALERT_RULE_TYPE_ID_NON_TYPED; @@ -58,6 +59,7 @@ interface Props { } export function ErrorDistribution({ distribution, title, fetchStatus }: Props) { + const { core } = useApmPluginContext(); const theme = useTheme(); const currentPeriod = getCoordinatedBuckets(distribution.currentPeriod); const previousPeriod = getCoordinatedBuckets(distribution.previousPeriod); @@ -103,6 +105,8 @@ export function ErrorDistribution({ distribution, title, fetchStatus }: Props) { undefined ); + const timeZone = getTimeZone(core.uiSettings); + return ( <> @@ -138,6 +142,7 @@ export function ErrorDistribution({ distribution, title, fetchStatus }: Props) { {timeseries.map((serie) => { return ( @@ -150,6 +151,7 @@ export function BreakdownChart({ timeseries.map((serie) => { return ( { let originalTimezone: moment.MomentZone | null; @@ -67,4 +68,22 @@ describe('Timezone helper', () => { ]); }); }); + + describe('getTimeZone', () => { + it('returns local when uiSettings is undefined', () => { + expect(getTimeZone()).toEqual('local'); + }); + + it('returns local when uiSettings returns Browser', () => { + expect( + getTimeZone({ get: () => 'Browser' } as unknown as IUiSettingsClient) + ).toEqual('local'); + }); + it('returns timezone defined on uiSettings', () => { + const timezone = 'America/toronto'; + expect( + getTimeZone({ get: () => timezone } as unknown as IUiSettingsClient) + ).toEqual(timezone); + }); + }); }); diff --git a/x-pack/plugins/apm/public/components/shared/charts/helper/timezone.ts b/x-pack/plugins/apm/public/components/shared/charts/helper/timezone.ts index 539c81c61c3ce3..f807d83c8977ff 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/helper/timezone.ts +++ b/x-pack/plugins/apm/public/components/shared/charts/helper/timezone.ts @@ -7,6 +7,8 @@ import d3 from 'd3'; import { getTimezoneOffsetInMs } from './get_timezone_offset_in_ms'; +import { IUiSettingsClient } from '../../../../../../../../src/core/public'; +import { UI_SETTINGS } from '../../../../../../../../src/plugins/data/common'; interface Params { domain: [number, number]; @@ -31,3 +33,15 @@ export const getDomainTZ = (min: number, max: number): [number, number] => { ); return [xMinZone, xMaxZone]; }; + +export function getTimeZone(uiSettings?: IUiSettingsClient) { + const kibanaTimeZone = uiSettings?.get<'Browser' | string>( + UI_SETTINGS.DATEFORMAT_TZ + ); + + if (!kibanaTimeZone || kibanaTimeZone === 'Browser') { + return 'local'; + } + + return kibanaTimeZone; +} diff --git a/x-pack/plugins/apm/public/components/shared/charts/timeseries_chart.tsx b/x-pack/plugins/apm/public/components/shared/charts/timeseries_chart.tsx index 08e8908d50e7ae..bcdfff2678cda1 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/timeseries_chart.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/timeseries_chart.tsx @@ -19,8 +19,8 @@ import { RectAnnotation, ScaleType, Settings, - YDomainRange, XYBrushEvent, + YDomainRange, } from '@elastic/charts'; import { EuiIcon } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; @@ -46,6 +46,7 @@ import { getLatencyChartSelector } from '../../../selectors/latency_chart_select import { unit } from '../../../utils/style'; import { ChartContainer } from './chart_container'; import { getAlertAnnotations } from './helper/get_alert_annotations'; +import { getTimeZone } from './helper/timezone'; import { isTimeseriesEmpty, onBrushEnd } from './helper/helper'; interface Props { @@ -85,7 +86,7 @@ export function TimeseriesChart({ alerts, }: Props) { const history = useHistory(); - const { observabilityRuleTypeRegistry } = useApmPluginContext(); + const { observabilityRuleTypeRegistry, core } = useApmPluginContext(); const { getFormatter } = observabilityRuleTypeRegistry; const { annotations } = useAnnotationsContext(); const { setPointerEvent, chartRef } = useChartPointerEventContext(); @@ -97,6 +98,8 @@ export function TimeseriesChart({ const xValues = timeseries.flatMap(({ data }) => data.map(({ x }) => x)); + const timeZone = getTimeZone(core.uiSettings); + const min = Math.min(...xValues); const max = Math.max(...xValues); @@ -180,6 +183,7 @@ export function TimeseriesChart({ return ( Date: Mon, 25 Oct 2021 20:28:47 +0200 Subject: [PATCH 37/66] Store interactive setup certificates in the data folder. (#115981) --- src/cli_setup/utils.ts | 4 +- .../server/kibana_config_writer.test.ts | 366 +++++++++--------- .../server/kibana_config_writer.ts | 21 +- .../interactive_setup/server/plugin.ts | 7 +- 4 files changed, 196 insertions(+), 202 deletions(-) diff --git a/src/cli_setup/utils.ts b/src/cli_setup/utils.ts index 65a46b8f5b2783..21406bf7e57e06 100644 --- a/src/cli_setup/utils.ts +++ b/src/cli_setup/utils.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { getConfigPath } from '@kbn/utils'; +import { getConfigPath, getDataPath } from '@kbn/utils'; import inquirer from 'inquirer'; import { duration } from 'moment'; import { merge } from 'lodash'; @@ -30,7 +30,7 @@ const logger: Logger = { get: () => logger, }; -export const kibanaConfigWriter = new KibanaConfigWriter(getConfigPath(), logger); +export const kibanaConfigWriter = new KibanaConfigWriter(getConfigPath(), getDataPath(), logger); export const elasticsearch = new ElasticsearchService(logger).setup({ connectionCheckInterval: duration(Infinity), elasticsearch: { diff --git a/src/plugins/interactive_setup/server/kibana_config_writer.test.ts b/src/plugins/interactive_setup/server/kibana_config_writer.test.ts index 4b68451930a3db..0580a35d909ea8 100644 --- a/src/plugins/interactive_setup/server/kibana_config_writer.test.ts +++ b/src/plugins/interactive_setup/server/kibana_config_writer.test.ts @@ -30,6 +30,7 @@ describe('KibanaConfigWriter', () => { kibanaConfigWriter = new KibanaConfigWriter( '/some/path/kibana.yml', + '/data', loggingSystemMock.createLogger() ); }); @@ -37,15 +38,15 @@ describe('KibanaConfigWriter', () => { afterEach(() => jest.resetAllMocks()); describe('#isConfigWritable()', () => { - it('returns `false` if config directory is not writable even if kibana yml is writable', async () => { + it('returns `false` if data directory is not writable even if kibana yml is writable', async () => { mockFsAccess.mockImplementation((path, modifier) => - path === '/some/path' && modifier === constants.W_OK ? Promise.reject() : Promise.resolve() + path === '/data' && modifier === constants.W_OK ? Promise.reject() : Promise.resolve() ); await expect(kibanaConfigWriter.isConfigWritable()).resolves.toBe(false); }); - it('returns `false` if kibana yml is NOT writable if even config directory is writable', async () => { + it('returns `false` if kibana yml is NOT writable if even data directory is writable', async () => { mockFsAccess.mockImplementation((path, modifier) => path === '/some/path/kibana.yml' && modifier === constants.W_OK ? Promise.reject() @@ -55,219 +56,208 @@ describe('KibanaConfigWriter', () => { await expect(kibanaConfigWriter.isConfigWritable()).resolves.toBe(false); }); - it('returns `true` if both kibana yml and config directory are writable', async () => { + it('returns `true` if both kibana yml and data directory are writable', async () => { mockFsAccess.mockResolvedValue(undefined); await expect(kibanaConfigWriter.isConfigWritable()).resolves.toBe(true); }); - it('returns `true` even if kibana yml does not exist when config directory is writable', async () => { + it('returns `true` even if kibana yml does not exist even if data directory is writable', async () => { mockFsAccess.mockImplementation((path) => path === '/some/path/kibana.yml' ? Promise.reject() : Promise.resolve() ); - await expect(kibanaConfigWriter.isConfigWritable()).resolves.toBe(true); + await expect(kibanaConfigWriter.isConfigWritable()).resolves.toBe(false); }); }); describe('#writeConfig()', () => { - describe('without existing config', () => { - beforeEach(() => { - mockReadFile.mockResolvedValue(''); - }); - - it('throws if cannot write CA file', async () => { - mockWriteFile.mockRejectedValue(new Error('Oh no!')); - - await expect( - kibanaConfigWriter.writeConfig({ - caCert: 'ca-content', - host: '', - serviceAccountToken: { name: '', value: '' }, - }) - ).rejects.toMatchInlineSnapshot(`[Error: Oh no!]`); - - expect(mockWriteFile).toHaveBeenCalledTimes(1); - expect(mockWriteFile).toHaveBeenCalledWith('/some/path/ca_1234.crt', 'ca-content'); - }); - - it('throws if cannot write config to yaml file', async () => { - mockWriteFile.mockResolvedValueOnce(undefined).mockRejectedValueOnce(new Error('Oh no!')); - - await expect( - kibanaConfigWriter.writeConfig({ - caCert: 'ca-content', - host: 'some-host', - serviceAccountToken: { name: 'some-token', value: 'some-value' }, - }) - ).rejects.toMatchInlineSnapshot(`[Error: Oh no!]`); - - expect(mockWriteFile).toHaveBeenCalledTimes(2); - expect(mockWriteFile).toHaveBeenCalledWith('/some/path/ca_1234.crt', 'ca-content'); - expect(mockWriteFile).toHaveBeenCalledWith( - '/some/path/kibana.yml', - ` - -# This section was automatically generated during setup. -elasticsearch.hosts: [some-host] -elasticsearch.serviceAccountToken: some-value -elasticsearch.ssl.certificateAuthorities: [/some/path/ca_1234.crt] - -` - ); - }); - - it('throws if cannot read existing config', async () => { - mockReadFile.mockRejectedValue(new Error('Oh no!')); - - await expect( - kibanaConfigWriter.writeConfig({ - caCert: 'ca-content', - host: 'some-host', - serviceAccountToken: { name: 'some-token', value: 'some-value' }, - }) - ).rejects.toMatchInlineSnapshot(`[Error: Oh no!]`); - - expect(mockWriteFile).not.toHaveBeenCalled(); - }); - - it('throws if cannot parse existing config', async () => { - mockReadFile.mockResolvedValue('foo: bar\nfoo: baz'); - - await expect( - kibanaConfigWriter.writeConfig({ - caCert: 'ca-content', - host: 'some-host', - serviceAccountToken: { name: 'some-token', value: 'some-value' }, - }) - ).rejects.toMatchInlineSnapshot(` - [YAMLException: duplicated mapping key at line 2, column 1: - foo: baz - ^] - `); - - expect(mockWriteFile).not.toHaveBeenCalled(); - }); - - it('can successfully write CA certificate and elasticsearch config with service token', async () => { - await expect( - kibanaConfigWriter.writeConfig({ - caCert: 'ca-content', - host: 'some-host', - serviceAccountToken: { name: 'some-token', value: 'some-value' }, - }) - ).resolves.toBeUndefined(); + beforeEach(() => { + mockReadFile.mockResolvedValue( + '# Default Kibana configuration for docker target\nserver.host: "0.0.0.0"\nserver.shutdownTimeout: "5s"' + ); + }); - expect(mockWriteFile).toHaveBeenCalledTimes(2); - expect(mockWriteFile).toHaveBeenCalledWith('/some/path/ca_1234.crt', 'ca-content'); - expect(mockWriteFile).toHaveBeenCalledWith( - '/some/path/kibana.yml', - ` + it('throws if cannot write CA file', async () => { + mockWriteFile.mockRejectedValue(new Error('Oh no!')); -# This section was automatically generated during setup. -elasticsearch.hosts: [some-host] -elasticsearch.serviceAccountToken: some-value -elasticsearch.ssl.certificateAuthorities: [/some/path/ca_1234.crt] + await expect( + kibanaConfigWriter.writeConfig({ + caCert: 'ca-content', + host: '', + serviceAccountToken: { name: '', value: '' }, + }) + ).rejects.toMatchInlineSnapshot(`[Error: Oh no!]`); -` - ); - }); + expect(mockWriteFile).toHaveBeenCalledTimes(1); + expect(mockWriteFile).toHaveBeenCalledWith('/data/ca_1234.crt', 'ca-content'); + }); - it('can successfully write CA certificate and elasticsearch config with credentials', async () => { - await expect( - kibanaConfigWriter.writeConfig({ - caCert: 'ca-content', - host: 'some-host', - username: 'username', - password: 'password', - }) - ).resolves.toBeUndefined(); + it('throws if cannot write config to yaml file', async () => { + mockWriteFile.mockResolvedValueOnce(undefined).mockRejectedValueOnce(new Error('Oh no!')); - expect(mockWriteFile).toHaveBeenCalledTimes(2); - expect(mockWriteFile).toHaveBeenCalledWith('/some/path/ca_1234.crt', 'ca-content'); - expect(mockWriteFile).toHaveBeenCalledWith( - '/some/path/kibana.yml', - ` - -# This section was automatically generated during setup. -elasticsearch.hosts: [some-host] -elasticsearch.password: password -elasticsearch.username: username -elasticsearch.ssl.certificateAuthorities: [/some/path/ca_1234.crt] - -` - ); - }); + await expect( + kibanaConfigWriter.writeConfig({ + caCert: 'ca-content', + host: 'some-host', + serviceAccountToken: { name: 'some-token', value: 'some-value' }, + }) + ).rejects.toMatchInlineSnapshot(`[Error: Oh no!]`); - it('can successfully write elasticsearch config without CA certificate', async () => { - await expect( - kibanaConfigWriter.writeConfig({ - host: 'some-host', - username: 'username', - password: 'password', - }) - ).resolves.toBeUndefined(); + expect(mockWriteFile.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + "/data/ca_1234.crt", + "ca-content", + ], + Array [ + "/some/path/kibana.yml", + "# Default Kibana configuration for docker target + server.host: \\"0.0.0.0\\" + server.shutdownTimeout: \\"5s\\" + + # This section was automatically generated during setup. + elasticsearch.hosts: [some-host] + elasticsearch.serviceAccountToken: some-value + elasticsearch.ssl.certificateAuthorities: [/data/ca_1234.crt] + + ", + ], + ] + `); + }); - expect(mockWriteFile).toHaveBeenCalledTimes(1); - expect(mockWriteFile).toHaveBeenCalledWith( - '/some/path/kibana.yml', - ` + it('throws if cannot read existing config', async () => { + mockReadFile.mockRejectedValue(new Error('Oh no!')); -# This section was automatically generated during setup. -elasticsearch.hosts: [some-host] -elasticsearch.password: password -elasticsearch.username: username + await expect( + kibanaConfigWriter.writeConfig({ + caCert: 'ca-content', + host: 'some-host', + serviceAccountToken: { name: 'some-token', value: 'some-value' }, + }) + ).rejects.toMatchInlineSnapshot(`[Error: Oh no!]`); -` - ); - }); + expect(mockWriteFile).not.toHaveBeenCalled(); }); - describe('with existing config (no conflicts)', () => { - beforeEach(() => { - mockReadFile.mockResolvedValue( - '# Default Kibana configuration for docker target\nserver.host: "0.0.0.0"\nserver.shutdownTimeout: "5s"' - ); - }); - - it('can successfully write CA certificate and elasticsearch config', async () => { - await expect( - kibanaConfigWriter.writeConfig({ - caCert: 'ca-content', - host: 'some-host', - serviceAccountToken: { name: 'some-token', value: 'some-value' }, - }) - ).resolves.toBeUndefined(); - - expect(mockReadFile).toHaveBeenCalledTimes(1); - expect(mockReadFile).toHaveBeenCalledWith('/some/path/kibana.yml', 'utf-8'); + it('throws if cannot parse existing config', async () => { + mockReadFile.mockResolvedValue('foo: bar\nfoo: baz'); + + await expect( + kibanaConfigWriter.writeConfig({ + caCert: 'ca-content', + host: 'some-host', + serviceAccountToken: { name: 'some-token', value: 'some-value' }, + }) + ).rejects.toMatchInlineSnapshot(` + [YAMLException: duplicated mapping key at line 2, column 1: + foo: baz + ^] + `); + + expect(mockWriteFile).not.toHaveBeenCalled(); + }); - expect(mockWriteFile).toHaveBeenCalledTimes(2); - expect(mockWriteFile.mock.calls).toMatchInlineSnapshot(` + it('can successfully write CA certificate and elasticsearch config with credentials', async () => { + await expect( + kibanaConfigWriter.writeConfig({ + caCert: 'ca-content', + host: 'some-host', + username: 'username', + password: 'password', + }) + ).resolves.toBeUndefined(); + + expect(mockWriteFile.mock.calls).toMatchInlineSnapshot(` + Array [ Array [ - Array [ - "/some/path/ca_1234.crt", - "ca-content", - ], - Array [ - "/some/path/kibana.yml", - "# Default Kibana configuration for docker target - server.host: \\"0.0.0.0\\" - server.shutdownTimeout: \\"5s\\" + "/data/ca_1234.crt", + "ca-content", + ], + Array [ + "/some/path/kibana.yml", + "# Default Kibana configuration for docker target + server.host: \\"0.0.0.0\\" + server.shutdownTimeout: \\"5s\\" + + # This section was automatically generated during setup. + elasticsearch.hosts: [some-host] + elasticsearch.password: password + elasticsearch.username: username + elasticsearch.ssl.certificateAuthorities: [/data/ca_1234.crt] + + ", + ], + ] + `); + }); - # This section was automatically generated during setup. - elasticsearch.hosts: [some-host] - elasticsearch.serviceAccountToken: some-value - elasticsearch.ssl.certificateAuthorities: [/some/path/ca_1234.crt] + it('can successfully write elasticsearch config without CA certificate', async () => { + await expect( + kibanaConfigWriter.writeConfig({ + host: 'some-host', + username: 'username', + password: 'password', + }) + ).resolves.toBeUndefined(); + + expect(mockWriteFile.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + "/some/path/kibana.yml", + "# Default Kibana configuration for docker target + server.host: \\"0.0.0.0\\" + server.shutdownTimeout: \\"5s\\" + + # This section was automatically generated during setup. + elasticsearch.hosts: [some-host] + elasticsearch.password: password + elasticsearch.username: username + + ", + ], + ] + `); + }); - ", - ], - ] - `); - }); + it('can successfully write CA certificate and elasticsearch config with service token', async () => { + await expect( + kibanaConfigWriter.writeConfig({ + caCert: 'ca-content', + host: 'some-host', + serviceAccountToken: { name: 'some-token', value: 'some-value' }, + }) + ).resolves.toBeUndefined(); + + expect(mockReadFile).toHaveBeenCalledTimes(1); + expect(mockReadFile).toHaveBeenCalledWith('/some/path/kibana.yml', 'utf-8'); + + expect(mockWriteFile).toHaveBeenCalledTimes(2); + expect(mockWriteFile.mock.calls).toMatchInlineSnapshot(` + Array [ + Array [ + "/data/ca_1234.crt", + "ca-content", + ], + Array [ + "/some/path/kibana.yml", + "# Default Kibana configuration for docker target + server.host: \\"0.0.0.0\\" + server.shutdownTimeout: \\"5s\\" + + # This section was automatically generated during setup. + elasticsearch.hosts: [some-host] + elasticsearch.serviceAccountToken: some-value + elasticsearch.ssl.certificateAuthorities: [/data/ca_1234.crt] + + ", + ], + ] + `); }); - describe('with existing config (with conflicts)', () => { + describe('with conflicts', () => { beforeEach(() => { jest.spyOn(Date.prototype, 'toISOString').mockReturnValue('some date'); mockReadFile.mockResolvedValue( @@ -291,7 +281,7 @@ elasticsearch.username: username expect(mockWriteFile.mock.calls).toMatchInlineSnapshot(` Array [ Array [ - "/some/path/ca_1234.crt", + "/data/ca_1234.crt", "ca-content", ], Array [ @@ -312,7 +302,7 @@ elasticsearch.username: username elasticsearch.hosts: [some-host] monitoring.ui.container.elasticsearch.enabled: true elasticsearch.serviceAccountToken: some-value - elasticsearch.ssl.certificateAuthorities: [/some/path/ca_1234.crt] + elasticsearch.ssl.certificateAuthorities: [/data/ca_1234.crt] ", ], diff --git a/src/plugins/interactive_setup/server/kibana_config_writer.ts b/src/plugins/interactive_setup/server/kibana_config_writer.ts index ff67e887fab49a..ea7f776aad82fe 100644 --- a/src/plugins/interactive_setup/server/kibana_config_writer.ts +++ b/src/plugins/interactive_setup/server/kibana_config_writer.ts @@ -31,24 +31,23 @@ export type WriteConfigParameters = { ); export class KibanaConfigWriter { - constructor(private readonly configPath: string, private readonly logger: Logger) {} + constructor( + private readonly configPath: string, + private readonly dataDirectoryPath: string, + private readonly logger: Logger + ) {} /** - * Checks if we can write to the Kibana configuration file and configuration directory. + * Checks if we can write to the Kibana configuration file and data directory. */ public async isConfigWritable() { try { // We perform two separate checks here: - // 1. If we can write to config directory to add a new CA certificate file and potentially Kibana configuration - // file if it doesn't exist for some reason. + // 1. If we can write to data directory to add a new CA certificate file. // 2. If we can write to the Kibana configuration file if it exists. - const canWriteToConfigDirectory = fs.access(path.dirname(this.configPath), constants.W_OK); await Promise.all([ - canWriteToConfigDirectory, - fs.access(this.configPath, constants.F_OK).then( - () => fs.access(this.configPath, constants.W_OK), - () => canWriteToConfigDirectory - ), + fs.access(this.dataDirectoryPath, constants.W_OK), + fs.access(this.configPath, constants.W_OK), ]); return true; } catch { @@ -61,7 +60,7 @@ export class KibanaConfigWriter { * @param params */ public async writeConfig(params: WriteConfigParameters) { - const caPath = path.join(path.dirname(this.configPath), `ca_${Date.now()}.crt`); + const caPath = path.join(this.dataDirectoryPath, `ca_${Date.now()}.crt`); const config: Record = { 'elasticsearch.hosts': [params.host] }; if ('serviceAccountToken' in params) { config['elasticsearch.serviceAccountToken'] = params.serviceAccountToken.value; diff --git a/src/plugins/interactive_setup/server/plugin.ts b/src/plugins/interactive_setup/server/plugin.ts index 8c1d00a254764e..067b8fd044f30c 100644 --- a/src/plugins/interactive_setup/server/plugin.ts +++ b/src/plugins/interactive_setup/server/plugin.ts @@ -10,6 +10,7 @@ import chalk from 'chalk'; import type { Subscription } from 'rxjs'; import type { TypeOf } from '@kbn/config-schema'; +import { getDataPath } from '@kbn/utils'; import type { CorePreboot, Logger, PluginInitializerContext, PrebootPlugin } from 'src/core/server'; import { ElasticsearchConnectionStatus } from '../common'; @@ -146,7 +147,11 @@ Go to ${chalk.cyanBright.underline(url)} to get started. basePath: core.http.basePath, logger: this.#logger.get('routes'), preboot: { ...core.preboot, completeSetup }, - kibanaConfigWriter: new KibanaConfigWriter(configPath, this.#logger.get('kibana-config')), + kibanaConfigWriter: new KibanaConfigWriter( + configPath, + getDataPath(), + this.#logger.get('kibana-config') + ), elasticsearch, verificationCode, getConfig: this.#getConfig.bind(this), From a266b2d426f09f52f585a0facee4d2a7aaea20ec Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Mon, 25 Oct 2021 19:54:11 +0100 Subject: [PATCH 38/66] [Fleet] Add link to integration data retention documentation (#115353) * add ILM policy help text * update API docs * change link * regen api docs --- ...-plugin-core-public.doclinksstart.links.md | 1 + ...kibana-plugin-core-public.doclinksstart.md | 2 +- .../public/doc_links/doc_links_service.ts | 2 ++ src/core/public/public.api.md | 1 + .../step_define_package_policy.tsx | 28 +++++++++++++++++++ 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md index 01e7beae61ce8c..ed6763db69ffe4 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md @@ -229,6 +229,7 @@ readonly links: { readonly snapshotRestore: Record; readonly ingest: Record; readonly fleet: Readonly<{ + datastreamsILM: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index fdf469f443f281..96c2c0df9d7822 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -17,5 +17,5 @@ export interface DocLinksStart | --- | --- | --- | | [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | | | [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly settings: string;
readonly elasticStackGetStarted: string;
readonly apm: {
readonly kibanaSettings: string;
readonly supportedServiceMaps: string;
readonly customLinks: string;
readonly droppedTransactionSpans: string;
readonly upgrading: string;
readonly metaData: string;
};
readonly canvas: {
readonly guide: string;
};
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly discover: Record<string, string>;
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly elasticsearchModule: string;
readonly startup: string;
readonly exportedFields: string;
readonly suricataModule: string;
readonly zeekModule: string;
};
readonly auditbeat: {
readonly base: string;
readonly auditdModule: string;
readonly systemModule: string;
};
readonly metricbeat: {
readonly base: string;
readonly configure: string;
readonly httpEndpoint: string;
readonly install: string;
readonly start: string;
};
readonly enterpriseSearch: {
readonly base: string;
readonly appSearchBase: string;
readonly workplaceSearchBase: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly libbeat: {
readonly getStarted: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly runtimeFields: {
readonly overview: string;
readonly mapping: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessLangSpec: string;
readonly painlessSyntax: string;
readonly painlessWalkthrough: string;
readonly luceneExpressions: string;
};
readonly search: {
readonly sessions: string;
readonly sessionLimits: string;
};
readonly indexPatterns: {
readonly introduction: string;
readonly fieldFormattersNumber: string;
readonly fieldFormattersString: string;
readonly runtimeFields: string;
};
readonly addData: string;
readonly kibana: string;
readonly upgradeAssistant: string;
readonly rollupJobs: string;
readonly elasticsearch: Record<string, string>;
readonly siem: {
readonly privileges: string;
readonly guide: string;
readonly gettingStarted: string;
readonly ml: string;
readonly ruleChangeLog: string;
readonly detectionsReq: string;
readonly networkMap: string;
readonly troubleshootGaps: string;
};
readonly securitySolution: {
readonly trustedApps: string;
};
readonly query: {
readonly eql: string;
readonly kueryQuerySyntax: string;
readonly luceneQuerySyntax: string;
readonly percolate: string;
readonly queryDsl: string;
readonly autocompleteChanges: string;
};
readonly date: {
readonly dateMath: string;
readonly dateMathIndexNames: string;
};
readonly management: Record<string, string>;
readonly ml: Record<string, string>;
readonly transforms: Record<string, string>;
readonly visualize: Record<string, string>;
readonly apis: Readonly<{
bulkIndexAlias: string;
byteSizeUnits: string;
createAutoFollowPattern: string;
createFollower: string;
createIndex: string;
createSnapshotLifecyclePolicy: string;
createRoleMapping: string;
createRoleMappingTemplates: string;
createRollupJobsRequest: string;
createApiKey: string;
createPipeline: string;
createTransformRequest: string;
cronExpressions: string;
executeWatchActionModes: string;
indexExists: string;
openIndex: string;
putComponentTemplate: string;
painlessExecute: string;
painlessExecuteAPIContexts: string;
putComponentTemplateMetadata: string;
putSnapshotLifecyclePolicy: string;
putIndexTemplateV1: string;
putWatch: string;
simulatePipeline: string;
timeUnits: string;
updateTransform: string;
}>;
readonly observability: Readonly<{
guide: string;
infrastructureThreshold: string;
logsThreshold: string;
metricsThreshold: string;
monitorStatus: string;
monitorUptime: string;
tlsCertificate: string;
uptimeDurationAnomaly: string;
}>;
readonly alerting: Record<string, string>;
readonly maps: Record<string, string>;
readonly monitoring: Record<string, string>;
readonly security: Readonly<{
apiKeyServiceSettings: string;
clusterPrivileges: string;
elasticsearchSettings: string;
elasticsearchEnableSecurity: string;
indicesPrivileges: string;
kibanaTLS: string;
kibanaPrivileges: string;
mappingRoles: string;
mappingRolesFieldRules: string;
runAsPrivilege: string;
}>;
readonly spaces: Readonly<{
kibanaLegacyUrlAliases: string;
kibanaDisableLegacyUrlAliasesApi: string;
}>;
readonly watcher: Record<string, string>;
readonly ccs: Record<string, string>;
readonly plugins: Record<string, string>;
readonly snapshotRestore: Record<string, string>;
readonly ingest: Record<string, string>;
readonly fleet: Readonly<{
guide: string;
fleetServer: string;
fleetServerAddFleetServer: string;
settings: string;
settingsFleetServerHostSettings: string;
troubleshooting: string;
elasticAgent: string;
datastreams: string;
datastreamsNamingScheme: string;
installElasticAgent: string;
upgradeElasticAgent: string;
upgradeElasticAgent712lower: string;
learnMoreBlog: string;
apiKeysLearnMore: string;
}>;
readonly ecs: {
readonly guide: string;
};
readonly clients: {
readonly guide: string;
readonly goOverview: string;
readonly javaIndex: string;
readonly jsIntro: string;
readonly netGuide: string;
readonly perlGuide: string;
readonly phpGuide: string;
readonly pythonGuide: string;
readonly rubyOverview: string;
readonly rustGuide: string;
};
} | | +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | {
readonly settings: string;
readonly elasticStackGetStarted: string;
readonly apm: {
readonly kibanaSettings: string;
readonly supportedServiceMaps: string;
readonly customLinks: string;
readonly droppedTransactionSpans: string;
readonly upgrading: string;
readonly metaData: string;
};
readonly canvas: {
readonly guide: string;
};
readonly dashboard: {
readonly guide: string;
readonly drilldowns: string;
readonly drilldownsTriggerPicker: string;
readonly urlDrilldownTemplateSyntax: string;
readonly urlDrilldownVariables: string;
};
readonly discover: Record<string, string>;
readonly filebeat: {
readonly base: string;
readonly installation: string;
readonly configuration: string;
readonly elasticsearchOutput: string;
readonly elasticsearchModule: string;
readonly startup: string;
readonly exportedFields: string;
readonly suricataModule: string;
readonly zeekModule: string;
};
readonly auditbeat: {
readonly base: string;
readonly auditdModule: string;
readonly systemModule: string;
};
readonly metricbeat: {
readonly base: string;
readonly configure: string;
readonly httpEndpoint: string;
readonly install: string;
readonly start: string;
};
readonly enterpriseSearch: {
readonly base: string;
readonly appSearchBase: string;
readonly workplaceSearchBase: string;
};
readonly heartbeat: {
readonly base: string;
};
readonly libbeat: {
readonly getStarted: string;
};
readonly logstash: {
readonly base: string;
};
readonly functionbeat: {
readonly base: string;
};
readonly winlogbeat: {
readonly base: string;
};
readonly aggs: {
readonly composite: string;
readonly composite_missing_bucket: string;
readonly date_histogram: string;
readonly date_range: string;
readonly date_format_pattern: string;
readonly filter: string;
readonly filters: string;
readonly geohash_grid: string;
readonly histogram: string;
readonly ip_range: string;
readonly range: string;
readonly significant_terms: string;
readonly terms: string;
readonly avg: string;
readonly avg_bucket: string;
readonly max_bucket: string;
readonly min_bucket: string;
readonly sum_bucket: string;
readonly cardinality: string;
readonly count: string;
readonly cumulative_sum: string;
readonly derivative: string;
readonly geo_bounds: string;
readonly geo_centroid: string;
readonly max: string;
readonly median: string;
readonly min: string;
readonly moving_avg: string;
readonly percentile_ranks: string;
readonly serial_diff: string;
readonly std_dev: string;
readonly sum: string;
readonly top_hits: string;
};
readonly runtimeFields: {
readonly overview: string;
readonly mapping: string;
};
readonly scriptedFields: {
readonly scriptFields: string;
readonly scriptAggs: string;
readonly painless: string;
readonly painlessApi: string;
readonly painlessLangSpec: string;
readonly painlessSyntax: string;
readonly painlessWalkthrough: string;
readonly luceneExpressions: string;
};
readonly search: {
readonly sessions: string;
readonly sessionLimits: string;
};
readonly indexPatterns: {
readonly introduction: string;
readonly fieldFormattersNumber: string;
readonly fieldFormattersString: string;
readonly runtimeFields: string;
};
readonly addData: string;
readonly kibana: string;
readonly upgradeAssistant: string;
readonly rollupJobs: string;
readonly elasticsearch: Record<string, string>;
readonly siem: {
readonly privileges: string;
readonly guide: string;
readonly gettingStarted: string;
readonly ml: string;
readonly ruleChangeLog: string;
readonly detectionsReq: string;
readonly networkMap: string;
readonly troubleshootGaps: string;
};
readonly securitySolution: {
readonly trustedApps: string;
};
readonly query: {
readonly eql: string;
readonly kueryQuerySyntax: string;
readonly luceneQuerySyntax: string;
readonly percolate: string;
readonly queryDsl: string;
readonly autocompleteChanges: string;
};
readonly date: {
readonly dateMath: string;
readonly dateMathIndexNames: string;
};
readonly management: Record<string, string>;
readonly ml: Record<string, string>;
readonly transforms: Record<string, string>;
readonly visualize: Record<string, string>;
readonly apis: Readonly<{
bulkIndexAlias: string;
byteSizeUnits: string;
createAutoFollowPattern: string;
createFollower: string;
createIndex: string;
createSnapshotLifecyclePolicy: string;
createRoleMapping: string;
createRoleMappingTemplates: string;
createRollupJobsRequest: string;
createApiKey: string;
createPipeline: string;
createTransformRequest: string;
cronExpressions: string;
executeWatchActionModes: string;
indexExists: string;
openIndex: string;
putComponentTemplate: string;
painlessExecute: string;
painlessExecuteAPIContexts: string;
putComponentTemplateMetadata: string;
putSnapshotLifecyclePolicy: string;
putIndexTemplateV1: string;
putWatch: string;
simulatePipeline: string;
timeUnits: string;
updateTransform: string;
}>;
readonly observability: Readonly<{
guide: string;
infrastructureThreshold: string;
logsThreshold: string;
metricsThreshold: string;
monitorStatus: string;
monitorUptime: string;
tlsCertificate: string;
uptimeDurationAnomaly: string;
}>;
readonly alerting: Record<string, string>;
readonly maps: Record<string, string>;
readonly monitoring: Record<string, string>;
readonly security: Readonly<{
apiKeyServiceSettings: string;
clusterPrivileges: string;
elasticsearchSettings: string;
elasticsearchEnableSecurity: string;
elasticsearchEnableApiKeys: string;
indicesPrivileges: string;
kibanaTLS: string;
kibanaPrivileges: string;
mappingRoles: string;
mappingRolesFieldRules: string;
runAsPrivilege: string;
}>;
readonly spaces: Readonly<{
kibanaLegacyUrlAliases: string;
kibanaDisableLegacyUrlAliasesApi: string;
}>;
readonly watcher: Record<string, string>;
readonly ccs: Record<string, string>;
readonly plugins: Record<string, string>;
readonly snapshotRestore: Record<string, string>;
readonly ingest: Record<string, string>;
readonly fleet: Readonly<{
datastreamsILM: string;
guide: string;
fleetServer: string;
fleetServerAddFleetServer: string;
settings: string;
settingsFleetServerHostSettings: string;
troubleshooting: string;
elasticAgent: string;
datastreams: string;
datastreamsNamingScheme: string;
installElasticAgent: string;
upgradeElasticAgent: string;
upgradeElasticAgent712lower: string;
learnMoreBlog: string;
apiKeysLearnMore: string;
}>;
readonly ecs: {
readonly guide: string;
};
readonly clients: {
readonly guide: string;
readonly goOverview: string;
readonly javaIndex: string;
readonly jsIntro: string;
readonly netGuide: string;
readonly perlGuide: string;
readonly phpGuide: string;
readonly pythonGuide: string;
readonly rubyOverview: string;
readonly rustGuide: string;
};
} | | diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 20757463737fc9..2bbb4703ecd19d 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -480,6 +480,7 @@ export class DocLinksService { troubleshooting: `${FLEET_DOCS}fleet-troubleshooting.html`, elasticAgent: `${FLEET_DOCS}elastic-agent-installation.html`, datastreams: `${FLEET_DOCS}data-streams.html`, + datastreamsILM: `${FLEET_DOCS}data-streams.html#data-streams-ilm`, datastreamsNamingScheme: `${FLEET_DOCS}data-streams.html#data-streams-naming-scheme`, installElasticAgent: `${FLEET_DOCS}install-fleet-managed-elastic-agent.html`, upgradeElasticAgent: `${FLEET_DOCS}upgrade-elastic-agent.html`, @@ -734,6 +735,7 @@ export interface DocLinksStart { readonly snapshotRestore: Record; readonly ingest: Record; readonly fleet: Readonly<{ + datastreamsILM: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 353e5aa4607e4b..bd274d7994bfa7 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -698,6 +698,7 @@ export interface DocLinksStart { readonly snapshotRestore: Record; readonly ingest: Record; readonly fleet: Readonly<{ + datastreamsILM: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; diff --git a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_define_package_policy.tsx b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_define_package_policy.tsx index 29c226ca64f57e..e11aaabb4fd951 100644 --- a/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_define_package_policy.tsx +++ b/x-pack/plugins/fleet/public/applications/fleet/sections/agent_policy/create_package_policy_page/step_define_package_policy.tsx @@ -312,6 +312,34 @@ export const StepDefinePackagePolicy: React.FunctionComponent<{ />
+ + + } + helpText={ + + {i18n.translate( + 'xpack.fleet.createPackagePolicy.stepConfigure.packagePolicyDataRetentionLearnMoreLink', + { defaultMessage: 'Learn more' } + )} + + ), + }} + /> + } + > +
+ + {/* Advanced vars */} {advancedVars.map((varDef) => { const { name: varName, type: varType } = varDef; From 3a18a8226ff58d1cab59f67ca428d9d064a8b096 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Mon, 25 Oct 2021 19:55:16 +0100 Subject: [PATCH 39/66] skip flaky suite (#116186) --- x-pack/test/api_integration/apis/maps/get_grid_tile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/maps/get_grid_tile.js b/x-pack/test/api_integration/apis/maps/get_grid_tile.js index c37dc9770693cc..63063514555b31 100644 --- a/x-pack/test/api_integration/apis/maps/get_grid_tile.js +++ b/x-pack/test/api_integration/apis/maps/get_grid_tile.js @@ -12,7 +12,8 @@ import expect from '@kbn/expect'; export default function ({ getService }) { const supertest = getService('supertest'); - describe('getGridTile', () => { + // FLAKY: https://github.com/elastic/kibana/issues/116186 + describe.skip('getGridTile', () => { it('should return vector tile containing cluster features', async () => { const resp = await supertest .get( From 81264f73e931412a7c2f8e0fbdf9346ccf5735c0 Mon Sep 17 00:00:00 2001 From: Nathan L Smith Date: Mon, 25 Oct 2021 14:05:15 -0500 Subject: [PATCH 40/66] Re-enable APM E2E tests and allow server to shut down cleanly on failure (#115450) * Re-enable APM E2E tests and allow server to shut down cleanly on failure Calling `process.exit` in the test script made it so the FTR runner would not properly shut down the server, and cause other tests to fail because Kibana was left running on a port. Remove that and just throw instead. No changes were made to the tests, as I was unable to reproduce any failures locally. I'll try in CI and see if we can get anything to fail. Fixes #115280. --- .../scripts/pipelines/pull_request/pipeline.js | 12 ++++++------ .buildkite/scripts/steps/functional/apm_cypress.sh | 8 ++++++-- vars/tasks.groovy | 14 +++++++------- x-pack/plugins/apm/ftr_e2e/cypress_start.ts | 11 +++-------- x-pack/plugins/apm/scripts/test/e2e.js | 9 +++++++-- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.buildkite/scripts/pipelines/pull_request/pipeline.js b/.buildkite/scripts/pipelines/pull_request/pipeline.js index 7b5c944d31c1c0..02d6fc270ddb01 100644 --- a/.buildkite/scripts/pipelines/pull_request/pipeline.js +++ b/.buildkite/scripts/pipelines/pull_request/pipeline.js @@ -66,12 +66,12 @@ const uploadPipeline = (pipelineContent) => { pipeline.push(getPipeline('.buildkite/pipelines/pull_request/security_solution.yml')); } - // if ( - // (await doAnyChangesMatch([/^x-pack\/plugins\/apm/])) || - // process.env.GITHUB_PR_LABELS.includes('ci:all-cypress-suites') - // ) { - // pipeline.push(getPipeline('.buildkite/pipelines/pull_request/apm_cypress.yml')); - // } + if ( + (await doAnyChangesMatch([/^x-pack\/plugins\/apm/])) || + process.env.GITHUB_PR_LABELS.includes('ci:all-cypress-suites') + ) { + pipeline.push(getPipeline('.buildkite/pipelines/pull_request/apm_cypress.yml')); + } if (await doAnyChangesMatch([/^x-pack\/plugins\/uptime/])) { pipeline.push(getPipeline('.buildkite/pipelines/pull_request/uptime.yml')); diff --git a/.buildkite/scripts/steps/functional/apm_cypress.sh b/.buildkite/scripts/steps/functional/apm_cypress.sh index 800f22c78d14c2..77b26fafee9202 100755 --- a/.buildkite/scripts/steps/functional/apm_cypress.sh +++ b/.buildkite/scripts/steps/functional/apm_cypress.sh @@ -2,7 +2,10 @@ set -euo pipefail -source .buildkite/scripts/steps/functional/common.sh +source .buildkite/scripts/common/util.sh + +.buildkite/scripts/bootstrap.sh +.buildkite/scripts/download_build_artifacts.sh export JOB=kibana-apm-cypress @@ -11,4 +14,5 @@ echo "--- APM Cypress Tests" cd "$XPACK_DIR" checks-reporter-with-killswitch "APM Cypress Tests" \ - node plugins/apm/scripts/test/e2e.js + node plugins/apm/scripts/test/e2e.js \ + --kibana-install-dir "$KIBANA_BUILD_LOCATION" diff --git a/vars/tasks.groovy b/vars/tasks.groovy index da18d73e5b36c0..1842e278282b15 100644 --- a/vars/tasks.groovy +++ b/vars/tasks.groovy @@ -146,13 +146,13 @@ def functionalXpack(Map params = [:]) { } } - // whenChanged([ - // 'x-pack/plugins/apm/', - // ]) { - // if (githubPr.isPr()) { - // task(kibanaPipeline.functionalTestProcess('xpack-APMCypress', './test/scripts/jenkins_apm_cypress.sh')) - // } - // } + whenChanged([ + 'x-pack/plugins/apm/', + ]) { + if (githubPr.isPr()) { + task(kibanaPipeline.functionalTestProcess('xpack-APMCypress', './test/scripts/jenkins_apm_cypress.sh')) + } + } whenChanged([ 'x-pack/plugins/uptime/', diff --git a/x-pack/plugins/apm/ftr_e2e/cypress_start.ts b/x-pack/plugins/apm/ftr_e2e/cypress_start.ts index caf87d26274592..0cfc58653801a6 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress_start.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress_start.ts @@ -16,15 +16,10 @@ import { esArchiverLoad, esArchiverUnload } from './cypress/tasks/es_archiver'; export function cypressRunTests(spec?: string) { return async ({ getService }: FtrProviderContext) => { - try { - const result = await cypressStart(getService, cypress.run, spec); + const result = await cypressStart(getService, cypress.run, spec); - if (result && (result.status === 'failed' || result.totalFailed > 0)) { - process.exit(1); - } - } catch (error) { - console.error('errors: ', error); - process.exit(1); + if (result && (result.status === 'failed' || result.totalFailed > 0)) { + throw new Error(`APM Cypress tests failed`); } }; } diff --git a/x-pack/plugins/apm/scripts/test/e2e.js b/x-pack/plugins/apm/scripts/test/e2e.js index 629cdc24984146..b3ce510a8e569b 100644 --- a/x-pack/plugins/apm/scripts/test/e2e.js +++ b/x-pack/plugins/apm/scripts/test/e2e.js @@ -12,6 +12,11 @@ const yargs = require('yargs'); const childProcess = require('child_process'); const { argv } = yargs(process.argv.slice(2)) + .option('kibana-install-dir', { + default: '', + type: 'string', + description: 'Path to the Kibana install directory', + }) .option('server', { default: false, type: 'boolean', @@ -30,7 +35,7 @@ const { argv } = yargs(process.argv.slice(2)) }) .help(); -const { server, runner, open } = argv; +const { server, runner, open, kibanaInstallDir } = argv; const e2eDir = path.join(__dirname, '../../ftr_e2e'); @@ -44,6 +49,6 @@ if (server) { const config = open ? './cypress_open.ts' : './cypress_run.ts'; childProcess.execSync( - `node ../../../../scripts/${ftrScript} --config ${config}`, + `node ../../../../scripts/${ftrScript} --config ${config} --kibana-install-dir '${kibanaInstallDir}'`, { cwd: e2eDir, stdio: 'inherit' } ); From 0119bd8e4547b877fe98ba3ca214e5df8cde3c6a Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Mon, 25 Oct 2021 15:33:33 -0400 Subject: [PATCH 41/66] [Fleet] Remove unused authenticateAgentWithAccessToken method from agent service (#116183) --- x-pack/plugins/fleet/server/mocks/index.ts | 1 - x-pack/plugins/fleet/server/plugin.ts | 2 - .../services/agents/authenticate.test.ts | 156 ------------------ .../server/services/agents/authenticate.ts | 34 ---- .../fleet/server/services/agents/index.ts | 1 - x-pack/plugins/fleet/server/services/index.ts | 10 +- 6 files changed, 1 insertion(+), 203 deletions(-) delete mode 100644 x-pack/plugins/fleet/server/services/agents/authenticate.test.ts delete mode 100644 x-pack/plugins/fleet/server/services/agents/authenticate.ts diff --git a/x-pack/plugins/fleet/server/mocks/index.ts b/x-pack/plugins/fleet/server/mocks/index.ts index e6577426974a3f..9300e0bb6c3e18 100644 --- a/x-pack/plugins/fleet/server/mocks/index.ts +++ b/x-pack/plugins/fleet/server/mocks/index.ts @@ -114,7 +114,6 @@ export const createMockAgentService = (): jest.Mocked => { return { getAgentStatusById: jest.fn(), getAgentStatusForAgentPolicy: jest.fn(), - authenticateAgentWithAccessToken: jest.fn(), getAgent: jest.fn(), listAgents: jest.fn(), }; diff --git a/x-pack/plugins/fleet/server/plugin.ts b/x-pack/plugins/fleet/server/plugin.ts index 8a95065380b698..410682a13733cb 100644 --- a/x-pack/plugins/fleet/server/plugin.ts +++ b/x-pack/plugins/fleet/server/plugin.ts @@ -74,7 +74,6 @@ import { import { getAgentStatusById, getAgentStatusForAgentPolicy, - authenticateAgentWithAccessToken, getAgentsByKuery, getAgentById, } from './services/agents'; @@ -342,7 +341,6 @@ export class FleetPlugin listAgents: getAgentsByKuery, getAgentStatusById, getAgentStatusForAgentPolicy, - authenticateAgentWithAccessToken, }, agentPolicyService: { get: agentPolicyService.get, diff --git a/x-pack/plugins/fleet/server/services/agents/authenticate.test.ts b/x-pack/plugins/fleet/server/services/agents/authenticate.test.ts deleted file mode 100644 index eaa240165e8534..00000000000000 --- a/x-pack/plugins/fleet/server/services/agents/authenticate.test.ts +++ /dev/null @@ -1,156 +0,0 @@ -/* - * 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 type { KibanaRequest } from 'kibana/server'; -import { elasticsearchServiceMock } from 'src/core/server/mocks'; - -import { authenticateAgentWithAccessToken } from './authenticate'; - -describe('test agent autenticate services', () => { - it('should succeed with a valid API key and an active agent', async () => { - const mockEsClient = elasticsearchServiceMock.createInternalClient(); - - mockEsClient.search.mockResolvedValue({ - body: { - hits: { - hits: [ - { - // @ts-expect-error - _id: 'agent1', - _source: { - // @ts-expect-error - active: true, - // @ts-expect-error - access_api_key_id: 'pedTuHIBTEDt93wW0Fhr', - }, - }, - ], - }, - }, - }); - await authenticateAgentWithAccessToken(mockEsClient, { - auth: { isAuthenticated: true }, - headers: { - authorization: 'ApiKey cGVkVHVISUJURUR0OTN3VzBGaHI6TnU1U0JtbHJSeC12Rm9qQWpoSHlUZw==', - }, - } as KibanaRequest); - }); - - it('should throw if the request is not authenticated', async () => { - const mockEsClient = elasticsearchServiceMock.createInternalClient(); - - mockEsClient.search.mockResolvedValue({ - body: { - hits: { - hits: [ - { - // @ts-expect-error - _id: 'agent1', - _source: { - // @ts-expect-error - active: true, - // @ts-expect-error - access_api_key_id: 'pedTuHIBTEDt93wW0Fhr', - }, - }, - ], - }, - }, - }); - expect( - authenticateAgentWithAccessToken(mockEsClient, { - auth: { isAuthenticated: false }, - headers: { - authorization: 'ApiKey cGVkVHVISUJURUR0OTN3VzBGaHI6TnU1U0JtbHJSeC12Rm9qQWpoSHlUZw==', - }, - } as KibanaRequest) - ).rejects.toThrow(/Request not authenticated/); - }); - - it('should throw if the ApiKey headers is malformed', async () => { - const mockEsClient = elasticsearchServiceMock.createInternalClient(); - - const hits = [ - { - _id: 'agent1', - _source: { - active: true, - - access_api_key_id: 'pedTuHIBTEDt93wW0Fhr', - }, - }, - ]; - - mockEsClient.search.mockResolvedValue({ - body: { - hits: { - // @ts-expect-error - hits, - }, - }, - }); - expect( - authenticateAgentWithAccessToken(mockEsClient, { - auth: { isAuthenticated: true }, - headers: { - authorization: 'aaaa', - }, - } as KibanaRequest) - ).rejects.toThrow(/Authorization header is malformed/); - }); - - it('should throw if the agent is not active', async () => { - const mockEsClient = elasticsearchServiceMock.createInternalClient(); - - const hits = [ - { - _id: 'agent1', - _source: { - active: false, - access_api_key_id: 'pedTuHIBTEDt93wW0Fhr', - }, - }, - ]; - mockEsClient.search.mockResolvedValue({ - body: { - hits: { - // @ts-expect-error - hits, - }, - }, - }); - expect( - authenticateAgentWithAccessToken(mockEsClient, { - auth: { isAuthenticated: true }, - headers: { - authorization: 'ApiKey cGVkVHVISUJURUR0OTN3VzBGaHI6TnU1U0JtbHJSeC12Rm9qQWpoSHlUZw==', - }, - } as KibanaRequest) - ).rejects.toThrow(/Agent inactive/); - }); - - it('should throw if there is no agent matching the API key', async () => { - const mockEsClient = elasticsearchServiceMock.createInternalClient(); - - mockEsClient.search.mockResolvedValue({ - body: { - hits: { - // @ts-expect-error - hits: [], - }, - }, - }); - expect( - authenticateAgentWithAccessToken(mockEsClient, { - auth: { isAuthenticated: true }, - headers: { - authorization: 'ApiKey cGVkVHVISUJURUR0OTN3VzBGaHI6TnU1U0JtbHJSeC12Rm9qQWpoSHlUZw==', - }, - } as KibanaRequest) - ).rejects.toThrow(/Agent not found/); - }); -}); diff --git a/x-pack/plugins/fleet/server/services/agents/authenticate.ts b/x-pack/plugins/fleet/server/services/agents/authenticate.ts deleted file mode 100644 index 0d0d520528dad2..00000000000000 --- a/x-pack/plugins/fleet/server/services/agents/authenticate.ts +++ /dev/null @@ -1,34 +0,0 @@ -/* - * 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 Boom from '@hapi/boom'; -import type { KibanaRequest } from 'src/core/server'; -import type { ElasticsearchClient } from 'src/core/server'; - -import type { Agent } from '../../types'; -import * as APIKeyService from '../api_keys'; - -import { getAgentByAccessAPIKeyId } from './crud'; - -export async function authenticateAgentWithAccessToken( - esClient: ElasticsearchClient, - request: KibanaRequest -): Promise { - if (!request.auth.isAuthenticated) { - throw Boom.unauthorized('Request not authenticated'); - } - let res: { apiKey: string; apiKeyId: string }; - try { - res = APIKeyService.parseApiKeyFromHeaders(request.headers); - } catch (err) { - throw Boom.unauthorized(err.message); - } - - const agent = await getAgentByAccessAPIKeyId(esClient, res.apiKeyId); - - return agent; -} diff --git a/x-pack/plugins/fleet/server/services/agents/index.ts b/x-pack/plugins/fleet/server/services/agents/index.ts index ede548c6fd60d9..9b2846b68364e6 100644 --- a/x-pack/plugins/fleet/server/services/agents/index.ts +++ b/x-pack/plugins/fleet/server/services/agents/index.ts @@ -12,5 +12,4 @@ export * from './crud'; export * from './update'; export * from './actions'; export * from './reassign'; -export * from './authenticate'; export * from './setup'; diff --git a/x-pack/plugins/fleet/server/services/index.ts b/x-pack/plugins/fleet/server/services/index.ts index 0ec8a1452beb18..ab88e5af18efa9 100644 --- a/x-pack/plugins/fleet/server/services/index.ts +++ b/x-pack/plugins/fleet/server/services/index.ts @@ -5,10 +5,9 @@ * 2.0. */ -import type { KibanaRequest } from 'kibana/server'; import type { ElasticsearchClient, SavedObjectsClientContract } from 'kibana/server'; -import type { AgentStatus, Agent } from '../types'; +import type { AgentStatus } from '../types'; import type { GetAgentStatusResponse } from '../../common'; @@ -48,13 +47,6 @@ export interface AgentService { * Get an Agent by id */ getAgent: typeof getAgentById; - /** - * Authenticate an agent with access toekn - */ - authenticateAgentWithAccessToken( - esClient: ElasticsearchClient, - request: KibanaRequest - ): Promise; /** * Return the status by the Agent's id */ From 51f8feaea06f2c93d2a97ed0aa944bf918180f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Mon, 25 Oct 2021 22:25:01 +0200 Subject: [PATCH 42/66] Rename `apm-generator` to `apm-synthtrace` (#116075) --- api_docs/deprecations_by_api.mdx | 36 +- api_docs/deprecations_by_plugin.mdx | 101 +++--- api_docs/elastic_apm_generator.json | 288 ---------------- api_docs/elastic_apm_synthtrace.json | 321 ++++++++++++++++++ ...nerator.mdx => elastic_apm_synthtrace.mdx} | 16 +- api_docs/plugin_directory.mdx | 68 ++-- package.json | 2 +- packages/BUILD.bazel | 2 +- packages/elastic-apm-generator/README.md | 107 ------ .../BUILD.bazel | 4 +- packages/elastic-apm-synthtrace/README.md | 115 +++++++ .../jest.config.js | 2 +- .../package.json | 2 +- .../src/.eslintrc.js | 0 .../src/index.ts | 0 .../src/lib/apm_error.ts | 0 .../src/lib/base_span.ts | 0 .../src/lib/defaults/get_observer_defaults.ts | 0 .../src/lib/entity.ts | 0 .../src/lib/instance.ts | 0 .../src/lib/interval.ts | 0 .../src/lib/metricset.ts | 0 .../src/lib/output/to_elasticsearch_output.ts | 0 .../src/lib/serializable.ts | 0 .../src/lib/service.ts | 0 .../src/lib/span.ts | 0 .../src/lib/timerange.ts | 0 .../src/lib/transaction.ts | 0 .../src/lib/utils/aggregate.ts | 0 .../src/lib/utils/create_picker.ts | 0 .../src/lib/utils/generate_id.ts | 0 .../src/lib/utils/get_breakdown_metrics.ts | 0 .../lib/utils/get_span_destination_metrics.ts | 0 .../src/lib/utils/get_transaction_metrics.ts | 0 .../src/scripts/examples/01_simple_trace.ts | 0 .../src/scripts/run.js | 0 .../src/scripts/run.ts | 0 .../src/scripts/utils/clean_write_targets.ts | 0 .../src/scripts/utils/common_options.ts | 0 .../src/scripts/utils/get_common_resources.ts | 0 .../src/scripts/utils/get_scenario.ts | 0 .../src/scripts/utils/get_write_targets.ts | 0 .../src/scripts/utils/interval_to_ms.ts | 0 .../src/scripts/utils/logger.ts | 0 .../utils/start_historical_data_upload.ts | 0 .../scripts/utils/start_live_data_upload.ts | 0 .../src/scripts/utils/upload_events.ts | 0 .../test/scenarios/01_simple_trace.test.ts | 0 .../scenarios/02_transaction_metrics.test.ts | 0 .../03_span_destination_metrics.test.ts | 0 .../scenarios/04_breakdown_metrics.test.ts | 0 .../05_transactions_with_errors.test.ts | 0 .../scenarios/06_application_metrics.test.ts | 0 .../01_simple_trace.test.ts.snap | 0 .../src/test/to_elasticsearch_output.test.ts | 0 .../tsconfig.json | 11 +- .../apm_api_integration/common/trace_data.ts | 2 +- .../tests/error_rate/service_apis.ts | 2 +- .../tests/latency/service_apis.ts | 2 +- .../observability_overview.ts | 2 +- .../instances_main_statistics.ts | 2 +- .../tests/services/throughput.ts | 2 +- .../tests/throughput/dependencies_apis.ts | 2 +- .../tests/throughput/service_apis.ts | 2 +- ...transactions_groups_detailed_statistics.ts | 2 +- yarn.lock | 2 +- 66 files changed, 564 insertions(+), 531 deletions(-) delete mode 100644 api_docs/elastic_apm_generator.json create mode 100644 api_docs/elastic_apm_synthtrace.json rename api_docs/{elastic_apm_generator.mdx => elastic_apm_synthtrace.mdx} (63%) delete mode 100644 packages/elastic-apm-generator/README.md rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/BUILD.bazel (95%) create mode 100644 packages/elastic-apm-synthtrace/README.md rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/jest.config.js (89%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/package.json (85%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/.eslintrc.js (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/index.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/apm_error.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/base_span.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/defaults/get_observer_defaults.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/entity.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/instance.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/interval.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/metricset.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/output/to_elasticsearch_output.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/serializable.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/service.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/span.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/timerange.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/transaction.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/utils/aggregate.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/utils/create_picker.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/utils/generate_id.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/utils/get_breakdown_metrics.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/utils/get_span_destination_metrics.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/lib/utils/get_transaction_metrics.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/examples/01_simple_trace.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/run.js (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/run.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/clean_write_targets.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/common_options.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/get_common_resources.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/get_scenario.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/get_write_targets.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/interval_to_ms.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/logger.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/start_historical_data_upload.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/start_live_data_upload.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/scripts/utils/upload_events.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/test/scenarios/01_simple_trace.test.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/test/scenarios/02_transaction_metrics.test.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/test/scenarios/03_span_destination_metrics.test.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/test/scenarios/04_breakdown_metrics.test.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/test/scenarios/05_transactions_with_errors.test.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/test/scenarios/06_application_metrics.test.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/src/test/to_elasticsearch_output.test.ts (100%) rename packages/{elastic-apm-generator => elastic-apm-synthtrace}/tsconfig.json (60%) diff --git a/api_docs/deprecations_by_api.mdx b/api_docs/deprecations_by_api.mdx index 341a6b6b6bb335..fda6834f9b4e9c 100644 --- a/api_docs/deprecations_by_api.mdx +++ b/api_docs/deprecations_by_api.mdx @@ -16,9 +16,9 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | securitySolution | - | | | dataViews, visTypeTimeseries, reporting, discover, observability, maps, dataVisualizer, apm, lens, osquery, securitySolution, transform, savedObjects, indexPatternFieldEditor, visualizations, dashboard, graph, stackAlerts, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, savedObjectsManagement, visualize, visDefaultEditor, visTypeVega, data | - | | | dataViews, discover, maps, dataVisualizer, lens, indexPatternFieldEditor, securitySolution, indexPatternEditor, indexPatternManagement, inputControlVis, visDefaultEditor, visTypeTimeseries, data | - | -| | dataViews, timelines, monitoring, securitySolution, indexPatternManagement, stackAlerts, transform | - | -| | home, savedObjects, security, fleet, indexPatternFieldEditor, discover, visualizations, dashboard, lens, observability, maps, fileUpload, dataVisualizer, ml, infra, apm, graph, monitoring, osquery, securitySolution, stackAlerts, transform, upgradeAssistant, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, kibanaOverview, savedObjectsManagement, visualize, visTypeTimelion, visTypeTimeseries, visTypeVega | - | -| | dataViews, timelines, monitoring, securitySolution, indexPatternManagement, stackAlerts, transform, data | - | +| | dataViews, timelines, monitoring, securitySolution, indexPatternManagement, presentationUtil, stackAlerts, transform | - | +| | home, savedObjects, security, fleet, indexPatternFieldEditor, discover, dashboard, lens, observability, maps, fileUpload, dataVisualizer, ml, infra, graph, monitoring, osquery, securitySolution, stackAlerts, transform, upgradeAssistant, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, kibanaOverview, savedObjectsManagement, visualize, visTypeTimelion, visTypeTimeseries, visTypeVega | - | +| | dataViews, timelines, monitoring, securitySolution, indexPatternManagement, presentationUtil, stackAlerts, transform, data | - | | | dataViews, discover, maps, dataVisualizer, lens, indexPatternFieldEditor, securitySolution, indexPatternEditor, indexPatternManagement, inputControlVis, visDefaultEditor, visTypeTimeseries, data | - | | | dataViews, visTypeTimeseries, reporting, discover, observability, maps, dataVisualizer, apm, lens, osquery, securitySolution, transform, savedObjects, indexPatternFieldEditor, visualizations, dashboard, graph, stackAlerts, uptime, indexPatternEditor, indexPatternManagement, inputControlVis, savedObjectsManagement, visualize, visDefaultEditor, visTypeVega, data | - | | | dataViews, discover, maps, dataVisualizer, lens, indexPatternFieldEditor, securitySolution, indexPatternEditor, indexPatternManagement, inputControlVis, visDefaultEditor, visTypeTimeseries | - | @@ -29,27 +29,30 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | dashboard, lens, maps, ml, securitySolution, security, visualize | - | | | securitySolution | - | | | dataViews, visTypeTimeseries, maps, lens, discover, data | - | -| | dataViews, discover, observability, savedObjects, security, visualizations, dashboard, lens, maps, graph, stackAlerts, transform, indexPatternManagement, inputControlVis, savedObjectsManagement, visTypeTimelion, data | - | +| | dataViews, discover, observability, savedObjects, security, dashboard, lens, maps, graph, stackAlerts, transform, indexPatternManagement, inputControlVis, savedObjectsManagement, visTypeTimelion, data | - | | | dataViews, discover, transform, canvas | - | -| | dataViews, observability, indexPatternEditor, apm | - | +| | dataViews, observability, indexPatternEditor | - | | | dataViews | - | | | dataViews, indexPatternManagement | - | | | dataViews, discover, transform, canvas, data | - | | | dataViews, data | - | | | dataViews, data | - | | | dataViews | - | -| | dataViews, observability, indexPatternEditor, apm, data | - | +| | dataViews, observability, indexPatternEditor, data | - | | | dataViews, visualizations, dashboard, data | - | | | dataViews, data | - | | | dataViews, visTypeTimeseries, maps, lens, discover, data | - | -| | dataViews, discover, observability, savedObjects, security, visualizations, dashboard, lens, maps, graph, stackAlerts, transform, indexPatternManagement, inputControlVis, savedObjectsManagement, visTypeTimelion, data | - | +| | dataViews, discover, observability, savedObjects, security, dashboard, lens, maps, graph, stackAlerts, transform, indexPatternManagement, inputControlVis, savedObjectsManagement, visTypeTimelion, data | - | | | dataViews, discover, dashboard, lens, visualize | - | | | dataViews, indexPatternManagement, data | - | +| | dataViews, maps | - | | | dataViews, discover, transform, canvas | - | | | dataViews, visTypeTimeseries, maps, lens, discover | - | +| | dataViews, maps | - | | | fleet, indexPatternFieldEditor, discover, dashboard, lens, ml, stackAlerts, indexPatternManagement, visTypePie, visTypeTable, visTypeTimeseries, visTypeXy, visTypeVislib | - | | | reporting, visTypeTimeseries | - | | | data, lens, visTypeTimeseries, infra, maps, visTypeTimelion | - | +| | maps | - | | | dashboard, maps, graph, visualize | - | | | spaces, security, reporting, actions, alerting, ml, fleet, remoteClusters, graph, indexLifecycleManagement, maps, painlessLab, rollup, searchprofiler, snapshotRestore, transform, upgradeAssistant | - | | | discover, dashboard, lens, visualize | - | @@ -57,9 +60,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | discover | - | | | discover | - | | | embeddable, presentationUtil, discover, dashboard, graph | - | -| | discover, visualizations, dashboard | - | -| | savedObjectsTaggingOss, discover, visualizations, dashboard | - | -| | discover, visualizations, dashboard | - | | | data, discover, embeddable | - | | | advancedSettings, discover | - | | | advancedSettings, discover | - | @@ -68,7 +68,9 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | security | - | | | security, licenseManagement, ml, fleet, apm, reporting, crossClusterReplication, logstash, painlessLab, searchprofiler, watcher | - | | | management, fleet, security, kibanaOverview | - | -| | visualizations | - | +| | dashboard | - | +| | savedObjectsTaggingOss, dashboard | - | +| | dashboard | - | | | spaces, savedObjectsManagement | - | | | spaces, savedObjectsManagement | - | | | reporting | - | @@ -103,14 +105,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | discover, visualizations, dashboard, lens, observability, timelines, maps, infra, dashboardEnhanced, discoverEnhanced, securitySolution, urlDrilldown, inputControlVis, visualize, visTypeTimelion, visTypeVega, ml, visTypeTimeseries | 8.1 | | | discover, visualizations, dashboard, lens, observability, timelines, maps, infra, dashboardEnhanced, discoverEnhanced, securitySolution, urlDrilldown, inputControlVis, visualize, visTypeTimelion, visTypeVega, ml, visTypeTimeseries | 8.1 | | | discover, visualizations, dashboard, lens, observability, timelines, maps, infra, dashboardEnhanced, discoverEnhanced, securitySolution, urlDrilldown, inputControlVis, visualize, visTypeTimelion, visTypeVega, ml, visTypeTimeseries | 8.1 | -| | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement | 8.1 | -| | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement, data | 8.1 | +| | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement, presentationUtil | 8.1 | +| | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement, presentationUtil, data | 8.1 | | | dataViews | 8.1 | | | dataViews | 8.1 | | | indexPatternManagement, dataViews | 8.1 | | | visTypeTimeseries, graph, indexPatternManagement, dataViews | 8.1 | | | dataViews, indexPatternManagement | 8.1 | -| | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement | 8.1 | +| | dataViews, fleet, infra, monitoring, stackAlerts, indexPatternManagement, presentationUtil | 8.1 | | | dataViews | 8.1 | | | dataViews | 8.1 | | | indexPatternManagement, dataViews | 8.1 | @@ -125,8 +127,6 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | lens, infra, apm, graph, monitoring, stackAlerts, transform | 8.1 | | | observability | 8.1 | | | observability | 8.1 | -| | visualizations, visDefaultEditor | 8.1 | -| | visualizations, visDefaultEditor | 8.1 | | | indexPatternManagement | 8.1 | | | indexPatternManagement | 8.1 | | | indexPatternManagement | 8.1 | @@ -136,6 +136,8 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | indexPatternFieldEditor | 8.1 | | | indexPatternFieldEditor | 8.1 | | | indexPatternFieldEditor | 8.1 | +| | visualizations, visDefaultEditor | 8.1 | +| | visualizations, visDefaultEditor | 8.1 | | | visualize | 8.1 | | | timelines | 8.1 | | | timelines | 8.1 | @@ -214,8 +216,6 @@ Safe to remove. | | | | | | -| | -| | | | | | | | diff --git a/api_docs/deprecations_by_plugin.mdx b/api_docs/deprecations_by_plugin.mdx index 7ef3a75269963d..d405da72f959cf 100644 --- a/api_docs/deprecations_by_plugin.mdx +++ b/api_docs/deprecations_by_plugin.mdx @@ -48,19 +48,16 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPattern), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPattern)+ 4 more | - | -| | [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPatternSpec), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPatternSpec) | - | -| | [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=indexPatterns) | - | +| | [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern) | - | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=esKuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=esKuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=esKuery) | 8.1 | -| | [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPatternSpec), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPatternSpec), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPatternSpec), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPatternSpec) | - | -| | [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPattern), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPattern)+ 4 more | - | -| | [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPattern), [use_index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/use_index_pattern.ts#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/shared/kuery_bar/index.tsx#:~:text=IndexPattern) | - | +| | [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern) | - | +| | [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [SelectedFilters.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/SelectedFilters.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern), [selected_wildcards.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/components/app/RumDashboard/LocalUIFilters/selected_wildcards.tsx#:~:text=IndexPattern) | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/plugin.ts#:~:text=environment) | - | | | [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode)+ 2 more | - | | | [license_context.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/public/context/license/license_context.tsx#:~:text=license%24) | - | | | [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode), [license_check.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/common/license_check.test.ts#:~:text=mode)+ 2 more | - | -| | [index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/server/routes/index_pattern.ts#:~:text=spacesService) | 7.16 | -| | [index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/server/routes/index_pattern.ts#:~:text=getSpaceId) | 7.16 | +| | [data_view.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/server/routes/data_view.ts#:~:text=spacesService) | 7.16 | +| | [data_view.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/apm/server/routes/data_view.ts#:~:text=getSpaceId) | 7.16 | @@ -228,6 +225,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern) | - | | | [data_views.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_views.ts#:~:text=IndexPatternListItem), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternListItem) | - | | | [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [update_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/server/routes/update_index_pattern.ts#:~:text=intervalName), [update_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/server/routes/update_index_pattern.ts#:~:text=intervalName) | 8.1 | +| | [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=flattenHit) | - | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=addScriptedField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=addScriptedField) | 8.1 | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=removeScriptedField) | 8.1 | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getNonScriptedFields) | 8.1 | @@ -238,6 +236,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [data_view_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/fields/data_view_field.test.ts#:~:text=IndexPattern), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=IndexPattern) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/index.ts#:~:text=IndexPatternsService), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/public/index.ts#:~:text=IndexPatternsService) | - | | | [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=intervalName), [update_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/server/routes/update_index_pattern.ts#:~:text=intervalName), [update_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/server/routes/update_index_pattern.ts#:~:text=intervalName) | 8.1 | +| | [data_view.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.ts#:~:text=flattenHit) | - | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=addScriptedField), [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=addScriptedField) | 8.1 | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=removeScriptedField) | 8.1 | | | [data_view.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/data_views/common/data_views/data_view.test.ts#:~:text=getNonScriptedFields) | 8.1 | @@ -250,11 +249,11 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts#:~:text=IndexPattern), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts#:~:text=IndexPattern), [geo_point_content_with_map.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx#:~:text=IndexPattern), [geo_point_content_with_map.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx#:~:text=IndexPattern), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPattern), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPattern)+ 60 more | - | -| | [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField)+ 16 more | - | +| | [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField)+ 20 more | - | | | [file_data_visualizer.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/file_data_visualizer/file_data_visualizer.tsx#:~:text=indexPatterns), [index_data_visualizer.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/index_data_visualizer.tsx#:~:text=indexPatterns) | - | -| | [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField)+ 16 more | - | +| | [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField)+ 20 more | - | | | [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts#:~:text=IndexPattern), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts#:~:text=IndexPattern), [geo_point_content_with_map.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx#:~:text=IndexPattern), [geo_point_content_with_map.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx#:~:text=IndexPattern), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPattern), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPattern)+ 60 more | - | -| | [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField)+ 3 more | - | +| | [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_data_row.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/stats_table/types/field_data_row.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [field_types_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/util/field_types_utils.ts#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [search_panel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/search_panel/search_panel.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField), [index_data_visualizer_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/index_data_visualizer/components/index_data_visualizer_view/index_data_visualizer_view.tsx#:~:text=IndexPatternField)+ 5 more | - | | | [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [lens_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/lens_utils.ts#:~:text=IndexPattern), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts#:~:text=IndexPattern), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/field_data_row/action_menu/actions.ts#:~:text=IndexPattern), [geo_point_content_with_map.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx#:~:text=IndexPattern), [geo_point_content_with_map.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/geo_point_content_with_map/geo_point_content_with_map.tsx#:~:text=IndexPattern), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPattern), [index_based_expanded_row.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/data_visualizer/public/application/common/components/expanded_row/index_based_expanded_row.tsx#:~:text=IndexPattern)+ 25 more | - | @@ -264,38 +263,35 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService)+ 6 more | - | -| | [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract)+ 34 more | - | -| | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 378 more | - | -| | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField)+ 192 more | - | +| | [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract)+ 26 more | - | +| | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 382 more | - | +| | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField)+ 198 more | - | | | [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes)+ 3 more | - | | | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=create), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=create) | - | | | [anchor.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/services/anchor.ts#:~:text=fetch), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/services/utils/fetch_hits_in_interval.ts#:~:text=fetch) | 8.1 | -| | [build_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/build_services.ts#:~:text=indexPatterns), [source_viewer.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/source_viewer/source_viewer.tsx#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=indexPatterns) | - | +| | [build_services.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/build_services.ts#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=indexPatterns), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=indexPatterns) | - | | | [histogram.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/chart/histogram.tsx#:~:text=fieldFormats) | - | | | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=esFilters), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=esFilters), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=esFilters), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=esFilters), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=esFilters), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=esFilters), [get_context_url.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/get_context_url.tsx#:~:text=esFilters), [get_context_url.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/get_context_url.tsx#:~:text=esFilters), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=esFilters), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=esFilters)+ 17 more | 8.1 | | | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 22 more | 8.1 | | | [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes)+ 16 more | - | -| | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField)+ 192 more | - | +| | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField)+ 198 more | - | | | [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService)+ 6 more | - | -| | [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract)+ 34 more | - | +| | [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_data_grid_columns.ts#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [use_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/use_index_pattern.tsx#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/utils/resolve_index_pattern.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [use_data_grid_columns.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/helpers/use_data_grid_columns.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract), [resolve_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/utils/resolve_index_pattern.d.ts#:~:text=IndexPatternsContract)+ 26 more | - | | | [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=ensureDefaultDataView), [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=ensureDefaultDataView) | - | -| | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 378 more | - | +| | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 382 more | - | | | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 22 more | 8.1 | | | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=create), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=create) | - | | | [anchor.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/services/anchor.ts#:~:text=fetch), [fetch_hits_in_interval.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/services/utils/fetch_hits_in_interval.ts#:~:text=fetch) | 8.1 | -| | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField), [discover_field_visualize.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_field_visualize.tsx#:~:text=IndexPatternField)+ 91 more | - | +| | [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [discover_grid_cell_actions.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_cell_actions.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [doc_table_wrapper.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/doc_table_wrapper.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [data_visualizer_grid.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/data_visualizer_grid/data_visualizer_grid.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=IndexPatternField), [context_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/context/context_app.tsx#:~:text=IndexPatternField)+ 94 more | - | | | [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_index_pattern.tsx#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_index_pattern.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/apps/main/components/sidebar/discover_index_pattern.d.ts#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [discover_sidebar_responsive.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/layout/types.ts#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes), [discover_main_app.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_app.tsx#:~:text=IndexPatternAttributes)+ 3 more | - | -| | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 184 more | - | +| | [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/doc_table/components/table_header/helpers.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_flyout.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_flyout.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [discover_grid_context.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_context.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [get_render_cell_value.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/get_render_cell_value.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern), [discover_grid_columns.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/components/discover_grid/discover_grid_columns.tsx#:~:text=IndexPattern)+ 186 more | - | | | [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [popularize_field.test.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/helpers/popularize_field.test.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService), [index_patterns.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/__mocks__/index_patterns.ts#:~:text=IndexPatternsService)+ 6 more | - | | | [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [url_generator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/url_generator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [locator.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/locator.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/types.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter), [discover_state.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/services/discover_state.ts#:~:text=Filter)+ 22 more | 8.1 | | | [discover_main_route.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/discover_main_route.tsx#:~:text=ensureDefaultDataView) | - | | | [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal), [on_save_search.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/apps/main/components/top_nav/on_save_search.tsx#:~:text=SavedObjectSaveModal) | - | -| | [saved_searches.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/saved_searches.ts#:~:text=SavedObjectLoader), [saved_searches.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/saved_searches.ts#:~:text=SavedObjectLoader), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=SavedObjectLoader), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=SavedObjectLoader) | - | -| | [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/_saved_search.ts#:~:text=SavedObject), [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/_saved_search.ts#:~:text=SavedObject) | - | -| | [_saved_search.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/saved_searches/legacy/_saved_search.ts#:~:text=SavedObjectClass) | - | | | [saved_search_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/saved_search_embeddable.tsx#:~:text=executeTriggerActions), [search_embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/application/embeddable/search_embeddable_factory.ts#:~:text=executeTriggerActions), [plugin.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/discover/public/plugin.tsx#:~:text=executeTriggerActions), [search_embeddable_factory.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/target/types/public/application/embeddable/search_embeddable_factory.d.ts#:~:text=executeTriggerActions) | - | -| | [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric), [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric) | - | -| | [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric), [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric) | - | +| | [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric), [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric), [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric) | - | +| | [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric), [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric), [ui_settings.ts](https://github.com/elastic/kibana/tree/master/src/plugins/discover/server/ui_settings.ts#:~:text=metric) | - | @@ -443,7 +439,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IFieldType), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IFieldType), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IFieldType) | 8.1 | | | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IndexPatternListItem), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IndexPatternListItem), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IndexPatternListItem), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IndexPatternListItem), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IndexPatternListItem), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IndexPatternListItem), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IndexPatternListItem), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IndexPatternListItem) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/constants/index.ts#:~:text=getKbnTypeNames), [index.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/constants/index.ts#:~:text=getKbnTypeNames) | 8.1 | -| | [edit_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx#:~:text=indexPatterns), [edit_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx#:~:text=indexPatterns), [edit_index_pattern_container.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx#:~:text=indexPatterns), [edit_index_pattern_container.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx#:~:text=indexPatterns), [create_edit_field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx#:~:text=indexPatterns), [create_edit_field_container.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx#:~:text=indexPatterns), [create_edit_field_container.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx#:~:text=indexPatterns) | - | +| | [scripted_fields_table.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/scripted_fields_table/scripted_fields_table.tsx#:~:text=indexPatterns), [tabs.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/tabs.tsx#:~:text=indexPatterns), [edit_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx#:~:text=indexPatterns), [edit_index_pattern.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern.tsx#:~:text=indexPatterns), [edit_index_pattern_container.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx#:~:text=indexPatterns), [edit_index_pattern_container.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/edit_index_pattern_container.tsx#:~:text=indexPatterns), [create_edit_field.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field.tsx#:~:text=indexPatterns), [create_edit_field_container.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx#:~:text=indexPatterns), [create_edit_field_container.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/edit_index_pattern/create_edit_field/create_edit_field_container.tsx#:~:text=indexPatterns) | - | | | [field_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx#:~:text=fieldFormats), [field_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx#:~:text=fieldFormats), [field_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx#:~:text=fieldFormats), [field_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx#:~:text=fieldFormats), [field_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx#:~:text=fieldFormats), [field_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/field_editor.tsx#:~:text=fieldFormats) | - | | | [test_script.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx#:~:text=esQuery), [test_script.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx#:~:text=esQuery), [test_script.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/field_editor/components/scripting_help/test_script.tsx#:~:text=esQuery) | 8.1 | | | [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IFieldType), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IFieldType), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IFieldType), [utils.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/public/components/utils.ts#:~:text=IFieldType), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IFieldType), [utils.d.ts](https://github.com/elastic/kibana/tree/master/src/plugins/index_pattern_management/target/types/public/components/utils.d.ts#:~:text=IFieldType) | 8.1 | @@ -541,18 +537,18 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| | | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService) | - | -| | [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract)+ 20 more | - | +| | [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract)+ 22 more | - | | | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPattern), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts#:~:text=IndexPattern), [existing_fields.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts#:~:text=IndexPattern), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPattern), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPattern)+ 36 more | - | | | [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField)+ 8 more | - | | | [datapanel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx#:~:text=indexPatterns), [datapanel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx#:~:text=indexPatterns), [datapanel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx#:~:text=indexPatterns), [datapanel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx#:~:text=indexPatterns), [indexpattern.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern.tsx#:~:text=indexPatterns), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=indexPatterns), [lens_top_nav.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/lens_top_nav.tsx#:~:text=indexPatterns), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/plugin.ts#:~:text=indexPatterns), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/plugin.ts#:~:text=indexPatterns) | - | | | [ranges.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/ranges/ranges.tsx#:~:text=fieldFormats), [droppable.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/droppable/droppable.test.ts#:~:text=fieldFormats) | - | -| | [save_modal_container.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx#:~:text=esFilters), [save_modal_container.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx#:~:text=esFilters), [mocks.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/mocks.tsx#:~:text=esFilters), [mocks.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/mocks.tsx#:~:text=esFilters) | 8.1 | +| | [save_modal_container.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx#:~:text=esFilters), [save_modal_container.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/app_plugin/save_modal_container.tsx#:~:text=esFilters), [data_plugin_mock.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/mocks/data_plugin_mock.ts#:~:text=esFilters), [data_plugin_mock.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/mocks/data_plugin_mock.ts#:~:text=esFilters) | 8.1 | | | [validation.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/validation.ts#:~:text=esKuery), [validation.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/validation.ts#:~:text=esKuery), [validation.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/validation.ts#:~:text=esKuery) | 8.1 | | | [validation.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/validation.ts#:~:text=esQuery), [validation.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/validation.ts#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/terms/index.tsx#:~:text=esQuery), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=esQuery), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=esQuery), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=esQuery), [datapanel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx#:~:text=esQuery), [datapanel.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx#:~:text=esQuery)+ 1 more | 8.1 | | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/state_management/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/state_management/types.ts#:~:text=Filter), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=Filter), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=Filter)+ 16 more | 8.1 | | | [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/field_stats.d.ts#:~:text=IndexPatternField), [field_stats.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/field_stats.ts#:~:text=IndexPatternField)+ 8 more | - | | | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPatternsService) | - | -| | [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract)+ 20 more | - | +| | [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/utils.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [embeddable_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable_factory.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract), [loader.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.test.ts#:~:text=IndexPatternsContract)+ 22 more | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/plugin.ts#:~:text=ensureDefaultDataView), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/plugin.ts#:~:text=ensureDefaultDataView) | - | | | [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPattern), [existing_fields.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/server/routes/existing_fields.test.ts#:~:text=IndexPattern), [existing_fields.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts#:~:text=IndexPattern), [existing_fields.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/target/types/server/routes/existing_fields.d.ts#:~:text=IndexPattern), [loader.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts#:~:text=IndexPattern), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=IndexPattern)+ 36 more | - | | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/types.ts#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [embeddable.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/embeddable/embeddable.tsx#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/state_management/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/state_management/types.ts#:~:text=Filter), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=Filter), [field_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/lens/public/indexpattern_datasource/field_item.tsx#:~:text=Filter)+ 16 more | 8.1 | @@ -608,12 +604,15 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=IndexPatternsService), [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=IndexPatternsService), [create_doc_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts#:~:text=IndexPatternsService), [create_doc_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts#:~:text=IndexPatternsService), [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=IndexPatternsService), [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=IndexPatternsService), [create_doc_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts#:~:text=IndexPatternsService), [create_doc_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts#:~:text=IndexPatternsService) | - | | | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/target/types/public/lazy_load_bundle/index.d.ts#:~:text=IndexPatternsContract), [index.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/target/types/public/lazy_load_bundle/index.d.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/lazy_load_bundle/index.ts#:~:text=IndexPatternsContract), [index.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/target/types/public/lazy_load_bundle/index.d.ts#:~:text=IndexPatternsContract), [index.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/target/types/public/lazy_load_bundle/index.d.ts#:~:text=IndexPatternsContract) | - | | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/embeddable/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/embeddable/types.ts#:~:text=IndexPattern), [es_agg_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts#:~:text=IndexPattern), [es_agg_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts#:~:text=IndexPattern), [agg_field_types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts#:~:text=IndexPattern), [agg_field_types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts#:~:text=IndexPattern), [percentile_agg_field.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts#:~:text=IndexPattern), [percentile_agg_field.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts#:~:text=IndexPattern), [es_geo_grid_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx#:~:text=IndexPattern), [es_geo_grid_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx#:~:text=IndexPattern)+ 206 more | - | +| | [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit) | - | | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/reducers/map/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/reducers/map/types.ts#:~:text=Filter), [tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts#:~:text=Filter), [tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts#:~:text=Filter), [tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts#:~:text=Filter), [tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts#:~:text=Filter), [vector_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx#:~:text=Filter), [vector_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx#:~:text=Filter), [es_tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts#:~:text=Filter), [es_tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts#:~:text=Filter)+ 115 more | 8.1 | | | [es_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_source/es_source.ts#:~:text=fetch), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=fetch), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=fetch) | 8.1 | | | [es_agg_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts#:~:text=IndexPatternField), [es_agg_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts#:~:text=IndexPatternField), [es_agg_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts#:~:text=IndexPatternField), [es_agg_utils.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/target/types/common/elasticsearch_util/es_agg_utils.d.ts#:~:text=IndexPatternField), [es_agg_utils.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/target/types/common/elasticsearch_util/es_agg_utils.d.ts#:~:text=IndexPatternField), [es_agg_utils.d.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/target/types/common/elasticsearch_util/es_agg_utils.d.ts#:~:text=IndexPatternField), [es_tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts#:~:text=IndexPatternField), [es_tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts#:~:text=IndexPatternField), [es_doc_field.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/es_doc_field.ts#:~:text=IndexPatternField), [es_doc_field.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/es_doc_field.ts#:~:text=IndexPatternField)+ 129 more | - | | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/embeddable/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/embeddable/types.ts#:~:text=IndexPattern), [es_agg_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts#:~:text=IndexPattern), [es_agg_utils.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/common/elasticsearch_util/es_agg_utils.ts#:~:text=IndexPattern), [agg_field_types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts#:~:text=IndexPattern), [agg_field_types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/agg_field_types.ts#:~:text=IndexPattern), [percentile_agg_field.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts#:~:text=IndexPattern), [percentile_agg_field.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/fields/agg/percentile_agg_field.ts#:~:text=IndexPattern), [es_geo_grid_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx#:~:text=IndexPattern), [es_geo_grid_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_geo_grid_source/es_geo_grid_source.tsx#:~:text=IndexPattern)+ 98 more | - | | | [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=IndexPatternsService), [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=IndexPatternsService), [create_doc_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts#:~:text=IndexPatternsService), [create_doc_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts#:~:text=IndexPatternsService), [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=IndexPatternsService), [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=IndexPatternsService), [create_doc_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts#:~:text=IndexPatternsService), [create_doc_source.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/create_doc_source.ts#:~:text=IndexPatternsService) | - | +| | [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit) | - | | | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/reducers/map/types.ts#:~:text=Filter), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/reducers/map/types.ts#:~:text=Filter), [tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts#:~:text=Filter), [tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts#:~:text=Filter), [tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts#:~:text=Filter), [tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/tooltip_property.ts#:~:text=Filter), [vector_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx#:~:text=Filter), [vector_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/vector_source/vector_source.tsx#:~:text=Filter), [es_tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts#:~:text=Filter), [es_tooltip_property.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/tooltips/es_tooltip_property.ts#:~:text=Filter)+ 115 more | 8.1 | +| | [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit), [es_search_source.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/classes/sources/es_search_source/es_search_source.tsx#:~:text=flattenHit) | - | | | [kibana_server_services.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/kibana_server_services.ts#:~:text=indexPatternsServiceFactory), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/plugin.ts#:~:text=indexPatternsServiceFactory), [indexing_routes.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/data_indexing/indexing_routes.ts#:~:text=indexPatternsServiceFactory) | - | | | [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings), [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings), [maps_list_view.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/public/routes/list_page/maps_list_view.tsx#:~:text=settings) | - | | | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/maps/server/plugin.ts#:~:text=license%24) | - | @@ -683,11 +682,11 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern), [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=IndexPattern), [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=IndexPattern), [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern)+ 2 more | - | -| | [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=indexPatterns), [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=indexPatterns) | - | -| | [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern), [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=IndexPattern), [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=IndexPattern), [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern)+ 2 more | - | -| | [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_errors.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern), [use_scheduled_query_group_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/use_scheduled_query_group_query_last_results.ts#:~:text=IndexPattern), [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=IndexPattern), [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=IndexPattern) | - | -| | [scheduled_query_group_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/scheduled_query_groups/scheduled_query_group_queries_status_table.tsx#:~:text=urlGenerator), [use_discover_link.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/common/hooks/use_discover_link.tsx#:~:text=urlGenerator) | - | +| | [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern), [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=IndexPattern), [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=IndexPattern), [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern)+ 2 more | - | +| | [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=indexPatterns), [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=indexPatterns) | - | +| | [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern), [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=IndexPattern), [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=IndexPattern), [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern)+ 2 more | - | +| | [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_errors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_errors.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern), [use_pack_query_last_results.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/use_pack_query_last_results.ts#:~:text=IndexPattern), [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=IndexPattern), [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=IndexPattern) | - | +| | [pack_queries_status_table.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/packs/pack_queries_status_table.tsx#:~:text=urlGenerator), [use_discover_link.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/osquery/public/common/hooks/use_discover_link.tsx#:~:text=urlGenerator) | - | @@ -704,7 +703,12 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| +| | [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern) | - | +| | [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType) | 8.1 | | | [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=esFilters), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=esFilters) | 8.1 | +| | [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType)+ 10 more | 8.1 | +| | [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IIndexPattern)+ 10 more | - | +| | [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_embeddable.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_embeddable.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType), [options_list_editor.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/controls/control_types/options_list/options_list_editor.tsx#:~:text=IFieldType) | 8.1 | | | [saved_object_save_modal_dashboard.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx#:~:text=SavedObjectSaveModal), [saved_object_save_modal_dashboard.tsx](https://github.com/elastic/kibana/tree/master/src/plugins/presentation_util/public/components/saved_object_save_modal_dashboard.tsx#:~:text=SavedObjectSaveModal) | - | @@ -826,23 +830,23 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [use_risky_hosts_dashboard_button_href.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_risky_hosts_dashboard_button_href.ts#:~:text=dashboardUrlGenerator), [use_risky_hosts_dashboard_links.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/overview/containers/overview_risky_host_links/use_risky_hosts_dashboard_links.tsx#:~:text=dashboardUrlGenerator), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/overview/containers/overview_cti_links/index.tsx#:~:text=dashboardUrlGenerator) | - | | | [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [list_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.tsx#:~:text=IndexPattern), [list_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.tsx#:~:text=IndexPattern)+ 30 more | - | | | [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField), [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField), [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField), [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField) | - | -| | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts#:~:text=IIndexPattern), [action.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/action.ts#:~:text=IIndexPattern), [action.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/action.ts#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/url_state/types.ts#:~:text=IIndexPattern)+ 74 more | - | +| | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/url_state/types.ts#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/url_state/types.ts#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/url_state/types.ts#:~:text=IIndexPattern)+ 74 more | - | | | [middleware.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/middleware.ts#:~:text=indexPatterns), [plugin.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/plugin.tsx#:~:text=indexPatterns), [dependencies_start_mock.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/mock/endpoint/dependencies_start_mock.ts#:~:text=indexPatterns) | - | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx#:~:text=esFilters), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/query_bar/index.tsx#:~:text=esFilters), [epic.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts#:~:text=esFilters), [epic.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts#:~:text=esFilters), [epic.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts#:~:text=esFilters), [epic.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts#:~:text=esFilters), [epic.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts#:~:text=esFilters), [epic.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts#:~:text=esFilters), [epic.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts#:~:text=esFilters), [epic.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts#:~:text=esFilters)+ 14 more | 8.1 | | | [expandable_network.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/side_panel/network_details/expandable_network.tsx#:~:text=esQuery), [expandable_network.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/side_panel/network_details/expandable_network.tsx#:~:text=esQuery), [events_viewer.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx#:~:text=esQuery), [events_viewer.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/events_viewer/events_viewer.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/top_n/index.tsx#:~:text=esQuery)+ 30 more | 8.1 | -| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [selectors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/selectors.ts#:~:text=Filter), [selectors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/selectors.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter)+ 163 more | 8.1 | -| | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts#:~:text=IIndexPattern), [action.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/action.ts#:~:text=IIndexPattern), [action.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/store/action.ts#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/url_state/types.ts#:~:text=IIndexPattern)+ 158 more | - | +| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx#:~:text=Filter), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx#:~:text=Filter)+ 165 more | 8.1 | +| | [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/types.ts#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/containers/source/index.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/timeline/helpers.tsx#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/url_state/types.ts#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/url_state/types.ts#:~:text=IIndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/url_state/types.ts#:~:text=IIndexPattern)+ 158 more | - | | | [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField), [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField), [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField), [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField) | - | | | [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [list_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.tsx#:~:text=IndexPattern), [list_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.tsx#:~:text=IndexPattern)+ 30 more | - | -| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [selectors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/selectors.ts#:~:text=Filter), [selectors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/selectors.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter)+ 163 more | 8.1 | +| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx#:~:text=Filter), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx#:~:text=Filter)+ 165 more | 8.1 | | | [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField), [field_name_cell.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/event_details/table/field_name_cell.tsx#:~:text=IndexPatternField) | - | | | [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/helpers.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [entry_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/entry_item.tsx#:~:text=IndexPattern), [list_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.tsx#:~:text=IndexPattern), [list_item.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/components/threat_match/list_item.tsx#:~:text=IndexPattern)+ 10 more | - | -| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [selectors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/selectors.ts#:~:text=Filter), [selectors.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/selectors.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter)+ 163 more | 8.1 | +| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/model.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/common/store/inputs/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [actions.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/store/timeline/actions.ts#:~:text=Filter), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx#:~:text=Filter), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/helpers.tsx#:~:text=Filter)+ 165 more | 8.1 | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode)+ 4 more | - | | | [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [policy_config.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/common/license/policy_config.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [fleet_integration.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/fleet_integration/fleet_integration.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [license_watch.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/lib/policy/license_watch.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode), [isolation.test.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/endpoint/routes/actions/isolation.test.ts#:~:text=mode)+ 4 more | - | -| | [create_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts#:~:text=authc), [delete_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts#:~:text=authc), [finalize_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts#:~:text=authc), [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts#:~:text=authc) | - | -| | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/plugin.ts#:~:text=spacesService), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/plugin.ts#:~:text=spacesService) | 7.16 | -| | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/plugin.ts#:~:text=getSpaceId), [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/plugin.ts#:~:text=getSpaceId) | 7.16 | +| | [create_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/create_signals_migration_route.ts#:~:text=authc), [delete_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/delete_signals_migration_route.ts#:~:text=authc), [finalize_signals_migration_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/finalize_signals_migration_route.ts#:~:text=authc), [preview_rules_route.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/detection_engine/routes/rules/preview_rules_route.ts#:~:text=authc), [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=authc), [common.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/lib/timeline/utils/common.ts#:~:text=authc) | - | +| | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/plugin.ts#:~:text=spacesService), [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=spacesService), [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=spacesService) | 7.16 | +| | [plugin.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/plugin.ts#:~:text=getSpaceId), [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=getSpaceId), [request_context_factory.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/server/request_context_factory.ts#:~:text=getSpaceId) | 7.16 | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/index.tsx#:~:text=onAppLeave) | - | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/timelines/components/flyout/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/bottom_bar/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/index.tsx#:~:text=AppLeaveHandler), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/home/index.tsx#:~:text=AppLeaveHandler), [routes.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/routes.tsx#:~:text=AppLeaveHandler), [routes.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/security_solution/public/app/routes.tsx#:~:text=AppLeaveHandler)+ 3 more | - | @@ -894,11 +898,11 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/container/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/container/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/container/source/index.tsx#:~:text=IIndexPattern), [index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/mock/index_pattern.ts#:~:text=IIndexPattern), [index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/mock/index_pattern.ts#:~:text=IIndexPattern) | - | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx#:~:text=IFieldSubType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx#:~:text=IFieldSubType) | 8.1 | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=esQuery), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=esQuery) | 8.1 | -| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=Filter)+ 5 more | 8.1 | +| | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/cells/index.ts#:~:text=Filter), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/cells/index.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter)+ 5 more | 8.1 | | | [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/container/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/container/source/index.tsx#:~:text=IIndexPattern), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/container/source/index.tsx#:~:text=IIndexPattern), [index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/mock/index_pattern.ts#:~:text=IIndexPattern), [index_pattern.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/mock/index_pattern.ts#:~:text=IIndexPattern), [helpers.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/helpers.tsx#:~:text=IIndexPattern)+ 8 more | - | -| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=Filter)+ 5 more | 8.1 | +| | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/cells/index.ts#:~:text=Filter), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/cells/index.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter)+ 5 more | 8.1 | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx#:~:text=IFieldSubType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx#:~:text=IFieldSubType) | 8.1 | -| | [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/standalone/index.tsx#:~:text=Filter)+ 5 more | 8.1 | +| | [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/cells/index.ts#:~:text=Filter), [index.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/cells/index.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [store.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/store.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [model.ts](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/store/t_grid/model.ts#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/body/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/public/components/t_grid/integrated/index.tsx#:~:text=Filter)+ 5 more | 8.1 | | | [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx#:~:text=IFieldSubType), [index.tsx](https://github.com/elastic/kibana/tree/master/x-pack/plugins/timelines/common/types/timeline/columns/index.tsx#:~:text=IFieldSubType) | 8.1 | @@ -1073,23 +1077,16 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Deprecated API | Reference location(s) | Remove By | | ---------------|-----------|-----------| -| | [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=IndexPatternsContract), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=IndexPatternsContract), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=IndexPatternsContract), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=IndexPatternsContract) | - | | | [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=IndexPattern), [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [create_vis_embeddable_from_object.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts#:~:text=IndexPattern), [create_vis_embeddable_from_object.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern)+ 10 more | - | | | [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=toJSON) | 8.1 | -| | [plugin.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/plugin.ts#:~:text=indexPatterns) | - | | | [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=esFilters), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=esFilters) | 8.1 | | | [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter) | 8.1 | | | [controls_references.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_visualization_references/controls_references.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [controls_references.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_visualization_references/controls_references.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [timeseries_references.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_visualization_references/timeseries_references.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [timeseries_references.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_visualization_references/timeseries_references.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [visualization_saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/server/migrations/visualization_saved_object_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [visualization_saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/server/migrations/visualization_saved_object_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [visualization_saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/server/migrations/visualization_saved_object_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [visualization_saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/server/migrations/visualization_saved_object_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [visualization_saved_object_migrations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/server/migrations/visualization_saved_object_migrations.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE), [controls_references.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/utils/saved_visualization_references/controls_references.ts#:~:text=INDEX_PATTERN_SAVED_OBJECT_TYPE)+ 8 more | - | -| | [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=IndexPatternsContract), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=IndexPatternsContract), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=IndexPatternsContract), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=IndexPatternsContract) | - | | | [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=IndexPattern), [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [create_vis_embeddable_from_object.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts#:~:text=IndexPattern), [create_vis_embeddable_from_object.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern)+ 10 more | - | | | [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter) | 8.1 | | | [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=toJSON) | 8.1 | | | [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=IndexPattern), [vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [types.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/vis_types/types.ts#:~:text=IndexPattern), [create_vis_embeddable_from_object.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts#:~:text=IndexPattern), [create_vis_embeddable_from_object.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/create_vis_embeddable_from_object.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=IndexPattern) | - | | | [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter), [visualize_embeddable.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/embeddable/visualize_embeddable.ts#:~:text=Filter) | 8.1 | -| | [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=__LEGACY), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=__LEGACY) | - | -| | [find_list_items.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts#:~:text=SavedObjectLoader), [find_list_items.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader), [saved_visualizations.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/saved_visualizations.ts#:~:text=SavedObjectLoader) | - | -| | [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObject), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObject), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObject), [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObject) | - | -| | [_saved_vis.ts](https://github.com/elastic/kibana/tree/master/src/plugins/visualizations/public/saved_visualizations/_saved_vis.ts#:~:text=SavedObjectClass) | - | diff --git a/api_docs/elastic_apm_generator.json b/api_docs/elastic_apm_generator.json deleted file mode 100644 index 24f11791d92b66..00000000000000 --- a/api_docs/elastic_apm_generator.json +++ /dev/null @@ -1,288 +0,0 @@ -{ - "id": "@elastic/apm-generator", - "client": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "server": { - "classes": [], - "functions": [ - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.getBreakdownMetrics", - "type": "Function", - "tags": [], - "label": "getBreakdownMetrics", - "description": [], - "signature": [ - "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]) => Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" - ], - "path": "packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.getBreakdownMetrics.$1", - "type": "Array", - "tags": [], - "label": "events", - "description": [], - "signature": [ - "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" - ], - "path": "packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.getObserverDefaults", - "type": "Function", - "tags": [], - "label": "getObserverDefaults", - "description": [], - "signature": [ - "() => Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>" - ], - "path": "packages/elastic-apm-generator/src/lib/defaults/get_observer_defaults.ts", - "deprecated": false, - "children": [], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.getSpanDestinationMetrics", - "type": "Function", - "tags": [], - "label": "getSpanDestinationMetrics", - "description": [], - "signature": [ - "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]) => { \"metricset.name\": string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; '@timestamp'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'host.name'?: string | undefined; 'observer.version'?: string | undefined; 'observer.version_major'?: number | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.duration.histogram'?: { values: number[]; counts: number[]; } | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.self_time.count'?: number | undefined; 'span.self_time.sum.us'?: number | undefined; }[]" - ], - "path": "packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.getSpanDestinationMetrics.$1", - "type": "Array", - "tags": [], - "label": "events", - "description": [], - "signature": [ - "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" - ], - "path": "packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.getTransactionMetrics", - "type": "Function", - "tags": [], - "label": "getTransactionMetrics", - "description": [], - "signature": [ - "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]) => { 'transaction.duration.histogram': { values: number[]; counts: number[]; }; _doc_count: number; '@timestamp'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'host.name'?: string | undefined; 'metricset.name'?: string | undefined; 'observer.version'?: string | undefined; 'observer.version_major'?: number | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.destination.service.response_time.sum.us'?: number | undefined; 'span.destination.service.response_time.count'?: number | undefined; 'span.self_time.count'?: number | undefined; 'span.self_time.sum.us'?: number | undefined; }[]" - ], - "path": "packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.getTransactionMetrics.$1", - "type": "Array", - "tags": [], - "label": "events", - "description": [], - "signature": [ - "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" - ], - "path": "packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.service", - "type": "Function", - "tags": [], - "label": "service", - "description": [], - "signature": [ - "(name: string, environment: string, agentName: string) => ", - "Service" - ], - "path": "packages/elastic-apm-generator/src/lib/service.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.service.$1", - "type": "string", - "tags": [], - "label": "name", - "description": [], - "signature": [ - "string" - ], - "path": "packages/elastic-apm-generator/src/lib/service.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.service.$2", - "type": "string", - "tags": [], - "label": "environment", - "description": [], - "signature": [ - "string" - ], - "path": "packages/elastic-apm-generator/src/lib/service.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.service.$3", - "type": "string", - "tags": [], - "label": "agentName", - "description": [], - "signature": [ - "string" - ], - "path": "packages/elastic-apm-generator/src/lib/service.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.timerange", - "type": "Function", - "tags": [], - "label": "timerange", - "description": [], - "signature": [ - "(from: number, to: number) => ", - "Timerange" - ], - "path": "packages/elastic-apm-generator/src/lib/timerange.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.timerange.$1", - "type": "number", - "tags": [], - "label": "from", - "description": [], - "signature": [ - "number" - ], - "path": "packages/elastic-apm-generator/src/lib/timerange.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.timerange.$2", - "type": "number", - "tags": [], - "label": "to", - "description": [], - "signature": [ - "number" - ], - "path": "packages/elastic-apm-generator/src/lib/timerange.ts", - "deprecated": false, - "isRequired": true - } - ], - "returnComment": [], - "initialIsOpen": false - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.toElasticsearchOutput", - "type": "Function", - "tags": [], - "label": "toElasticsearchOutput", - "description": [], - "signature": [ - "(events: Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[], versionOverride: string | undefined) => { _index: string; _source: {}; }[]" - ], - "path": "packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts", - "deprecated": false, - "children": [ - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.toElasticsearchOutput.$1", - "type": "Array", - "tags": [], - "label": "events", - "description": [], - "signature": [ - "Partial<{ '@timestamp': number; 'agent.name': string; 'agent.version': string; 'container.id': string; 'ecs.version': string; 'event.outcome': string; 'event.ingested': number; 'host.name': string; 'metricset.name': string; 'observer.version': string; 'observer.version_major': number; 'parent.id': string; 'processor.event': string; 'processor.name': string; 'trace.id': string; 'transaction.name': string; 'transaction.type': string; 'transaction.id': string; 'transaction.duration.us': number; 'transaction.duration.histogram': { values: number[]; counts: number[]; }; 'transaction.sampled': true; 'service.name': string; 'service.environment': string; 'service.node.name': string; 'span.id': string; 'span.name': string; 'span.type': string; 'span.subtype': string; 'span.duration.us': number; 'span.destination.service.name': string; 'span.destination.service.resource': string; 'span.destination.service.type': string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; 'span.self_time.count': number; 'span.self_time.sum.us': number; }>[]" - ], - "path": "packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts", - "deprecated": false, - "isRequired": true - }, - { - "parentPluginId": "@elastic/apm-generator", - "id": "def-server.toElasticsearchOutput.$2", - "type": "string", - "tags": [], - "label": "versionOverride", - "description": [], - "signature": [ - "string | undefined" - ], - "path": "packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts", - "deprecated": false, - "isRequired": false - } - ], - "returnComment": [], - "initialIsOpen": false - } - ], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - }, - "common": { - "classes": [], - "functions": [], - "interfaces": [], - "enums": [], - "misc": [], - "objects": [] - } -} \ No newline at end of file diff --git a/api_docs/elastic_apm_synthtrace.json b/api_docs/elastic_apm_synthtrace.json new file mode 100644 index 00000000000000..13d950c53a8df0 --- /dev/null +++ b/api_docs/elastic_apm_synthtrace.json @@ -0,0 +1,321 @@ +{ + "id": "@elastic/apm-synthtrace", + "client": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "server": { + "classes": [], + "functions": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.getBreakdownMetrics", + "type": "Function", + "tags": [], + "label": "getBreakdownMetrics", + "description": [], + "signature": [ + "(events: ", + "Fields", + "[]) => ", + "Fields", + "[]" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/utils/get_breakdown_metrics.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.getBreakdownMetrics.$1", + "type": "Array", + "tags": [], + "label": "events", + "description": [], + "signature": [ + "Fields", + "[]" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/utils/get_breakdown_metrics.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.getObserverDefaults", + "type": "Function", + "tags": [], + "label": "getObserverDefaults", + "description": [], + "signature": [ + "() => ", + "Fields" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/defaults/get_observer_defaults.ts", + "deprecated": false, + "children": [], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.getSpanDestinationMetrics", + "type": "Function", + "tags": [], + "label": "getSpanDestinationMetrics", + "description": [], + "signature": [ + "(events: ", + "Fields", + "[]) => { \"metricset.name\": string; 'span.destination.service.response_time.sum.us': number; 'span.destination.service.response_time.count': number; '@timestamp'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'error.id'?: string | undefined; 'error.exception'?: ", + "Exception", + "[] | undefined; 'error.grouping_name'?: string | undefined; 'error.grouping_key'?: string | undefined; 'host.name'?: string | undefined; 'observer.version'?: string | undefined; 'observer.version_major'?: number | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.duration.histogram'?: { values: number[]; counts: number[]; } | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.self_time.count'?: number | undefined; 'span.self_time.sum.us'?: number | undefined; 'system.process.memory.size'?: number | undefined; 'system.memory.actual.free'?: number | undefined; 'system.memory.total'?: number | undefined; 'system.cpu.total.norm.pct'?: number | undefined; 'system.process.memory.rss.bytes'?: number | undefined; 'system.process.cpu.total.norm.pct'?: number | undefined; }[]" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/utils/get_span_destination_metrics.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.getSpanDestinationMetrics.$1", + "type": "Array", + "tags": [], + "label": "events", + "description": [], + "signature": [ + "Fields", + "[]" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/utils/get_span_destination_metrics.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.getTransactionMetrics", + "type": "Function", + "tags": [], + "label": "getTransactionMetrics", + "description": [], + "signature": [ + "(events: ", + "Fields", + "[]) => { 'transaction.duration.histogram': { values: number[]; counts: number[]; }; _doc_count: number; '@timestamp'?: number | undefined; 'agent.name'?: string | undefined; 'agent.version'?: string | undefined; 'container.id'?: string | undefined; 'ecs.version'?: string | undefined; 'event.outcome'?: string | undefined; 'event.ingested'?: number | undefined; 'error.id'?: string | undefined; 'error.exception'?: ", + "Exception", + "[] | undefined; 'error.grouping_name'?: string | undefined; 'error.grouping_key'?: string | undefined; 'host.name'?: string | undefined; 'metricset.name'?: string | undefined; 'observer.version'?: string | undefined; 'observer.version_major'?: number | undefined; 'parent.id'?: string | undefined; 'processor.event'?: string | undefined; 'processor.name'?: string | undefined; 'trace.id'?: string | undefined; 'transaction.name'?: string | undefined; 'transaction.type'?: string | undefined; 'transaction.id'?: string | undefined; 'transaction.duration.us'?: number | undefined; 'transaction.sampled'?: true | undefined; 'service.name'?: string | undefined; 'service.environment'?: string | undefined; 'service.node.name'?: string | undefined; 'span.id'?: string | undefined; 'span.name'?: string | undefined; 'span.type'?: string | undefined; 'span.subtype'?: string | undefined; 'span.duration.us'?: number | undefined; 'span.destination.service.name'?: string | undefined; 'span.destination.service.resource'?: string | undefined; 'span.destination.service.type'?: string | undefined; 'span.destination.service.response_time.sum.us'?: number | undefined; 'span.destination.service.response_time.count'?: number | undefined; 'span.self_time.count'?: number | undefined; 'span.self_time.sum.us'?: number | undefined; 'system.process.memory.size'?: number | undefined; 'system.memory.actual.free'?: number | undefined; 'system.memory.total'?: number | undefined; 'system.cpu.total.norm.pct'?: number | undefined; 'system.process.memory.rss.bytes'?: number | undefined; 'system.process.cpu.total.norm.pct'?: number | undefined; }[]" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/utils/get_transaction_metrics.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.getTransactionMetrics.$1", + "type": "Array", + "tags": [], + "label": "events", + "description": [], + "signature": [ + "Fields", + "[]" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/utils/get_transaction_metrics.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.service", + "type": "Function", + "tags": [], + "label": "service", + "description": [], + "signature": [ + "(name: string, environment: string, agentName: string) => ", + "Service" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/service.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.service.$1", + "type": "string", + "tags": [], + "label": "name", + "description": [], + "signature": [ + "string" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/service.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.service.$2", + "type": "string", + "tags": [], + "label": "environment", + "description": [], + "signature": [ + "string" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/service.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.service.$3", + "type": "string", + "tags": [], + "label": "agentName", + "description": [], + "signature": [ + "string" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/service.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.timerange", + "type": "Function", + "tags": [], + "label": "timerange", + "description": [], + "signature": [ + "(from: number, to: number) => ", + "Timerange" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/timerange.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.timerange.$1", + "type": "number", + "tags": [], + "label": "from", + "description": [], + "signature": [ + "number" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/timerange.ts", + "deprecated": false, + "isRequired": true + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.timerange.$2", + "type": "number", + "tags": [], + "label": "to", + "description": [], + "signature": [ + "number" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/timerange.ts", + "deprecated": false, + "isRequired": true + } + ], + "returnComment": [], + "initialIsOpen": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.toElasticsearchOutput", + "type": "Function", + "tags": [], + "label": "toElasticsearchOutput", + "description": [], + "signature": [ + "({\n events,\n writeTargets,\n}: { events: ", + "Fields", + "[]; writeTargets: ", + "ElasticsearchOutputWriteTargets", + "; }) => ", + "ElasticsearchOutput", + "[]" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/output/to_elasticsearch_output.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.toElasticsearchOutput.$1", + "type": "Object", + "tags": [], + "label": "{\n events,\n writeTargets,\n}", + "description": [], + "path": "packages/elastic-apm-synthtrace/src/lib/output/to_elasticsearch_output.ts", + "deprecated": false, + "children": [ + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.toElasticsearchOutput.$1.events", + "type": "Array", + "tags": [], + "label": "events", + "description": [], + "signature": [ + "Fields", + "[]" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/output/to_elasticsearch_output.ts", + "deprecated": false + }, + { + "parentPluginId": "@elastic/apm-synthtrace", + "id": "def-server.toElasticsearchOutput.$1.writeTargets", + "type": "Object", + "tags": [], + "label": "writeTargets", + "description": [], + "signature": [ + "ElasticsearchOutputWriteTargets" + ], + "path": "packages/elastic-apm-synthtrace/src/lib/output/to_elasticsearch_output.ts", + "deprecated": false + } + ] + } + ], + "returnComment": [], + "initialIsOpen": false + } + ], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + }, + "common": { + "classes": [], + "functions": [], + "interfaces": [], + "enums": [], + "misc": [], + "objects": [] + } +} \ No newline at end of file diff --git a/api_docs/elastic_apm_generator.mdx b/api_docs/elastic_apm_synthtrace.mdx similarity index 63% rename from api_docs/elastic_apm_generator.mdx rename to api_docs/elastic_apm_synthtrace.mdx index 4c95050b09c28d..b41afe6c7357c8 100644 --- a/api_docs/elastic_apm_generator.mdx +++ b/api_docs/elastic_apm_synthtrace.mdx @@ -1,14 +1,14 @@ --- -id: kibElasticApmGeneratorPluginApi -slug: /kibana-dev-docs/api/elastic-apm-generator -title: "@elastic/apm-generator" +id: kibElasticApmSynthtracePluginApi +slug: /kibana-dev-docs/api/elastic-apm-synthtrace +title: "@elastic/apm-synthtrace" image: https://source.unsplash.com/400x175/?github -summary: API docs for the @elastic/apm-generator plugin +summary: API docs for the @elastic/apm-synthtrace plugin date: 2020-11-16 -tags: ['contributor', 'dev', 'apidocs', 'kibana', '@elastic/apm-generator'] +tags: ['contributor', 'dev', 'apidocs', 'kibana', '@elastic/apm-synthtrace'] warning: This document is auto-generated and is meant to be viewed inside our experimental, new docs system. Reach out in #docs-engineering for more info. --- -import elasticApmGeneratorObj from './elastic_apm_generator.json'; +import elasticApmSynthtraceObj from './elastic_apm_synthtrace.json'; Elastic APM trace data generator @@ -18,10 +18,10 @@ Contact [Owner missing] for questions regarding this plugin. | Public API count | Any count | Items lacking comments | Missing exports | |-------------------|-----------|------------------------|-----------------| -| 17 | 0 | 17 | 2 | +| 18 | 0 | 18 | 6 | ## Server ### Functions - + diff --git a/api_docs/plugin_directory.mdx b/api_docs/plugin_directory.mdx index 19e3bc08a53615..d23a52b07a1e33 100644 --- a/api_docs/plugin_directory.mdx +++ b/api_docs/plugin_directory.mdx @@ -18,7 +18,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | API Count | Any Count | Missing comments | Missing exports | |--------------|----------|-----------------|--------| -| 24459 | 276 | 19826 | 1583 | +| 24503 | 264 | 19863 | 1594 | ## Plugin Directory @@ -26,7 +26,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex |--------------|----------------|-----------|--------------|----------|---------------|--------| | | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 125 | 0 | 125 | 8 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 23 | 0 | 22 | 1 | -| | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 257 | 0 | 249 | 17 | +| | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 258 | 0 | 250 | 17 | | | [APM UI](https://github.com/orgs/elastic/teams/apm-ui) | The user interface for Elastic APM | 39 | 0 | 39 | 37 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 9 | 0 | 9 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Considering using bfetch capabilities when fetching large amounts of data. This services supports batching HTTP requests and streaming responses back. | 76 | 1 | 67 | 2 | @@ -34,18 +34,18 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Security Solution Threat Hunting](https://github.com/orgs/elastic/teams/security-threat-hunting) | The Case management system in Kibana | 476 | 0 | 432 | 14 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 285 | 4 | 253 | 3 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 22 | 0 | 22 | 0 | -| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 9 | 0 | 9 | 1 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2298 | 27 | 1018 | 29 | +| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 13 | 0 | 13 | 1 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 2304 | 27 | 1023 | 29 | | crossClusterReplication | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 91 | 1 | 75 | 1 | -| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 145 | 1 | 132 | 10 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | Add custom data integrations so they can be displayed in the Fleet integrations app | 100 | 1 | 84 | 1 | +| | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds the Dashboard app to Kibana | 147 | 1 | 134 | 10 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 51 | 0 | 50 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3193 | 43 | 2807 | 48 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 3238 | 40 | 2848 | 48 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Enhanced data plugin. (See src/plugins/data.) Enhances the main data plugin with a search session management UI. Includes a reusable search session indicator component to use in other applications. Exposes routes for managing search sessions. Includes a service that monitors, updates, and cleans up search session saved objects. | 16 | 0 | 16 | 2 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 683 | 6 | 541 | 5 | -| | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 80 | 5 | 80 | 0 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Data services are useful for searching and querying data from Elasticsearch. Helpful utilities include: a re-usable react query bar, KQL autocomplete, async search, Data Views (Index Patterns) and field formatters. | 668 | 5 | 526 | 5 | +| | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The Data Visualizer tools help you understand your data, by analyzing the metrics and fields in a log file or an existing Elasticsearch index. | 84 | 5 | 84 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 10 | 0 | 8 | 2 | -| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 103 | 0 | 77 | 7 | +| | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | This plugin contains the Discover application and the saved search embeddable. | 84 | 0 | 58 | 7 | | | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 37 | 0 | 35 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds embeddables service to Kibana | 469 | 5 | 393 | 3 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Extends embeddable plugin with more functionality | 14 | 0 | 14 | 0 | @@ -61,17 +61,17 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'revealImage' function and renderer to expressions | 12 | 0 | 12 | 3 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds 'shape' function and renderer to expressions | 143 | 0 | 143 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Expression Tagcloud plugin adds a `tagcloud` renderer and function to the expression plugin. The renderer will display the `Wordcloud` chart. | 5 | 0 | 5 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2086 | 27 | 1640 | 4 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds expression runtime to Kibana | 2092 | 27 | 1646 | 3 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 216 | 0 | 98 | 2 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 288 | 7 | 250 | 3 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Index pattern fields and ambiguous values formatters | 284 | 7 | 246 | 3 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | The file upload plugin contains components and services for uploading a file, analyzing its data, and then importing the data into an Elasticsearch index. Supported file types include CSV, TSV, newline-delimited JSON and GeoJSON. | 129 | 4 | 129 | 1 | -| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1210 | 15 | 1110 | 10 | +| | [Fleet](https://github.com/orgs/elastic/teams/fleet) | - | 1225 | 15 | 1122 | 10 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 68 | 0 | 14 | 5 | | globalSearchBar | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | globalSearchProviders | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 0 | 0 | 0 | 0 | | graph | [Data Discovery](https://github.com/orgs/elastic/teams/kibana-data-discovery) | - | 0 | 0 | 0 | 0 | | grokdebugger | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | -| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 99 | 3 | 77 | 5 | +| | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 96 | 2 | 74 | 5 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 4 | 0 | 4 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 169 | 9 | 164 | 3 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | This plugin provides the ability to create index patterns via a modal flyout from any kibana app | 13 | 1 | 8 | 0 | @@ -82,16 +82,16 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | inputControlVis | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds Input Control visualization to Kibana | 0 | 0 | 0 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 123 | 6 | 96 | 4 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides UI and APIs for the interactive setup mode. | 26 | 0 | 16 | 0 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 48 | 1 | 45 | 0 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 12 | 0 | 9 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 6 | 0 | 6 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 297 | 8 | 260 | 5 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 282 | 2 | 245 | 5 | | kibanaUsageCollection | [Kibana Telemtry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 0 | 0 | 0 | 0 | -| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 606 | 3 | 413 | 8 | +| | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 607 | 3 | 414 | 8 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Visualization editor allowing to quickly and easily configure compelling visualizations to use on dashboards and canvas workpads. Exposes components to embed visualizations and link into the Lens editor from within other apps in Kibana. | 253 | 0 | 235 | 24 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 8 | 0 | 8 | 0 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 3 | 0 | 3 | 0 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 117 | 0 | 42 | 8 | -| | [Security detections response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 150 | 0 | 143 | 38 | +| | [Security detections response](https://github.com/orgs/elastic/teams/security-detections-response) | - | 155 | 0 | 148 | 39 | | logstash | [Logstash](https://github.com/orgs/elastic/teams/logstash) | - | 0 | 0 | 0 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | - | 40 | 0 | 40 | 5 | | | [GIS](https://github.com/orgs/elastic/teams/kibana-gis) | - | 202 | 0 | 201 | 29 | @@ -101,14 +101,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Stack Monitoring](https://github.com/orgs/elastic/teams/stack-monitoring-ui) | - | 10 | 0 | 10 | 2 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 31 | 0 | 31 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 17 | 0 | 17 | 0 | -| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 258 | 1 | 257 | 12 | -| | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 11 | 0 | 11 | 0 | +| | [Observability UI](https://github.com/orgs/elastic/teams/observability-ui) | - | 268 | 1 | 267 | 15 | +| | [Security asset management](https://github.com/orgs/elastic/teams/security-asset-management) | - | 10 | 0 | 10 | 0 | | painlessLab | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | | | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | The Presentation Utility Plugin is a set of common, shared components and toolkits for solutions within the Presentation space, (e.g. Dashboards, Canvas). | 178 | 3 | 151 | 6 | | | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 4 | 0 | 4 | 0 | -| | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 135 | 0 | 134 | 12 | -| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 20 | 0 | 20 | 0 | -| | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 136 | 0 | 113 | 7 | +| | [Kibana Reporting Services](https://github.com/orgs/elastic/teams/kibana-reporting-services) | Reporting Services enables applications to feature reports that the user can automate with Watcher and download later. | 137 | 0 | 136 | 12 | +| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 21 | 0 | 21 | 0 | +| | [RAC](https://github.com/orgs/elastic/teams/rac) | - | 151 | 0 | 128 | 7 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 24 | 0 | 19 | 2 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 221 | 3 | 207 | 4 | | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 103 | 0 | 90 | 0 | @@ -116,18 +116,18 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Kibana Core](https://github.com/orgs/elastic/teams/kibana-core) | - | 90 | 3 | 51 | 0 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | - | 22 | 0 | 17 | 1 | | searchprofiler | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | -| | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 113 | 0 | 51 | 7 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 1361 | 8 | 1307 | 30 | +| | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides authentication and authorization features, and exposes functionality to understand the capabilities of the currently authenticated user. | 116 | 0 | 54 | 8 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 1372 | 8 | 1318 | 33 | | | [App Services](https://github.com/orgs/elastic/teams/kibana-app-services) | Adds URL Service and sharing capabilities to Kibana | 143 | 1 | 90 | 10 | -| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 23 | 1 | 22 | 1 | +| | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 23 | 1 | 23 | 1 | | | [Platform Security](https://github.com/orgs/elastic/teams/kibana-security) | This plugin provides the Spaces feature, which allows saved objects to be organized into meaningful categories. | 208 | 0 | 21 | 1 | | | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 4 | 0 | 4 | 0 | | | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 70 | 0 | 32 | 7 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 41 | 0 | 0 | 0 | -| | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 36 | 0 | 36 | 4 | +| | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 32 | 0 | 32 | 5 | | | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 1 | 0 | 1 | 0 | -| | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 14 | 0 | 13 | 0 | -| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 968 | 6 | 847 | 25 | +| | [Kibana Telemetry](https://github.com/orgs/elastic/teams/kibana-telemetry) | - | 11 | 0 | 10 | 0 | +| | [Security solution](https://github.com/orgs/elastic/teams/security-solution) | - | 969 | 6 | 848 | 25 | | | [Machine Learning UI](https://github.com/orgs/elastic/teams/ml-ui) | This plugin provides access to the transforms features provided by Elastic. Transforms enable you to convert existing Elasticsearch indices into summarized indices, which provide opportunities for new insights and analytics. | 4 | 0 | 4 | 1 | | translations | [Kibana Localization](https://github.com/orgs/elastic/teams/kibana-localization) | - | 0 | 0 | 0 | 0 | | | [Kibana Alerting](https://github.com/orgs/elastic/teams/kibana-alerting-services) | - | 238 | 1 | 229 | 18 | @@ -142,14 +142,14 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | visTypeMarkdown | [Kibana Presentation](https://github.com/orgs/elastic/teams/kibana-presentation) | Adds a markdown visualization type | 0 | 0 | 0 | 0 | | visTypeMetric | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the Metric aggregation-based visualization. | 0 | 0 | 0 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the pie chart implementation using the elastic-charts library. The goal is to eventually deprecate the old implementation and keep only this. Until then, the library used is defined by the Legacy charts library advanced setting. | 12 | 0 | 12 | 2 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the datatable aggregation-based visualization. | 11 | 0 | 11 | 0 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the datatable aggregation-based visualization. | 12 | 0 | 12 | 0 | | visTypeTagcloud | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the tagcloud visualization. It is based on elastic-charts wordcloud. | 0 | 0 | 0 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the timelion visualization. Also contains the backend for both timelion app and timelion visualization. | 2 | 0 | 2 | 2 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the TSVB visualization. TSVB has its one editor, works with index patterns and index strings and contains 6 types of charts: timeseries, topN, table. markdown, metric and gauge. | 10 | 1 | 10 | 3 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Registers the vega visualization. Is the elastic version of vega and vega-lite libraries. | 2 | 0 | 2 | 0 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the vislib visualizations. These are the classical area/line/bar, pie, gauge/goal and heatmap charts. We want to replace them with elastic-charts. | 26 | 0 | 25 | 1 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the new xy-axis chart using the elastic-charts library, which will eventually replace the vislib xy-axis charts including bar, area, and line. | 57 | 0 | 51 | 5 | -| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 304 | 13 | 286 | 16 | +| | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the shared architecture among all the legacy visualizations, e.g. the visualization type registry or the visualization embeddable. | 303 | 13 | 285 | 15 | | | [Vis Editors](https://github.com/orgs/elastic/teams/kibana-vis-editors) | Contains the visualize application which includes the listing page and the app frame, which will load the visualization's editor. | 24 | 0 | 23 | 1 | | watcher | [Stack Management](https://github.com/orgs/elastic/teams/kibana-stack-management) | - | 0 | 0 | 0 | 0 | @@ -157,7 +157,7 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | Package name           | Maintaining team | Description | API Cnt | Any Cnt | Missing
comments | Missing
exports | |--------------|----------------|-----------|--------------|----------|---------------|--------| -| | [Owner missing] | Elastic APM trace data generator | 17 | 0 | 17 | 2 | +| | [Owner missing] | Elastic APM trace data generator | 18 | 0 | 18 | 6 | | | [Owner missing] | elasticsearch datemath parser, used in kibana | 44 | 0 | 43 | 0 | | | [Owner missing] | - | 11 | 5 | 11 | 0 | | | [Owner missing] | Alerts components and hooks | 9 | 1 | 9 | 0 | @@ -187,13 +187,13 @@ warning: This document is auto-generated and is meant to be viewed inside our ex | | [Owner missing] | security solution elastic search utilities to use across plugins such lists, security_solution, cases, etc... | 54 | 0 | 51 | 0 | | | [Owner missing] | Security Solution utilities for React hooks | 8 | 0 | 1 | 1 | | | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 147 | 1 | 128 | 0 | -| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 418 | 1 | 409 | 0 | +| | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 419 | 1 | 410 | 0 | | | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 45 | 0 | 23 | 0 | | | [Owner missing] | io ts utilities and types to be shared with plugins from the security solution project | 28 | 0 | 22 | 0 | | | [Owner missing] | security solution list REST API | 42 | 0 | 41 | 5 | | | [Owner missing] | security solution list constants to use across plugins such lists, security_solution, cases, etc... | 23 | 0 | 9 | 0 | | | [Owner missing] | Security solution list ReactJS hooks | 56 | 0 | 44 | 0 | -| | [Owner missing] | security solution list utilities | 222 | 0 | 177 | 0 | +| | [Owner missing] | security solution list utilities | 223 | 0 | 178 | 0 | | | [Owner missing] | security solution t-grid packages will allow sharing components between timelines and security_solution plugin until we transfer all functionality to timelines plugin | 120 | 0 | 116 | 0 | | | [Owner missing] | security solution utilities to use across plugins such lists, security_solution, cases, etc... | 6 | 0 | 4 | 0 | | | [Owner missing] | - | 53 | 0 | 50 | 1 | diff --git a/package.json b/package.json index d9dd4912481b9b..1f2102f3aff2ee 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "@dnd-kit/core": "^3.1.1", "@dnd-kit/sortable": "^4.0.0", "@dnd-kit/utilities": "^2.0.0", - "@elastic/apm-generator": "link:bazel-bin/packages/elastic-apm-generator", + "@elastic/apm-synthtrace": "link:bazel-bin/packages/elastic-apm-synthtrace", "@elastic/apm-rum": "^5.9.1", "@elastic/apm-rum-react": "^1.3.1", "@elastic/charts": "38.0.1", diff --git a/packages/BUILD.bazel b/packages/BUILD.bazel index ace4f982b8515c..846f2c9fc3e4b6 100644 --- a/packages/BUILD.bazel +++ b/packages/BUILD.bazel @@ -3,7 +3,7 @@ filegroup( name = "build", srcs = [ - "//packages/elastic-apm-generator:build", + "//packages/elastic-apm-synthtrace:build", "//packages/elastic-datemath:build", "//packages/elastic-eslint-config-kibana:build", "//packages/elastic-safer-lodash-set:build", diff --git a/packages/elastic-apm-generator/README.md b/packages/elastic-apm-generator/README.md deleted file mode 100644 index b442c0ec23ee04..00000000000000 --- a/packages/elastic-apm-generator/README.md +++ /dev/null @@ -1,107 +0,0 @@ -# @elastic/apm-generator - -`@elastic/apm-generator` is an experimental tool to generate synthetic APM data. It is intended to be used for development and testing of the Elastic APM app in Kibana. - -At a high-level, the module works by modeling APM events/metricsets with [a fluent API](https://en.wikipedia.org/wiki/Fluent_interface). The models can then be serialized and converted to Elasticsearch documents. In the future we might support APM Server as an output as well. - -## Usage - -This section assumes that you've installed Kibana's dependencies by running `yarn kbn bootstrap` in the repository's root folder. - -This library can currently be used in two ways: - -- Imported as a Node.js module, for instance to be used in Kibana's functional test suite. -- With a command line interface, to index data based on a specified scenario. - -### Using the Node.js module - -#### Concepts - -- `Service`: a logical grouping for a monitored service. A `Service` object contains fields like `service.name`, `service.environment` and `agent.name`. -- `Instance`: a single instance of a monitored service. E.g., the workload for a monitored service might be spread across multiple containers. An `Instance` object contains fields like `service.node.name` and `container.id`. -- `Timerange`: an object that will return an array of timestamps based on an interval and a rate. These timestamps can be used to generate events/metricsets. -- `Transaction`, `Span`, `APMError` and `Metricset`: events/metricsets that occur on an instance. For more background, see the [explanation of the APM data model](https://www.elastic.co/guide/en/apm/get-started/7.15/apm-data-model.html) - - -#### Example - -```ts -import { service, timerange, toElasticsearchOutput } from '@elastic/apm-generator'; - -const instance = service('synth-go', 'production', 'go') - .instance('instance-a'); - -const from = new Date('2021-01-01T12:00:00.000Z').getTime(); -const to = new Date('2021-01-01T12:00:00.000Z').getTime(); - -const traceEvents = timerange(from, to) - .interval('1m') - .rate(10) - .flatMap(timestamp => instance.transaction('GET /api/product/list') - .timestamp(timestamp) - .duration(1000) - .success() - .children( - instance.span('GET apm-*/_search', 'db', 'elasticsearch') - .timestamp(timestamp + 50) - .duration(900) - .destination('elasticsearch') - .success() - ).serialize() - ); - -const metricsets = timerange(from, to) - .interval('30s') - .rate(1) - .flatMap(timestamp => instance.appMetrics({ - 'system.memory.actual.free': 800, - 'system.memory.total': 1000, - 'system.cpu.total.norm.pct': 0.6, - 'system.process.cpu.total.norm.pct': 0.7, - }).timestamp(timestamp) - .serialize() - ); - -const esEvents = toElasticsearchOutput(traceEvents.concat(metricsets)); -``` - -#### Generating metricsets - -`@elastic/apm-generator` can also automatically generate transaction metrics, span destination metrics and transaction breakdown metrics based on the generated trace events. If we expand on the previous example: - -```ts -import { getTransactionMetrics, getSpanDestinationMetrics, getBreakdownMetrics } from '@elastic/apm-generator'; - -const esEvents = toElasticsearchOutput([ - ...traceEvents, - ...getTransactionMetrics(traceEvents), - ...getSpanDestinationMetrics(traceEvents), - ...getBreakdownMetrics(traceEvents) -]); -``` - -### CLI - -Via the CLI, you can upload scenarios, either using a fixed time range or continuously generating data. Some examples are available in in `src/scripts/examples`. Here's an example for live data: - -`$ node packages/elastic-apm-generator/src/scripts/run packages/elastic-apm-generator/src/examples/01_simple_trace.ts --target=http://admin:changeme@localhost:9200 --live` - -For a fixed time window: -`$ node packages/elastic-apm-generator/src/scripts/run packages/elastic-apm-generator/src/examples/01_simple_trace.ts --target=http://admin:changeme@localhost:9200 --from=now-24h --to=now` - -The script will try to automatically find bootstrapped APM indices. __If these indices do not exist, the script will exit with an error. It will not bootstrap the indices itself.__ - -The following options are supported: -| Option | Description | Default | -| -------------- | ------------------------------------------------------- | ------------ | -| `--from` | The start of the time window. | `now - 15m` | -| `--to` | The end of the time window. | `now` | -| `--live` | Continously ingest data | `false` | -| `--bucketSize` | Size of bucket for which to generate data. | `15m` | -| `--clean` | Clean APM indices before indexing new data. | `false` | -| `--interval` | The interval at which to index data. | `10s` | -| `--logLevel` | Log level. | `info` | -| `--lookback` | The lookback window for which data should be generated. | `15m` | -| `--target` | Elasticsearch target, including username/password. | **Required** | -| `--workers` | Amount of simultaneously connected ES clients. | `1` | - diff --git a/packages/elastic-apm-generator/BUILD.bazel b/packages/elastic-apm-synthtrace/BUILD.bazel similarity index 95% rename from packages/elastic-apm-generator/BUILD.bazel rename to packages/elastic-apm-synthtrace/BUILD.bazel index 396c27b3a4c893..5d9510c6a81d5a 100644 --- a/packages/elastic-apm-generator/BUILD.bazel +++ b/packages/elastic-apm-synthtrace/BUILD.bazel @@ -2,8 +2,8 @@ load("@npm//@bazel/typescript:index.bzl", "ts_config", "ts_project") load("@build_bazel_rules_nodejs//:index.bzl", "js_library", "pkg_npm") load("//src/dev/bazel:index.bzl", "jsts_transpiler") -PKG_BASE_NAME = "elastic-apm-generator" -PKG_REQUIRE_NAME = "@elastic/apm-generator" +PKG_BASE_NAME = "elastic-apm-synthtrace" +PKG_REQUIRE_NAME = "@elastic/apm-synthtrace" SOURCE_FILES = glob( [ diff --git a/packages/elastic-apm-synthtrace/README.md b/packages/elastic-apm-synthtrace/README.md new file mode 100644 index 00000000000000..8413ba58a5c421 --- /dev/null +++ b/packages/elastic-apm-synthtrace/README.md @@ -0,0 +1,115 @@ +# @elastic/apm-synthtrace + +`@elastic/apm-synthtrace` is an experimental tool to generate synthetic APM data. It is intended to be used for development and testing of the Elastic APM app in Kibana. + +At a high-level, the module works by modeling APM events/metricsets with [a fluent API](https://en.wikipedia.org/wiki/Fluent_interface). The models can then be serialized and converted to Elasticsearch documents. In the future we might support APM Server as an output as well. + +## Usage + +This section assumes that you've installed Kibana's dependencies by running `yarn kbn bootstrap` in the repository's root folder. + +This library can currently be used in two ways: + +- Imported as a Node.js module, for instance to be used in Kibana's functional test suite. +- With a command line interface, to index data based on a specified scenario. + +### Using the Node.js module + +#### Concepts + +- `Service`: a logical grouping for a monitored service. A `Service` object contains fields like `service.name`, `service.environment` and `agent.name`. +- `Instance`: a single instance of a monitored service. E.g., the workload for a monitored service might be spread across multiple containers. An `Instance` object contains fields like `service.node.name` and `container.id`. +- `Timerange`: an object that will return an array of timestamps based on an interval and a rate. These timestamps can be used to generate events/metricsets. +- `Transaction`, `Span`, `APMError` and `Metricset`: events/metricsets that occur on an instance. For more background, see the [explanation of the APM data model](https://www.elastic.co/guide/en/apm/get-started/7.15/apm-data-model.html) + +#### Example + +```ts +import { service, timerange, toElasticsearchOutput } from '@elastic/apm-synthtrace'; + +const instance = service('synth-go', 'production', 'go').instance('instance-a'); + +const from = new Date('2021-01-01T12:00:00.000Z').getTime(); +const to = new Date('2021-01-01T12:00:00.000Z').getTime(); + +const traceEvents = timerange(from, to) + .interval('1m') + .rate(10) + .flatMap((timestamp) => + instance + .transaction('GET /api/product/list') + .timestamp(timestamp) + .duration(1000) + .success() + .children( + instance + .span('GET apm-*/_search', 'db', 'elasticsearch') + .timestamp(timestamp + 50) + .duration(900) + .destination('elasticsearch') + .success() + ) + .serialize() + ); + +const metricsets = timerange(from, to) + .interval('30s') + .rate(1) + .flatMap((timestamp) => + instance + .appMetrics({ + 'system.memory.actual.free': 800, + 'system.memory.total': 1000, + 'system.cpu.total.norm.pct': 0.6, + 'system.process.cpu.total.norm.pct': 0.7, + }) + .timestamp(timestamp) + .serialize() + ); + +const esEvents = toElasticsearchOutput(traceEvents.concat(metricsets)); +``` + +#### Generating metricsets + +`@elastic/apm-synthtrace` can also automatically generate transaction metrics, span destination metrics and transaction breakdown metrics based on the generated trace events. If we expand on the previous example: + +```ts +import { + getTransactionMetrics, + getSpanDestinationMetrics, + getBreakdownMetrics, +} from '@elastic/apm-synthtrace'; + +const esEvents = toElasticsearchOutput([ + ...traceEvents, + ...getTransactionMetrics(traceEvents), + ...getSpanDestinationMetrics(traceEvents), + ...getBreakdownMetrics(traceEvents), +]); +``` + +### CLI + +Via the CLI, you can upload scenarios, either using a fixed time range or continuously generating data. Some examples are available in in `src/scripts/examples`. Here's an example for live data: + +`$ node packages/elastic-apm-synthtrace/src/scripts/run packages/elastic-apm-synthtrace/src/examples/01_simple_trace.ts --target=http://admin:changeme@localhost:9200 --live` + +For a fixed time window: +`$ node packages/elastic-apm-synthtrace/src/scripts/run packages/elastic-apm-synthtrace/src/examples/01_simple_trace.ts --target=http://admin:changeme@localhost:9200 --from=now-24h --to=now` + +The script will try to automatically find bootstrapped APM indices. **If these indices do not exist, the script will exit with an error. It will not bootstrap the indices itself.** + +The following options are supported: +| Option | Description | Default | +| -------------- | ------------------------------------------------------- | ------------ | +| `--from` | The start of the time window. | `now - 15m` | +| `--to` | The end of the time window. | `now` | +| `--live` | Continously ingest data | `false` | +| `--bucketSize` | Size of bucket for which to generate data. | `15m` | +| `--clean` | Clean APM indices before indexing new data. | `false` | +| `--interval` | The interval at which to index data. | `10s` | +| `--logLevel` | Log level. | `info` | +| `--lookback` | The lookback window for which data should be generated. | `15m` | +| `--target` | Elasticsearch target, including username/password. | **Required** | +| `--workers` | Amount of simultaneously connected ES clients. | `1` | diff --git a/packages/elastic-apm-generator/jest.config.js b/packages/elastic-apm-synthtrace/jest.config.js similarity index 89% rename from packages/elastic-apm-generator/jest.config.js rename to packages/elastic-apm-synthtrace/jest.config.js index 64aaa43741cc3a..13d8643c5213cd 100644 --- a/packages/elastic-apm-generator/jest.config.js +++ b/packages/elastic-apm-synthtrace/jest.config.js @@ -9,7 +9,7 @@ module.exports = { preset: '@kbn/test', rootDir: '../..', - roots: ['/packages/elastic-apm-generator'], + roots: ['/packages/elastic-apm-synthtrace'], setupFiles: [], setupFilesAfterEnv: [], }; diff --git a/packages/elastic-apm-generator/package.json b/packages/elastic-apm-synthtrace/package.json similarity index 85% rename from packages/elastic-apm-generator/package.json rename to packages/elastic-apm-synthtrace/package.json index 57dafd5d6431da..43699e47955866 100644 --- a/packages/elastic-apm-generator/package.json +++ b/packages/elastic-apm-synthtrace/package.json @@ -1,5 +1,5 @@ { - "name": "@elastic/apm-generator", + "name": "@elastic/apm-synthtrace", "version": "0.1.0", "description": "Elastic APM trace data generator", "license": "SSPL-1.0 OR Elastic License 2.0", diff --git a/packages/elastic-apm-generator/src/.eslintrc.js b/packages/elastic-apm-synthtrace/src/.eslintrc.js similarity index 100% rename from packages/elastic-apm-generator/src/.eslintrc.js rename to packages/elastic-apm-synthtrace/src/.eslintrc.js diff --git a/packages/elastic-apm-generator/src/index.ts b/packages/elastic-apm-synthtrace/src/index.ts similarity index 100% rename from packages/elastic-apm-generator/src/index.ts rename to packages/elastic-apm-synthtrace/src/index.ts diff --git a/packages/elastic-apm-generator/src/lib/apm_error.ts b/packages/elastic-apm-synthtrace/src/lib/apm_error.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/apm_error.ts rename to packages/elastic-apm-synthtrace/src/lib/apm_error.ts diff --git a/packages/elastic-apm-generator/src/lib/base_span.ts b/packages/elastic-apm-synthtrace/src/lib/base_span.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/base_span.ts rename to packages/elastic-apm-synthtrace/src/lib/base_span.ts diff --git a/packages/elastic-apm-generator/src/lib/defaults/get_observer_defaults.ts b/packages/elastic-apm-synthtrace/src/lib/defaults/get_observer_defaults.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/defaults/get_observer_defaults.ts rename to packages/elastic-apm-synthtrace/src/lib/defaults/get_observer_defaults.ts diff --git a/packages/elastic-apm-generator/src/lib/entity.ts b/packages/elastic-apm-synthtrace/src/lib/entity.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/entity.ts rename to packages/elastic-apm-synthtrace/src/lib/entity.ts diff --git a/packages/elastic-apm-generator/src/lib/instance.ts b/packages/elastic-apm-synthtrace/src/lib/instance.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/instance.ts rename to packages/elastic-apm-synthtrace/src/lib/instance.ts diff --git a/packages/elastic-apm-generator/src/lib/interval.ts b/packages/elastic-apm-synthtrace/src/lib/interval.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/interval.ts rename to packages/elastic-apm-synthtrace/src/lib/interval.ts diff --git a/packages/elastic-apm-generator/src/lib/metricset.ts b/packages/elastic-apm-synthtrace/src/lib/metricset.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/metricset.ts rename to packages/elastic-apm-synthtrace/src/lib/metricset.ts diff --git a/packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts b/packages/elastic-apm-synthtrace/src/lib/output/to_elasticsearch_output.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/output/to_elasticsearch_output.ts rename to packages/elastic-apm-synthtrace/src/lib/output/to_elasticsearch_output.ts diff --git a/packages/elastic-apm-generator/src/lib/serializable.ts b/packages/elastic-apm-synthtrace/src/lib/serializable.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/serializable.ts rename to packages/elastic-apm-synthtrace/src/lib/serializable.ts diff --git a/packages/elastic-apm-generator/src/lib/service.ts b/packages/elastic-apm-synthtrace/src/lib/service.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/service.ts rename to packages/elastic-apm-synthtrace/src/lib/service.ts diff --git a/packages/elastic-apm-generator/src/lib/span.ts b/packages/elastic-apm-synthtrace/src/lib/span.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/span.ts rename to packages/elastic-apm-synthtrace/src/lib/span.ts diff --git a/packages/elastic-apm-generator/src/lib/timerange.ts b/packages/elastic-apm-synthtrace/src/lib/timerange.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/timerange.ts rename to packages/elastic-apm-synthtrace/src/lib/timerange.ts diff --git a/packages/elastic-apm-generator/src/lib/transaction.ts b/packages/elastic-apm-synthtrace/src/lib/transaction.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/transaction.ts rename to packages/elastic-apm-synthtrace/src/lib/transaction.ts diff --git a/packages/elastic-apm-generator/src/lib/utils/aggregate.ts b/packages/elastic-apm-synthtrace/src/lib/utils/aggregate.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/utils/aggregate.ts rename to packages/elastic-apm-synthtrace/src/lib/utils/aggregate.ts diff --git a/packages/elastic-apm-generator/src/lib/utils/create_picker.ts b/packages/elastic-apm-synthtrace/src/lib/utils/create_picker.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/utils/create_picker.ts rename to packages/elastic-apm-synthtrace/src/lib/utils/create_picker.ts diff --git a/packages/elastic-apm-generator/src/lib/utils/generate_id.ts b/packages/elastic-apm-synthtrace/src/lib/utils/generate_id.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/utils/generate_id.ts rename to packages/elastic-apm-synthtrace/src/lib/utils/generate_id.ts diff --git a/packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.ts b/packages/elastic-apm-synthtrace/src/lib/utils/get_breakdown_metrics.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/utils/get_breakdown_metrics.ts rename to packages/elastic-apm-synthtrace/src/lib/utils/get_breakdown_metrics.ts diff --git a/packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts b/packages/elastic-apm-synthtrace/src/lib/utils/get_span_destination_metrics.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/utils/get_span_destination_metrics.ts rename to packages/elastic-apm-synthtrace/src/lib/utils/get_span_destination_metrics.ts diff --git a/packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts b/packages/elastic-apm-synthtrace/src/lib/utils/get_transaction_metrics.ts similarity index 100% rename from packages/elastic-apm-generator/src/lib/utils/get_transaction_metrics.ts rename to packages/elastic-apm-synthtrace/src/lib/utils/get_transaction_metrics.ts diff --git a/packages/elastic-apm-generator/src/scripts/examples/01_simple_trace.ts b/packages/elastic-apm-synthtrace/src/scripts/examples/01_simple_trace.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/examples/01_simple_trace.ts rename to packages/elastic-apm-synthtrace/src/scripts/examples/01_simple_trace.ts diff --git a/packages/elastic-apm-generator/src/scripts/run.js b/packages/elastic-apm-synthtrace/src/scripts/run.js similarity index 100% rename from packages/elastic-apm-generator/src/scripts/run.js rename to packages/elastic-apm-synthtrace/src/scripts/run.js diff --git a/packages/elastic-apm-generator/src/scripts/run.ts b/packages/elastic-apm-synthtrace/src/scripts/run.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/run.ts rename to packages/elastic-apm-synthtrace/src/scripts/run.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/clean_write_targets.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/clean_write_targets.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/clean_write_targets.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/clean_write_targets.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/common_options.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/common_options.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/common_options.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/common_options.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/get_common_resources.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/get_common_resources.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/get_common_resources.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/get_common_resources.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/get_scenario.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/get_scenario.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/get_scenario.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/get_scenario.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/get_write_targets.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/get_write_targets.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/get_write_targets.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/get_write_targets.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/interval_to_ms.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/interval_to_ms.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/interval_to_ms.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/interval_to_ms.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/logger.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/logger.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/logger.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/logger.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/start_historical_data_upload.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/start_historical_data_upload.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/start_historical_data_upload.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/start_historical_data_upload.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/start_live_data_upload.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/start_live_data_upload.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/start_live_data_upload.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/start_live_data_upload.ts diff --git a/packages/elastic-apm-generator/src/scripts/utils/upload_events.ts b/packages/elastic-apm-synthtrace/src/scripts/utils/upload_events.ts similarity index 100% rename from packages/elastic-apm-generator/src/scripts/utils/upload_events.ts rename to packages/elastic-apm-synthtrace/src/scripts/utils/upload_events.ts diff --git a/packages/elastic-apm-generator/src/test/scenarios/01_simple_trace.test.ts b/packages/elastic-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts similarity index 100% rename from packages/elastic-apm-generator/src/test/scenarios/01_simple_trace.test.ts rename to packages/elastic-apm-synthtrace/src/test/scenarios/01_simple_trace.test.ts diff --git a/packages/elastic-apm-generator/src/test/scenarios/02_transaction_metrics.test.ts b/packages/elastic-apm-synthtrace/src/test/scenarios/02_transaction_metrics.test.ts similarity index 100% rename from packages/elastic-apm-generator/src/test/scenarios/02_transaction_metrics.test.ts rename to packages/elastic-apm-synthtrace/src/test/scenarios/02_transaction_metrics.test.ts diff --git a/packages/elastic-apm-generator/src/test/scenarios/03_span_destination_metrics.test.ts b/packages/elastic-apm-synthtrace/src/test/scenarios/03_span_destination_metrics.test.ts similarity index 100% rename from packages/elastic-apm-generator/src/test/scenarios/03_span_destination_metrics.test.ts rename to packages/elastic-apm-synthtrace/src/test/scenarios/03_span_destination_metrics.test.ts diff --git a/packages/elastic-apm-generator/src/test/scenarios/04_breakdown_metrics.test.ts b/packages/elastic-apm-synthtrace/src/test/scenarios/04_breakdown_metrics.test.ts similarity index 100% rename from packages/elastic-apm-generator/src/test/scenarios/04_breakdown_metrics.test.ts rename to packages/elastic-apm-synthtrace/src/test/scenarios/04_breakdown_metrics.test.ts diff --git a/packages/elastic-apm-generator/src/test/scenarios/05_transactions_with_errors.test.ts b/packages/elastic-apm-synthtrace/src/test/scenarios/05_transactions_with_errors.test.ts similarity index 100% rename from packages/elastic-apm-generator/src/test/scenarios/05_transactions_with_errors.test.ts rename to packages/elastic-apm-synthtrace/src/test/scenarios/05_transactions_with_errors.test.ts diff --git a/packages/elastic-apm-generator/src/test/scenarios/06_application_metrics.test.ts b/packages/elastic-apm-synthtrace/src/test/scenarios/06_application_metrics.test.ts similarity index 100% rename from packages/elastic-apm-generator/src/test/scenarios/06_application_metrics.test.ts rename to packages/elastic-apm-synthtrace/src/test/scenarios/06_application_metrics.test.ts diff --git a/packages/elastic-apm-generator/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap b/packages/elastic-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap similarity index 100% rename from packages/elastic-apm-generator/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap rename to packages/elastic-apm-synthtrace/src/test/scenarios/__snapshots__/01_simple_trace.test.ts.snap diff --git a/packages/elastic-apm-generator/src/test/to_elasticsearch_output.test.ts b/packages/elastic-apm-synthtrace/src/test/to_elasticsearch_output.test.ts similarity index 100% rename from packages/elastic-apm-generator/src/test/to_elasticsearch_output.test.ts rename to packages/elastic-apm-synthtrace/src/test/to_elasticsearch_output.test.ts diff --git a/packages/elastic-apm-generator/tsconfig.json b/packages/elastic-apm-synthtrace/tsconfig.json similarity index 60% rename from packages/elastic-apm-generator/tsconfig.json rename to packages/elastic-apm-synthtrace/tsconfig.json index 534e8481dce9ad..6ae9c20b4387ba 100644 --- a/packages/elastic-apm-generator/tsconfig.json +++ b/packages/elastic-apm-synthtrace/tsconfig.json @@ -7,13 +7,8 @@ "outDir": "target_types", "rootDir": "./src", "sourceMap": true, - "sourceRoot": "../../../../packages/elastic-apm-generator/src", - "types": [ - "node", - "jest" - ] + "sourceRoot": "../../../../packages/elastic-apm-synthtrace/src", + "types": ["node", "jest"] }, - "include": [ - "./src/**/*.ts" - ] + "include": ["./src/**/*.ts"] } diff --git a/x-pack/test/apm_api_integration/common/trace_data.ts b/x-pack/test/apm_api_integration/common/trace_data.ts index 9799e111cb1353..4e813efab29130 100644 --- a/x-pack/test/apm_api_integration/common/trace_data.ts +++ b/x-pack/test/apm_api_integration/common/trace_data.ts @@ -10,7 +10,7 @@ import { getSpanDestinationMetrics, getTransactionMetrics, toElasticsearchOutput, -} from '@elastic/apm-generator'; +} from '@elastic/apm-synthtrace'; import { chunk } from 'lodash'; import pLimit from 'p-limit'; import { inspect } from 'util'; diff --git a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts b/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts index 75ea10ed4d9d4b..ac81b6d5a4412a 100644 --- a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { service, timerange } from '@elastic/apm-generator'; +import { service, timerange } from '@elastic/apm-synthtrace'; import expect from '@kbn/expect'; import { mean, meanBy, sumBy } from 'lodash'; import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_aggregation_types'; diff --git a/x-pack/test/apm_api_integration/tests/latency/service_apis.ts b/x-pack/test/apm_api_integration/tests/latency/service_apis.ts index a09442cd73a2a0..c6ecf9e4a4abab 100644 --- a/x-pack/test/apm_api_integration/tests/latency/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/latency/service_apis.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { service, timerange } from '@elastic/apm-generator'; +import { service, timerange } from '@elastic/apm-synthtrace'; import expect from '@kbn/expect'; import { meanBy, sumBy } from 'lodash'; import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_aggregation_types'; diff --git a/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts b/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts index 458372196452a8..af95f981a3dc5f 100644 --- a/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts +++ b/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { service, timerange } from '@elastic/apm-generator'; +import { service, timerange } from '@elastic/apm-synthtrace'; import expect from '@kbn/expect'; import { meanBy, sumBy } from 'lodash'; import { FtrProviderContext } from '../../common/ftr_provider_context'; diff --git a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts index 5585a292d317eb..68979795f9dcf0 100644 --- a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts @@ -8,7 +8,7 @@ import expect from '@kbn/expect'; import { pick, sortBy } from 'lodash'; import moment from 'moment'; -import { service, timerange } from '@elastic/apm-generator'; +import { service, timerange } from '@elastic/apm-synthtrace'; import { APIReturnType } from '../../../../plugins/apm/public/services/rest/createCallApmApi'; import { isFiniteNumber } from '../../../../plugins/apm/common/utils/is_finite_number'; import { FtrProviderContext } from '../../common/ftr_provider_context'; diff --git a/x-pack/test/apm_api_integration/tests/services/throughput.ts b/x-pack/test/apm_api_integration/tests/services/throughput.ts index 561680e2725cfa..e98ab60af8ca49 100644 --- a/x-pack/test/apm_api_integration/tests/services/throughput.ts +++ b/x-pack/test/apm_api_integration/tests/services/throughput.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { service, timerange } from '@elastic/apm-generator'; +import { service, timerange } from '@elastic/apm-synthtrace'; import expect from '@kbn/expect'; import { first, last, meanBy } from 'lodash'; import moment from 'moment'; diff --git a/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts b/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts index 4b3820ee7f0332..4df40d1d85d564 100644 --- a/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts +++ b/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { service, timerange } from '@elastic/apm-generator'; +import { service, timerange } from '@elastic/apm-synthtrace'; import expect from '@kbn/expect'; import { meanBy, sumBy } from 'lodash'; import { BackendNode, ServiceNode } from '../../../../plugins/apm/common/connections'; diff --git a/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts b/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts index 6bf0e8c14fb23f..00e5e57c546dd7 100644 --- a/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { service, timerange } from '@elastic/apm-generator'; +import { service, timerange } from '@elastic/apm-synthtrace'; import expect from '@kbn/expect'; import { meanBy, sumBy } from 'lodash'; import { LatencyAggregationType } from '../../../../plugins/apm/common/latency_aggregation_types'; diff --git a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts index 100d3c306b7dea..acdd12f3501bff 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { service, timerange } from '@elastic/apm-generator'; +import { service, timerange } from '@elastic/apm-synthtrace'; import expect from '@kbn/expect'; import { first, isEmpty, last, meanBy } from 'lodash'; import moment from 'moment'; diff --git a/yarn.lock b/yarn.lock index a36d8e9373685d..04e303975b9c76 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2302,7 +2302,7 @@ is-absolute "^1.0.0" is-negated-glob "^1.0.0" -"@elastic/apm-generator@link:bazel-bin/packages/elastic-apm-generator": +"@elastic/apm-synthtrace@link:bazel-bin/packages/elastic-apm-synthtrace": version "0.0.0" uid "" From 74bc51ea7c2befe22ab11280c57f3e91053b204a Mon Sep 17 00:00:00 2001 From: Chris Cowan Date: Mon, 25 Oct 2021 14:50:02 -0600 Subject: [PATCH 43/66] [Metrics UI] Ensure Kubernetes Pod CPU Usage is consistent across pages (#116177) --- .../pod/metrics/tsvb/pod_overview.ts | 32 +++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/infra/common/inventory_models/pod/metrics/tsvb/pod_overview.ts b/x-pack/plugins/infra/common/inventory_models/pod/metrics/tsvb/pod_overview.ts index 5746410f03388f..0fe94c7f53dab8 100644 --- a/x-pack/plugins/infra/common/inventory_models/pod/metrics/tsvb/pod_overview.ts +++ b/x-pack/plugins/infra/common/inventory_models/pod/metrics/tsvb/pod_overview.ts @@ -25,9 +25,23 @@ export const podOverview: TSVBMetricModelCreator = ( metrics: [ { field: 'kubernetes.pod.cpu.usage.node.pct', - id: 'avg-cpu-usage', + id: 'avg-cpu-without', type: 'avg', }, + { + field: 'kubernetes.pod.cpu.usage.limit.pct', + id: 'avg-cpu-with', + type: 'avg', + }, + { + id: 'cpu-usage', + type: 'calculation', + variables: [ + { id: 'cpu_with', name: 'with_limit', field: 'avg-cpu-with' }, + { id: 'cpu_without', name: 'without_limit', field: 'avg-cpu-without' }, + ], + script: 'params.with_limit > 0.0 ? params.with_limit : params.without_limit', + }, ], }, { @@ -36,9 +50,23 @@ export const podOverview: TSVBMetricModelCreator = ( metrics: [ { field: 'kubernetes.pod.memory.usage.node.pct', - id: 'avg-memory-usage', + id: 'avg-memory-without', type: 'avg', }, + { + field: 'kubernetes.pod.memory.usage.limit.pct', + id: 'avg-memory-with', + type: 'avg', + }, + { + id: 'memory-usage', + type: 'calculation', + variables: [ + { id: 'memory_with', name: 'with_limit', field: 'avg-memory-with' }, + { id: 'memory_without', name: 'without_limit', field: 'avg-memory-without' }, + ], + script: 'params.with_limit > 0.0 ? params.with_limit : params.without_limit', + }, ], }, { From 106183551a69399d93d1a6686640ab1b1640f249 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Mon, 25 Oct 2021 23:25:24 +0200 Subject: [PATCH 44/66] [8.0] remove `kibana.index` config property (#112773) * remove kibana config * remove kibanaConfig usages * prettier fix * fix some globalConfig.kibana.index access * fix xpack_legacy globalConfig usage * fix home globalConfig usage * fix canvas globalConfig usage * fix action globalConfig usage * fix (all?) remaining usages * fix more plugins * fix more plugins bis * yet more usages * fix ml usages * fix security_solution * fix lens * fix monitoring * remove from settings docs * move doc update * fix unit tests * update generated doc * improve test * adapt new usage in security_solution * fix security_solution config * fix createConfig, again * fix mock config --- config/kibana.yml | 4 -- ...savedobjectsservicesetup.getkibanaindex.md | 13 +++++ ...in-core-server.savedobjectsservicesetup.md | 1 + ...a-plugin-core-server.sharedglobalconfig.md | 1 - docs/setup/settings.asciidoc | 12 ----- .../setup/upgrade/upgrade-migrations.asciidoc | 4 +- src/core/public/public.api.md | 1 - .../core_usage_data_service.test.ts | 3 -- .../core_usage_data_service.ts | 34 +++---------- src/core/server/kibana_config.test.ts | 42 --------------- src/core/server/kibana_config.ts | 51 ------------------- src/core/server/mocks.ts | 3 -- src/core/server/plugins/legacy_config.test.ts | 6 --- src/core/server/plugins/legacy_config.ts | 9 +--- .../server/plugins/plugin_context.test.ts | 3 -- src/core/server/plugins/plugin_context.ts | 1 + src/core/server/plugins/types.ts | 3 -- .../deprecations/deprecation_factory.ts | 3 +- .../deprecations/unknown_object_types.test.ts | 16 ++---- .../deprecations/unknown_object_types.ts | 19 ++++--- .../migrations/kibana/kibana_migrator.test.ts | 6 +-- .../migrations/kibana/kibana_migrator.ts | 12 ++--- .../deprecations/delete_unknown_types.ts | 7 ++- src/core/server/saved_objects/routes/index.ts | 7 ++- .../delete_unknown_types.test.ts | 8 +-- .../saved_objects_service.mock.ts | 3 ++ .../saved_objects/saved_objects_service.ts | 28 +++++----- src/core/server/server.api.md | 9 ++-- src/core/server/server.ts | 2 - .../kql_telemetry/kql_telemetry_service.ts | 17 +++---- .../make_kql_usage_collector.ts | 5 +- .../data/server/search/collectors/fetch.ts | 9 ++-- .../data/server/search/collectors/register.ts | 8 +-- .../data/server/search/search_service.ts | 2 +- .../sample_data/sample_data_registry.ts | 3 +- .../services/sample_data/usage/collector.ts | 8 +-- .../kibana_usage_collector.test.ts | 10 ++-- .../kibana_usage_collector.ts | 13 ++--- .../saved_objects_count_collector.test.ts | 5 +- .../saved_objects_count_collector.ts | 10 +--- .../kibana_usage_collection/server/plugin.ts | 10 ++-- src/plugins/usage_collection/server/plugin.ts | 4 +- x-pack/plugins/actions/server/plugin.ts | 24 +++++---- x-pack/plugins/alerting/server/plugin.ts | 18 +++---- x-pack/plugins/canvas/server/plugin.ts | 6 +-- .../server/collectors/fetch.test.ts | 10 +--- .../data_enhanced/server/collectors/fetch.ts | 9 ++-- .../server/collectors/register.ts | 8 +-- x-pack/plugins/data_enhanced/server/plugin.ts | 2 +- x-pack/plugins/event_log/server/plugin.ts | 5 +- x-pack/plugins/lens/server/plugin.tsx | 11 +--- x-pack/plugins/lens/server/usage/task.ts | 16 ++---- x-pack/plugins/ml/server/plugin.ts | 6 +-- x-pack/plugins/monitoring/server/plugin.ts | 2 +- x-pack/plugins/rollup/server/plugin.ts | 28 +++------- x-pack/plugins/rule_registry/server/plugin.ts | 21 +------- .../saved_objects_tagging/server/index.ts | 2 +- .../server/plugin.test.ts | 2 +- .../saved_objects_tagging/server/plugin.ts | 17 +------ .../server/usage/tag_usage_collector.ts | 12 ++--- x-pack/plugins/security/server/plugin.ts | 8 +-- .../security_solution/server/config.mock.ts | 1 - .../security_solution/server/config.ts | 5 -- .../security_solution/server/plugin.ts | 7 ++- x-pack/plugins/spaces/server/plugin.ts | 5 +- .../spaces_usage_collector.test.ts | 18 +++---- .../spaces_usage_collector.ts | 7 +-- 67 files changed, 188 insertions(+), 477 deletions(-) create mode 100644 docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md delete mode 100644 src/core/server/kibana_config.test.ts delete mode 100644 src/core/server/kibana_config.ts diff --git a/config/kibana.yml b/config/kibana.yml index 8338a148ef1762..eeb7c84df43183 100644 --- a/config/kibana.yml +++ b/config/kibana.yml @@ -31,10 +31,6 @@ # The URLs of the Elasticsearch instances to use for all your queries. #elasticsearch.hosts: ["http://localhost:9200"] -# Kibana uses an index in Elasticsearch to store saved searches, visualizations and -# dashboards. Kibana creates a new index if the index doesn't already exist. -#kibana.index: ".kibana" - # If your Elasticsearch is protected with basic authentication, these settings provide # the username and password that the Kibana server uses to perform maintenance on the Kibana # index at startup. Your Kibana users still need to authenticate with Elasticsearch, which diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md new file mode 100644 index 00000000000000..9319ae987ad444 --- /dev/null +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md @@ -0,0 +1,13 @@ + + +[Home](./index.md) > [kibana-plugin-core-server](./kibana-plugin-core-server.md) > [SavedObjectsServiceSetup](./kibana-plugin-core-server.savedobjectsservicesetup.md) > [getKibanaIndex](./kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md) + +## SavedObjectsServiceSetup.getKibanaIndex property + +Returns the default index used for saved objects. + +Signature: + +```typescript +getKibanaIndex: () => string; +``` diff --git a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md index a1bc99ce8d13dc..336d9f63f0cede 100644 --- a/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md +++ b/docs/development/core/server/kibana-plugin-core-server.savedobjectsservicesetup.md @@ -52,6 +52,7 @@ export class Plugin() { | Property | Type | Description | | --- | --- | --- | | [addClientWrapper](./kibana-plugin-core-server.savedobjectsservicesetup.addclientwrapper.md) | (priority: number, id: string, factory: SavedObjectsClientWrapperFactory) => void | Add a [client wrapper factory](./kibana-plugin-core-server.savedobjectsclientwrapperfactory.md) with the given priority. | +| [getKibanaIndex](./kibana-plugin-core-server.savedobjectsservicesetup.getkibanaindex.md) | () => string | Returns the default index used for saved objects. | | [registerType](./kibana-plugin-core-server.savedobjectsservicesetup.registertype.md) | <Attributes = any>(type: SavedObjectsType<Attributes>) => void | Register a [savedObjects type](./kibana-plugin-core-server.savedobjectstype.md) definition.See the [mappings format](./kibana-plugin-core-server.savedobjectstypemappingdefinition.md) and [migration format](./kibana-plugin-core-server.savedobjectmigrationmap.md) for more details about these. | | [setClientFactoryProvider](./kibana-plugin-core-server.savedobjectsservicesetup.setclientfactoryprovider.md) | (clientFactoryProvider: SavedObjectsClientFactoryProvider) => void | Set the default [factory provider](./kibana-plugin-core-server.savedobjectsclientfactoryprovider.md) for creating Saved Objects clients. Only one provider can be set, subsequent calls to this method will fail. | diff --git a/docs/development/core/server/kibana-plugin-core-server.sharedglobalconfig.md b/docs/development/core/server/kibana-plugin-core-server.sharedglobalconfig.md index ec2e1b227a2d7b..477cd5a651a56a 100644 --- a/docs/development/core/server/kibana-plugin-core-server.sharedglobalconfig.md +++ b/docs/development/core/server/kibana-plugin-core-server.sharedglobalconfig.md @@ -9,7 +9,6 @@ ```typescript export declare type SharedGlobalConfig = RecursiveReadonly<{ - kibana: Pick; elasticsearch: Pick; path: Pick; savedObjects: Pick; diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index 7235c2a6733766..6ff5556c331a20 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -285,18 +285,6 @@ is an alternative to `elasticsearch.username` and `elasticsearch.password`. | `interpreter.enableInVisualize` | Enables use of interpreter in Visualize. *Default: `true`* -|[[kibana-index]] `kibana.index:` - | deprecated:[7.11.0,This setting will be removed in 8.0.] Multitenancy by - changing `kibana.index` will not be supported starting in 8.0. See - https://ela.st/kbn-remove-legacy-multitenancy[8.0 Breaking Changes] for more - details. - + - {kib} uses an index in {es} to store saved searches, visualizations, and - dashboards. {kib} creates a new index if the index doesn’t already exist. If - you configure a custom index, the name must be lowercase, and conform to the - {es} {ref}/indices-create-index.html[index name limitations]. - *Default: `".kibana"`* - | `data.autocomplete.valueSuggestions.timeout:` {ess-icon} | Time in milliseconds to wait for autocomplete suggestions from {es}. This value must be a whole number greater than zero. *Default: `"1000"`* diff --git a/docs/setup/upgrade/upgrade-migrations.asciidoc b/docs/setup/upgrade/upgrade-migrations.asciidoc index 947043b21ef501..adf86d2b2b5428 100644 --- a/docs/setup/upgrade/upgrade-migrations.asciidoc +++ b/docs/setup/upgrade/upgrade-migrations.asciidoc @@ -16,8 +16,8 @@ WARNING: The following instructions assumes {kib} is using the default index nam Saved objects are stored in two indices: -* `.kibana_{kibana_version}_001`, or if the `kibana.index` configuration setting is set `.{kibana.index}_{kibana_version}_001`. E.g. for Kibana v7.12.0 `.kibana_7.12.0_001`. -* `.kibana_task_manager_{kibana_version}_001`, or if the `xpack.tasks.index` configuration setting is set `.{xpack.tasks.index}_{kibana_version}_001` E.g. for Kibana v7.12.0 `.kibana_task_manager_7.12.0_001`. +* `.kibana_{kibana_version}_001`, e.g. for Kibana v7.12.0 `.kibana_7.12.0_001`. +* `.kibana_task_manager_{kibana_version}_001`, e.g. for Kibana v7.12.0 `.kibana_task_manager_7.12.0_001`. The index aliases `.kibana` and `.kibana_task_manager` will always point to the most up-to-date saved object indices. diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index bd274d7994bfa7..1992b2d9686acc 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -7,7 +7,6 @@ import { Action } from 'history'; import { ApiResponse } from '@elastic/elasticsearch/lib/Transport'; import Boom from '@hapi/boom'; -import { ConfigDeprecationProvider } from '@kbn/config'; import { ConfigPath } from '@kbn/config'; import { DetailedPeerCertificate } from 'tls'; import { EnvironmentMode } from '@kbn/config'; diff --git a/src/core/server/core_usage_data/core_usage_data_service.test.ts b/src/core/server/core_usage_data/core_usage_data_service.test.ts index 3c05069d3cd079..209aece3f57197 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.test.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.test.ts @@ -17,7 +17,6 @@ import { mockCoreContext } from '../core_context.mock'; import { config as RawElasticsearchConfig } from '../elasticsearch/elasticsearch_config'; import { config as RawHttpConfig } from '../http/http_config'; import { config as RawLoggingConfig } from '../logging/logging_config'; -import { config as RawKibanaConfig } from '../kibana_config'; import { savedObjectsConfig as RawSavedObjectsConfig } from '../saved_objects/saved_objects_config'; import { httpServiceMock } from '../http/http_service.mock'; import { metricsServiceMock } from '../metrics/metrics_service.mock'; @@ -40,8 +39,6 @@ describe('CoreUsageDataService', () => { return new BehaviorSubject(RawLoggingConfig.schema.validate({})); } else if (path === 'savedObjects') { return new BehaviorSubject(RawSavedObjectsConfig.schema.validate({})); - } else if (path === 'kibana') { - return new BehaviorSubject(RawKibanaConfig.schema.validate({})); } return new BehaviorSubject({}); }; diff --git a/src/core/server/core_usage_data/core_usage_data_service.ts b/src/core/server/core_usage_data/core_usage_data_service.ts index 72b70824d305dd..22dafc7e44e06e 100644 --- a/src/core/server/core_usage_data/core_usage_data_service.ts +++ b/src/core/server/core_usage_data/core_usage_data_service.ts @@ -33,7 +33,6 @@ import type { } from './types'; import { isConfigured } from './is_configured'; import { ElasticsearchServiceStart } from '../elasticsearch'; -import { KibanaConfigType } from '../kibana_config'; import { coreUsageStatsType } from './core_usage_stats'; import { LEGACY_URL_ALIAS_TYPE } from '../saved_objects/object_types'; import { CORE_USAGE_STATS_TYPE } from './constants'; @@ -56,6 +55,8 @@ export interface StartDeps { exposedConfigsToUsage: ExposedConfigsToUsage; } +const kibanaIndex = '.kibana'; + /** * Because users can configure their Saved Object to any arbitrary index name, * we need to map customized index names back to a "standard" index name. @@ -74,19 +75,6 @@ const kibanaOrTaskManagerIndex = (index: string, kibanaConfigIndex: string) => { return index === kibanaConfigIndex ? '.kibana' : '.kibana_task_manager'; }; -/** - * This is incredibly hacky... The config service doesn't allow you to determine - * whether or not a config value has been changed from the default value, and the - * default value is defined in legacy code. - * - * This will be going away in 8.0, so please look away for a few months - * - * @param index The `kibana.index` setting from the `kibana.yml` - */ -const isCustomIndex = (index: string) => { - return index !== '.kibana'; -}; - export class CoreUsageDataService implements CoreService { @@ -98,7 +86,6 @@ export class CoreUsageDataService private soConfig?: SavedObjectsConfigType; private stop$: Subject; private opsMetrics?: OpsMetrics; - private kibanaConfig?: KibanaConfigType; private coreUsageStatsClient?: CoreUsageStatsClient; private deprecatedConfigPaths: ChangedDeprecatedPaths = { set: [], unset: [] }; private incrementUsageCounter: CoreIncrementUsageCounter = () => {}; // Initially set to noop @@ -133,8 +120,8 @@ export class CoreUsageDataService .getTypeRegistry() .getAllTypes() .reduce((acc, type) => { - const index = type.indexPattern ?? this.kibanaConfig!.index; - return index != null ? acc.add(index) : acc; + const index = type.indexPattern ?? kibanaIndex; + return acc.add(index); }, new Set()) .values() ).map((index) => { @@ -150,7 +137,7 @@ export class CoreUsageDataService .then(({ body }) => { const stats = body[0]; return { - alias: kibanaOrTaskManagerIndex(index, this.kibanaConfig!.index), + alias: kibanaOrTaskManagerIndex(index, kibanaIndex), docsCount: stats['docs.count'] ? parseInt(stats['docs.count'], 10) : 0, docsDeleted: stats['docs.deleted'] ? parseInt(stats['docs.deleted'], 10) : 0, storeSizeBytes: stats['store.size'] ? parseInt(stats['store.size'], 10) : 0, @@ -167,7 +154,7 @@ export class CoreUsageDataService // Note: this agg can be changed to use `savedObjectsRepository.find` in the future after `filters` is supported. // See src/core/server/saved_objects/service/lib/aggregations/aggs_types/bucket_aggs.ts for supported aggregations. const { body: resp } = await elasticsearch.client.asInternalUser.search({ - index: this.kibanaConfig!.index, + index: kibanaIndex, body: { track_total_hits: true, query: { match: { type: LEGACY_URL_ALIAS_TYPE } }, @@ -313,7 +300,7 @@ export class CoreUsageDataService }, savedObjects: { - customIndex: isCustomIndex(this.kibanaConfig!.index), + customIndex: false, maxImportPayloadBytes: this.soConfig.maxImportPayloadBytes.getValueInBytes(), maxImportExportSize: this.soConfig.maxImportExportSize, }, @@ -472,13 +459,6 @@ export class CoreUsageDataService this.soConfig = config; }); - this.configService - .atPath('kibana') - .pipe(takeUntil(this.stop$)) - .subscribe((config) => { - this.kibanaConfig = config; - }); - changedDeprecatedConfigPath$ .pipe(takeUntil(this.stop$)) .subscribe((deprecatedConfigPaths) => (this.deprecatedConfigPaths = deprecatedConfigPaths)); diff --git a/src/core/server/kibana_config.test.ts b/src/core/server/kibana_config.test.ts deleted file mode 100644 index 72ddb3b65081b5..00000000000000 --- a/src/core/server/kibana_config.test.ts +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { config } from './kibana_config'; -import { getDeprecationsFor } from './config/test_utils'; - -const CONFIG_PATH = 'kibana'; - -const applyKibanaDeprecations = (settings: Record = {}) => - getDeprecationsFor({ - provider: config.deprecations!, - settings, - path: CONFIG_PATH, - }); - -it('set correct defaults ', () => { - const configValue = config.schema.validate({}); - expect(configValue).toMatchInlineSnapshot(` - Object { - "enabled": true, - "index": ".kibana", - } - `); -}); - -describe('deprecations', () => { - ['.foo', '.kibana'].forEach((index) => { - it('logs a warning if index is set', () => { - const { messages } = applyKibanaDeprecations({ index }); - expect(messages).toMatchInlineSnapshot(` - Array [ - "\\"kibana.index\\" is deprecated. Multitenancy by changing \\"kibana.index\\" will not be supported starting in 8.0. See https://ela.st/kbn-remove-legacy-multitenancy for more details", - ] - `); - }); - }); -}); diff --git a/src/core/server/kibana_config.ts b/src/core/server/kibana_config.ts deleted file mode 100644 index 859f25d7082f11..00000000000000 --- a/src/core/server/kibana_config.ts +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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 and the Server Side Public License, v 1; you may not use this file except - * in compliance with, at your election, the Elastic License 2.0 or the Server - * Side Public License, v 1. - */ - -import { i18n } from '@kbn/i18n'; -import { schema, TypeOf } from '@kbn/config-schema'; -import { ConfigDeprecationProvider } from '@kbn/config'; - -export type KibanaConfigType = TypeOf; - -const deprecations: ConfigDeprecationProvider = () => [ - (settings, fromPath, addDeprecation) => { - const kibana = settings[fromPath]; - if (kibana?.index) { - addDeprecation({ - configPath: 'kibana.index', - title: i18n.translate('core.kibana.index.deprecationTitle', { - defaultMessage: `Setting "kibana.index" is deprecated`, - }), - message: i18n.translate('core.kibana.index.deprecationMessage', { - defaultMessage: `"kibana.index" is deprecated. Multitenancy by changing "kibana.index" will not be supported starting in 8.0. See https://ela.st/kbn-remove-legacy-multitenancy for more details`, - }), - documentationUrl: 'https://ela.st/kbn-remove-legacy-multitenancy', - correctiveActions: { - manualSteps: [ - i18n.translate('core.kibana.index.deprecationManualStep1', { - defaultMessage: `If you rely on this setting to achieve multitenancy you should use Spaces, cross-cluster replication, or cross-cluster search instead.`, - }), - i18n.translate('core.kibana.index.deprecationManualStep2', { - defaultMessage: `To migrate to Spaces, we encourage using saved object management to export your saved objects from a tenant into the default tenant in a space.`, - }), - ], - }, - }); - } - return settings; - }, -]; - -export const config = { - path: 'kibana', - schema: schema.object({ - enabled: schema.boolean({ defaultValue: true }), - index: schema.string({ defaultValue: '.kibana' }), - }), - deprecations, -}; diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 8b4dee45a8e72c..a2787369bd5343 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -65,9 +65,6 @@ type MockedPluginInitializerConfig = jest.Mocked[ export function pluginInitializerContextConfigMock(config: T) { const globalConfig: SharedGlobalConfig = { - kibana: { - index: '.kibana-tests', - }, elasticsearch: { shardTimeout: duration('30s'), requestTimeout: duration('30s'), diff --git a/src/core/server/plugins/legacy_config.test.ts b/src/core/server/plugins/legacy_config.test.ts index 2a980e38a4e191..af8cff843edf08 100644 --- a/src/core/server/plugins/legacy_config.test.ts +++ b/src/core/server/plugins/legacy_config.test.ts @@ -41,9 +41,6 @@ describe('Legacy config', () => { const legacyConfig = getGlobalConfig(configService); expect(legacyConfig).toStrictEqual({ - kibana: { - index: '.kibana', - }, elasticsearch: { shardTimeout: duration(30, 's'), requestTimeout: duration(30, 's'), @@ -62,9 +59,6 @@ describe('Legacy config', () => { const legacyConfig = await getGlobalConfig$(configService).pipe(take(1)).toPromise(); expect(legacyConfig).toStrictEqual({ - kibana: { - index: '.kibana', - }, elasticsearch: { shardTimeout: duration(30, 's'), requestTimeout: duration(30, 's'), diff --git a/src/core/server/plugins/legacy_config.ts b/src/core/server/plugins/legacy_config.ts index f7e22cb4b376a8..9dc4afc37515a1 100644 --- a/src/core/server/plugins/legacy_config.ts +++ b/src/core/server/plugins/legacy_config.ts @@ -13,7 +13,6 @@ import { pick, deepFreeze } from '@kbn/std'; import { IConfigService } from '@kbn/config'; import { SharedGlobalConfig, SharedGlobalConfigKeys } from './types'; -import { KibanaConfigType, config as kibanaConfig } from '../kibana_config'; import { ElasticsearchConfigType, config as elasticsearchConfig, @@ -21,18 +20,15 @@ import { import { SavedObjectsConfigType, savedObjectsConfig } from '../saved_objects/saved_objects_config'; const createGlobalConfig = ({ - kibana, elasticsearch, path, savedObjects, }: { - kibana: KibanaConfigType; elasticsearch: ElasticsearchConfigType; path: PathConfigType; savedObjects: SavedObjectsConfigType; }): SharedGlobalConfig => { return deepFreeze({ - kibana: pick(kibana, SharedGlobalConfigKeys.kibana), elasticsearch: pick(elasticsearch, SharedGlobalConfigKeys.elasticsearch), path: pick(path, SharedGlobalConfigKeys.path), savedObjects: pick(savedObjects, SharedGlobalConfigKeys.savedObjects), @@ -41,7 +37,6 @@ const createGlobalConfig = ({ export const getGlobalConfig = (configService: IConfigService): SharedGlobalConfig => { return createGlobalConfig({ - kibana: configService.atPathSync(kibanaConfig.path), elasticsearch: configService.atPathSync(elasticsearchConfig.path), path: configService.atPathSync(pathConfig.path), savedObjects: configService.atPathSync(savedObjectsConfig.path), @@ -50,15 +45,13 @@ export const getGlobalConfig = (configService: IConfigService): SharedGlobalConf export const getGlobalConfig$ = (configService: IConfigService): Observable => { return combineLatest([ - configService.atPath(kibanaConfig.path), configService.atPath(elasticsearchConfig.path), configService.atPath(pathConfig.path), configService.atPath(savedObjectsConfig.path), ]).pipe( map( - ([kibana, elasticsearch, path, savedObjects]) => + ([elasticsearch, path, savedObjects]) => createGlobalConfig({ - kibana, elasticsearch, path, savedObjects, diff --git a/src/core/server/plugins/plugin_context.test.ts b/src/core/server/plugins/plugin_context.test.ts index 00da0fa43c40f2..867d4d978314bc 100644 --- a/src/core/server/plugins/plugin_context.test.ts +++ b/src/core/server/plugins/plugin_context.test.ts @@ -124,9 +124,6 @@ describe('createPluginInitializerContext', () => { .pipe(first()) .toPromise(); expect(configObject).toStrictEqual({ - kibana: { - index: '.kibana', - }, elasticsearch: { shardTimeout: duration(30, 's'), requestTimeout: duration(30, 's'), diff --git a/src/core/server/plugins/plugin_context.ts b/src/core/server/plugins/plugin_context.ts index bdb4efde9b1fb1..28382d62e4ba78 100644 --- a/src/core/server/plugins/plugin_context.ts +++ b/src/core/server/plugins/plugin_context.ts @@ -197,6 +197,7 @@ export function createPluginSetupContext( setClientFactoryProvider: deps.savedObjects.setClientFactoryProvider, addClientWrapper: deps.savedObjects.addClientWrapper, registerType: deps.savedObjects.registerType, + getKibanaIndex: deps.savedObjects.getKibanaIndex, }, status: { core$: deps.status.core$, diff --git a/src/core/server/plugins/types.ts b/src/core/server/plugins/types.ts index a2e460a3e3c679..1d0dc62864fc98 100644 --- a/src/core/server/plugins/types.ts +++ b/src/core/server/plugins/types.ts @@ -13,7 +13,6 @@ import { PathConfigType } from '@kbn/utils'; import { ConfigPath, EnvironmentMode, PackageInfo, ConfigDeprecationProvider } from '../config'; import { LoggerFactory } from '../logging'; -import { KibanaConfigType } from '../kibana_config'; import { ElasticsearchConfigType } from '../elasticsearch/elasticsearch_config'; import { SavedObjectsConfigType } from '../saved_objects/saved_objects_config'; import { CorePreboot, CoreSetup, CoreStart } from '..'; @@ -364,7 +363,6 @@ export interface AsyncPlugin< export const SharedGlobalConfigKeys = { // We can add more if really needed - kibana: ['index'] as const, elasticsearch: ['shardTimeout', 'requestTimeout', 'pingTimeout'] as const, path: ['data'] as const, savedObjects: ['maxImportPayloadBytes'] as const, @@ -374,7 +372,6 @@ export const SharedGlobalConfigKeys = { * @public */ export type SharedGlobalConfig = RecursiveReadonly<{ - kibana: Pick; elasticsearch: Pick; path: Pick; savedObjects: Pick; diff --git a/src/core/server/saved_objects/deprecations/deprecation_factory.ts b/src/core/server/saved_objects/deprecations/deprecation_factory.ts index 670b43bfa7c771..60ee1b0193362d 100644 --- a/src/core/server/saved_objects/deprecations/deprecation_factory.ts +++ b/src/core/server/saved_objects/deprecations/deprecation_factory.ts @@ -9,13 +9,12 @@ import type { RegisterDeprecationsConfig } from '../../deprecations'; import type { ISavedObjectTypeRegistry } from '../saved_objects_type_registry'; import type { SavedObjectConfig } from '../saved_objects_config'; -import type { KibanaConfigType } from '../../kibana_config'; import { getUnknownTypesDeprecations } from './unknown_object_types'; interface GetDeprecationProviderOptions { typeRegistry: ISavedObjectTypeRegistry; savedObjectsConfig: SavedObjectConfig; - kibanaConfig: KibanaConfigType; + kibanaIndex: string; kibanaVersion: string; } diff --git a/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts b/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts index 1f9ca741691d10..3f8fce0bc1c87f 100644 --- a/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts +++ b/src/core/server/saved_objects/deprecations/unknown_object_types.test.ts @@ -12,7 +12,6 @@ import { estypes } from '@elastic/elasticsearch'; import { deleteUnknownTypeObjects, getUnknownTypesDeprecations } from './unknown_object_types'; import { typeRegistryMock } from '../saved_objects_type_registry.mock'; import { elasticsearchClientMock } from '../../elasticsearch/client/mocks'; -import type { KibanaConfigType } from '../../kibana_config'; import { SavedObjectsType } from 'kibana/server'; const createSearchResponse = (count: number): estypes.SearchResponse => { @@ -30,7 +29,7 @@ describe('unknown saved object types deprecation', () => { let typeRegistry: ReturnType; let esClient: ReturnType; - let kibanaConfig: KibanaConfigType; + const kibanaIndex = '.kibana'; beforeEach(() => { typeRegistry = typeRegistryMock.create(); @@ -41,11 +40,6 @@ describe('unknown saved object types deprecation', () => { { name: 'bar' }, ] as SavedObjectsType[]); getIndexForTypeMock.mockImplementation(({ type }: { type: string }) => `${type}-index`); - - kibanaConfig = { - index: '.kibana', - enabled: true, - }; }); afterEach(() => { @@ -63,7 +57,7 @@ describe('unknown saved object types deprecation', () => { await getUnknownTypesDeprecations({ esClient, typeRegistry, - kibanaConfig, + kibanaIndex, kibanaVersion, }); @@ -89,7 +83,7 @@ describe('unknown saved object types deprecation', () => { const deprecations = await getUnknownTypesDeprecations({ esClient, typeRegistry, - kibanaConfig, + kibanaIndex, kibanaVersion, }); @@ -104,7 +98,7 @@ describe('unknown saved object types deprecation', () => { const deprecations = await getUnknownTypesDeprecations({ esClient, typeRegistry, - kibanaConfig, + kibanaIndex, kibanaVersion, }); @@ -132,7 +126,7 @@ describe('unknown saved object types deprecation', () => { await deleteUnknownTypeObjects({ esClient, typeRegistry, - kibanaConfig, + kibanaIndex, kibanaVersion, }); diff --git a/src/core/server/saved_objects/deprecations/unknown_object_types.ts b/src/core/server/saved_objects/deprecations/unknown_object_types.ts index 8cd650bac8a2d5..1b34dcad640101 100644 --- a/src/core/server/saved_objects/deprecations/unknown_object_types.ts +++ b/src/core/server/saved_objects/deprecations/unknown_object_types.ts @@ -12,13 +12,12 @@ import type { DeprecationsDetails } from '../../deprecations'; import { IScopedClusterClient } from '../../elasticsearch'; import { ISavedObjectTypeRegistry } from '../saved_objects_type_registry'; import { SavedObjectsRawDocSource } from '../serialization'; -import type { KibanaConfigType } from '../../kibana_config'; import { getIndexForType } from '../service/lib'; interface UnknownTypesDeprecationOptions { typeRegistry: ISavedObjectTypeRegistry; esClient: IScopedClusterClient; - kibanaConfig: KibanaConfigType; + kibanaIndex: string; kibanaVersion: string; } @@ -29,11 +28,11 @@ const getTargetIndices = ({ types, typeRegistry, kibanaVersion, - kibanaConfig, + kibanaIndex, }: { types: string[]; typeRegistry: ISavedObjectTypeRegistry; - kibanaConfig: KibanaConfigType; + kibanaIndex: string; kibanaVersion: string; }) => { return [ @@ -43,7 +42,7 @@ const getTargetIndices = ({ type, typeRegistry, kibanaVersion, - defaultIndex: kibanaConfig.index, + defaultIndex: kibanaIndex, }) ) ), @@ -63,14 +62,14 @@ const getUnknownTypesQuery = (knownTypes: string[]): estypes.QueryDslQueryContai const getUnknownSavedObjects = async ({ typeRegistry, esClient, - kibanaConfig, + kibanaIndex, kibanaVersion, }: UnknownTypesDeprecationOptions) => { const knownTypes = getKnownTypes(typeRegistry); const targetIndices = getTargetIndices({ types: knownTypes, typeRegistry, - kibanaConfig, + kibanaIndex, kibanaVersion, }); const query = getUnknownTypesQuery(knownTypes); @@ -133,21 +132,21 @@ export const getUnknownTypesDeprecations = async ( interface DeleteUnknownTypesOptions { typeRegistry: ISavedObjectTypeRegistry; esClient: IScopedClusterClient; - kibanaConfig: KibanaConfigType; + kibanaIndex: string; kibanaVersion: string; } export const deleteUnknownTypeObjects = async ({ esClient, typeRegistry, - kibanaConfig, + kibanaIndex, kibanaVersion, }: DeleteUnknownTypesOptions) => { const knownTypes = getKnownTypes(typeRegistry); const targetIndices = getTargetIndices({ types: knownTypes, typeRegistry, - kibanaConfig, + kibanaIndex, kibanaVersion, }); const query = getUnknownTypesQuery(knownTypes); diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts index c397559b52570c..90274de557fdf6 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.test.ts @@ -16,6 +16,7 @@ import { SavedObjectTypeRegistry } from '../../saved_objects_type_registry'; import { SavedObjectsType } from '../../types'; import { DocumentMigrator } from '../core/document_migrator'; import { ByteSizeValue } from '@kbn/config-schema'; + jest.mock('../core/document_migrator', () => { return { // Create a mock for spying on the constructor @@ -304,10 +305,7 @@ const mockOptions = () => { migrations: {}, }, ]), - kibanaConfig: { - enabled: true, - index: '.my-index', - } as KibanaMigratorOptions['kibanaConfig'], + kibanaIndex: '.my-index', soMigrationsConfig: { batchSize: 20, maxBatchSizeBytes: ByteSizeValue.parse('20mb'), diff --git a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts index d3755f8c7e666c..a812339cef07ef 100644 --- a/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts +++ b/src/core/server/saved_objects/migrations/kibana/kibana_migrator.ts @@ -13,7 +13,6 @@ import { BehaviorSubject } from 'rxjs'; import Semver from 'semver'; -import { KibanaConfigType } from '../../../kibana_config'; import { ElasticsearchClient } from '../../../elasticsearch'; import { Logger } from '../../../logging'; import { IndexMapping, SavedObjectsTypeMappingDefinitions } from '../../mappings'; @@ -35,7 +34,7 @@ export interface KibanaMigratorOptions { client: ElasticsearchClient; typeRegistry: ISavedObjectTypeRegistry; soMigrationsConfig: SavedObjectsMigrationConfigType; - kibanaConfig: KibanaConfigType; + kibanaIndex: string; kibanaVersion: string; logger: Logger; migrationsRetryDelay?: number; @@ -55,7 +54,7 @@ export interface KibanaMigratorStatus { export class KibanaMigrator { private readonly client: ElasticsearchClient; private readonly documentMigrator: VersionedTransformer; - private readonly kibanaConfig: KibanaConfigType; + private readonly kibanaIndex: string; private readonly log: Logger; private readonly mappingProperties: SavedObjectsTypeMappingDefinitions; private readonly typeRegistry: ISavedObjectTypeRegistry; @@ -76,14 +75,14 @@ export class KibanaMigrator { constructor({ client, typeRegistry, - kibanaConfig, + kibanaIndex, soMigrationsConfig, kibanaVersion, logger, migrationsRetryDelay, }: KibanaMigratorOptions) { this.client = client; - this.kibanaConfig = kibanaConfig; + this.kibanaIndex = kibanaIndex; this.soMigrationsConfig = soMigrationsConfig; this.typeRegistry = typeRegistry; this.serializer = new SavedObjectsSerializer(this.typeRegistry); @@ -148,9 +147,8 @@ export class KibanaMigrator { } private runMigrationsInternal() { - const kibanaIndexName = this.kibanaConfig.index; const indexMap = createIndexMap({ - kibanaIndexName, + kibanaIndexName: this.kibanaIndex, indexMap: this.mappingProperties, registry: this.typeRegistry, }); diff --git a/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts b/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts index 2b6d64bef4f1af..97100980a37b3f 100644 --- a/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts +++ b/src/core/server/saved_objects/routes/deprecations/delete_unknown_types.ts @@ -9,16 +9,15 @@ import { IRouter } from '../../../http'; import { catchAndReturnBoomErrors } from '../utils'; import { deleteUnknownTypeObjects } from '../../deprecations'; -import { KibanaConfigType } from '../../../kibana_config'; interface RouteDependencies { - kibanaConfig: KibanaConfigType; + kibanaIndex: string; kibanaVersion: string; } export const registerDeleteUnknownTypesRoute = ( router: IRouter, - { kibanaConfig, kibanaVersion }: RouteDependencies + { kibanaIndex, kibanaVersion }: RouteDependencies ) => { router.post( { @@ -29,7 +28,7 @@ export const registerDeleteUnknownTypesRoute = ( await deleteUnknownTypeObjects({ esClient: context.core.elasticsearch.client, typeRegistry: context.core.savedObjects.typeRegistry, - kibanaConfig, + kibanaIndex, kibanaVersion, }); return res.ok({ diff --git a/src/core/server/saved_objects/routes/index.ts b/src/core/server/saved_objects/routes/index.ts index a85070867ae8fc..41ad9ff24c30c0 100644 --- a/src/core/server/saved_objects/routes/index.ts +++ b/src/core/server/saved_objects/routes/index.ts @@ -28,7 +28,6 @@ import { registerLegacyImportRoute } from './legacy_import_export/import'; import { registerLegacyExportRoute } from './legacy_import_export/export'; import { registerBulkResolveRoute } from './bulk_resolve'; import { registerDeleteUnknownTypesRoute } from './deprecations'; -import { KibanaConfigType } from '../../kibana_config'; export function registerRoutes({ http, @@ -37,7 +36,7 @@ export function registerRoutes({ config, migratorPromise, kibanaVersion, - kibanaConfig, + kibanaIndex, }: { http: InternalHttpServiceSetup; coreUsageData: InternalCoreUsageDataSetup; @@ -45,7 +44,7 @@ export function registerRoutes({ config: SavedObjectConfig; migratorPromise: Promise; kibanaVersion: string; - kibanaConfig: KibanaConfigType; + kibanaIndex: string; }) { const router = http.createRouter('/api/saved_objects/'); @@ -74,5 +73,5 @@ export function registerRoutes({ const internalRouter = http.createRouter('/internal/saved_objects/'); registerMigrateRoute(internalRouter, migratorPromise); - registerDeleteUnknownTypesRoute(internalRouter, { kibanaConfig, kibanaVersion }); + registerDeleteUnknownTypesRoute(internalRouter, { kibanaIndex, kibanaVersion }); } diff --git a/src/core/server/saved_objects/routes/integration_tests/delete_unknown_types.test.ts b/src/core/server/saved_objects/routes/integration_tests/delete_unknown_types.test.ts index 0c7fbdda89fbfe..ef1c711536b00d 100644 --- a/src/core/server/saved_objects/routes/integration_tests/delete_unknown_types.test.ts +++ b/src/core/server/saved_objects/routes/integration_tests/delete_unknown_types.test.ts @@ -12,17 +12,13 @@ import { registerDeleteUnknownTypesRoute } from '../deprecations'; import { elasticsearchServiceMock } from '../../../../../core/server/elasticsearch/elasticsearch_service.mock'; import { typeRegistryMock } from '../../saved_objects_type_registry.mock'; import { setupServer } from '../test_utils'; -import { KibanaConfigType } from '../../../kibana_config'; import { SavedObjectsType } from 'kibana/server'; type SetupServerReturn = UnwrapPromise>; describe('POST /internal/saved_objects/deprecations/_delete_unknown_types', () => { const kibanaVersion = '8.0.0'; - const kibanaConfig: KibanaConfigType = { - enabled: true, - index: '.kibana', - }; + const kibanaIndex = '.kibana'; let server: SetupServerReturn['server']; let httpSetup: SetupServerReturn['httpSetup']; @@ -45,7 +41,7 @@ describe('POST /internal/saved_objects/deprecations/_delete_unknown_types', () = const router = httpSetup.createRouter('/internal/saved_objects/'); registerDeleteUnknownTypesRoute(router, { kibanaVersion, - kibanaConfig, + kibanaIndex, }); await server.start(); diff --git a/src/core/server/saved_objects/saved_objects_service.mock.ts b/src/core/server/saved_objects/saved_objects_service.mock.ts index cd7310e226f639..fd04d917ebb9c6 100644 --- a/src/core/server/saved_objects/saved_objects_service.mock.ts +++ b/src/core/server/saved_objects/saved_objects_service.mock.ts @@ -60,8 +60,11 @@ const createSetupContractMock = () => { setClientFactoryProvider: jest.fn(), addClientWrapper: jest.fn(), registerType: jest.fn(), + getKibanaIndex: jest.fn(), }; + setupContract.getKibanaIndex.mockReturnValue('.kibana'); + return setupContract; }; diff --git a/src/core/server/saved_objects/saved_objects_service.ts b/src/core/server/saved_objects/saved_objects_service.ts index 534718bd683b81..33d75c38f43695 100644 --- a/src/core/server/saved_objects/saved_objects_service.ts +++ b/src/core/server/saved_objects/saved_objects_service.ts @@ -23,7 +23,6 @@ import { InternalElasticsearchServiceStart, } from '../elasticsearch'; import { InternalDeprecationsServiceSetup } from '../deprecations'; -import { KibanaConfigType } from '../kibana_config'; import { SavedObjectsConfigType, SavedObjectsMigrationConfigType, @@ -47,6 +46,8 @@ import { calculateStatus$ } from './status'; import { registerCoreObjectTypes } from './object_types'; import { getSavedObjectsDeprecationsProvider } from './deprecations'; +const kibanaIndex = '.kibana'; + /** * Saved Objects is Kibana's data persistence mechanism allowing plugins to * use Elasticsearch for storing and querying state. The SavedObjectsServiceSetup API exposes methods @@ -144,6 +145,11 @@ export interface SavedObjectsServiceSetup { * ``` */ registerType: (type: SavedObjectsType) => void; + + /** + * Returns the default index used for saved objects. + */ + getKibanaIndex: () => string; } /** @@ -302,14 +308,9 @@ export class SavedObjectsService .toPromise(); this.config = new SavedObjectConfig(savedObjectsConfig, savedObjectsMigrationConfig); - const kibanaConfig = await this.coreContext.configService - .atPath('kibana') - .pipe(first()) - .toPromise(); - deprecations.getRegistry('savedObjects').registerDeprecations( getSavedObjectsDeprecationsProvider({ - kibanaConfig, + kibanaIndex, savedObjectsConfig: this.config, kibanaVersion: this.coreContext.env.packageInfo.version, typeRegistry: this.typeRegistry, @@ -324,7 +325,7 @@ export class SavedObjectsService logger: this.logger, config: this.config, migratorPromise: this.migrator$.pipe(first()).toPromise(), - kibanaConfig, + kibanaIndex, kibanaVersion: this.coreContext.env.packageInfo.version, }); @@ -361,6 +362,7 @@ export class SavedObjectsService this.typeRegistry.registerType(type); }, getTypeRegistry: () => this.typeRegistry, + getKibanaIndex: () => kibanaIndex, }; } @@ -374,14 +376,9 @@ export class SavedObjectsService this.logger.debug('Starting SavedObjects service'); - const kibanaConfig = await this.coreContext.configService - .atPath('kibana') - .pipe(first()) - .toPromise(); const client = elasticsearch.client; const migrator = this.createMigrator( - kibanaConfig, this.config.migration, elasticsearch.client.asInternalUser, migrationsRetryDelay @@ -442,7 +439,7 @@ export class SavedObjectsService return SavedObjectsRepository.createRepository( migrator, this.typeRegistry, - kibanaConfig.index, + kibanaIndex, esClient, this.logger.get('repository'), includedHiddenTypes @@ -498,7 +495,6 @@ export class SavedObjectsService public async stop() {} private createMigrator( - kibanaConfig: KibanaConfigType, soMigrationsConfig: SavedObjectsMigrationConfigType, client: ElasticsearchClient, migrationsRetryDelay?: number @@ -508,7 +504,7 @@ export class SavedObjectsService logger: this.logger, kibanaVersion: this.coreContext.env.packageInfo.version, soMigrationsConfig, - kibanaConfig, + kibanaIndex, client, migrationsRetryDelay, }); diff --git a/src/core/server/server.api.md b/src/core/server/server.api.md index 9e50a3008293bb..632fea5c6660da 100644 --- a/src/core/server/server.api.md +++ b/src/core/server/server.api.md @@ -2704,6 +2704,7 @@ export class SavedObjectsSerializer { // @public export interface SavedObjectsServiceSetup { addClientWrapper: (priority: number, id: string, factory: SavedObjectsClientWrapperFactory) => void; + getKibanaIndex: () => string; registerType: (type: SavedObjectsType) => void; setClientFactoryProvider: (clientFactoryProvider: SavedObjectsClientFactoryProvider) => void; } @@ -2977,7 +2978,6 @@ export interface ShardsResponse { // @public (undocumented) export type SharedGlobalConfig = RecursiveReadonly<{ - kibana: Pick; elasticsearch: Pick; path: Pick; savedObjects: Pick; @@ -3052,9 +3052,8 @@ export const validBodyOutput: readonly ["data", "stream"]; // // src/core/server/elasticsearch/client/types.ts:94:7 - (ae-forgotten-export) The symbol "Explanation" needs to be exported by the entry point index.d.ts // src/core/server/http/router/response.ts:302:3 - (ae-forgotten-export) The symbol "KibanaResponse" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "KibanaConfigType" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/types.ts:380:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts -// src/core/server/plugins/types.ts:486:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create" +// src/core/server/plugins/types.ts:375:3 - (ae-forgotten-export) The symbol "SharedGlobalConfigKeys" needs to be exported by the entry point index.d.ts +// src/core/server/plugins/types.ts:377:3 - (ae-forgotten-export) The symbol "SavedObjectsConfigType" needs to be exported by the entry point index.d.ts +// src/core/server/plugins/types.ts:483:5 - (ae-unresolved-link) The @link reference could not be resolved: The package "kibana" does not have an export "create" ``` diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 2d3b87207fcbed..e8c7ce6abb0294 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -36,7 +36,6 @@ import { config as cspConfig } from './csp'; import { config as elasticsearchConfig } from './elasticsearch'; import { config as httpConfig } from './http'; import { config as loggingConfig } from './logging'; -import { config as kibanaConfig } from './kibana_config'; import { savedObjectsConfig, savedObjectsMigrationConfig } from './saved_objects'; import { config as uiSettingsConfig } from './ui_settings'; import { config as statusConfig } from './status'; @@ -373,7 +372,6 @@ export class Server { loggingConfig, httpConfig, pluginsConfig, - kibanaConfig, savedObjectsConfig, savedObjectsMigrationConfig, uiSettingsConfig, diff --git a/src/plugins/data/server/kql_telemetry/kql_telemetry_service.ts b/src/plugins/data/server/kql_telemetry/kql_telemetry_service.ts index 09e64ba7f43102..423ebbdcd43c71 100644 --- a/src/plugins/data/server/kql_telemetry/kql_telemetry_service.ts +++ b/src/plugins/data/server/kql_telemetry/kql_telemetry_service.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import { first } from 'rxjs/operators'; import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server'; import { registerKqlTelemetryRoute } from './route'; import { UsageCollectionSetup } from '../../../usage_collection/server'; @@ -28,15 +27,13 @@ export class KqlTelemetryService implements Plugin { ); if (usageCollection) { - this.initializerContext.config.legacy.globalConfig$ - .pipe(first()) - .toPromise() - .then((config) => makeKQLUsageCollector(usageCollection, config.kibana.index)) - .catch((e) => { - this.initializerContext.logger - .get('kql-telemetry') - .warn(`Registering KQL telemetry collector failed: ${e}`); - }); + try { + makeKQLUsageCollector(usageCollection, savedObjects.getKibanaIndex()); + } catch (e) { + this.initializerContext.logger + .get('kql-telemetry') + .warn(`Registering KQL telemetry collector failed: ${e}`); + } } } diff --git a/src/plugins/data/server/kql_telemetry/usage_collector/make_kql_usage_collector.ts b/src/plugins/data/server/kql_telemetry/usage_collector/make_kql_usage_collector.ts index f3b5865bd08932..39ea7d6ab2decd 100644 --- a/src/plugins/data/server/kql_telemetry/usage_collector/make_kql_usage_collector.ts +++ b/src/plugins/data/server/kql_telemetry/usage_collector/make_kql_usage_collector.ts @@ -9,10 +9,7 @@ import { fetchProvider, Usage } from './fetch'; import { UsageCollectionSetup } from '../../../../usage_collection/server'; -export async function makeKQLUsageCollector( - usageCollection: UsageCollectionSetup, - kibanaIndex: string -) { +export function makeKQLUsageCollector(usageCollection: UsageCollectionSetup, kibanaIndex: string) { const kqlUsageCollector = usageCollection.makeUsageCollector({ type: 'kql', fetch: fetchProvider(kibanaIndex), diff --git a/src/plugins/data/server/search/collectors/fetch.ts b/src/plugins/data/server/search/collectors/fetch.ts index 8c4b79b290565e..a2d1917fc47701 100644 --- a/src/plugins/data/server/search/collectors/fetch.ts +++ b/src/plugins/data/server/search/collectors/fetch.ts @@ -6,21 +6,18 @@ * Side Public License, v 1. */ -import { Observable } from 'rxjs'; -import { first } from 'rxjs/operators'; -import { SharedGlobalConfig } from 'kibana/server'; import { CollectorFetchContext } from 'src/plugins/usage_collection/server'; import { CollectedUsage, ReportedUsage } from './register'; + interface SearchTelemetry { 'search-telemetry': CollectedUsage; } -export function fetchProvider(config$: Observable) { +export function fetchProvider(kibanaIndex: string) { return async ({ esClient }: CollectorFetchContext): Promise => { - const config = await config$.pipe(first()).toPromise(); const { body: esResponse } = await esClient.search( { - index: config.kibana.index, + index: kibanaIndex, body: { query: { term: { type: { value: 'search-telemetry' } } }, }, diff --git a/src/plugins/data/server/search/collectors/register.ts b/src/plugins/data/server/search/collectors/register.ts index a370377c30eeaf..a70b9760122a9b 100644 --- a/src/plugins/data/server/search/collectors/register.ts +++ b/src/plugins/data/server/search/collectors/register.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import { PluginInitializerContext } from 'kibana/server'; import { UsageCollectionSetup } from '../../../../usage_collection/server'; import { fetchProvider } from './fetch'; @@ -22,15 +21,12 @@ export interface ReportedUsage { averageDuration: number | null; } -export async function registerUsageCollector( - usageCollection: UsageCollectionSetup, - context: PluginInitializerContext -) { +export function registerUsageCollector(usageCollection: UsageCollectionSetup, kibanaIndex: string) { try { const collector = usageCollection.makeUsageCollector({ type: 'search', isReady: () => true, - fetch: fetchProvider(context.config.legacy.globalConfig$), + fetch: fetchProvider(kibanaIndex), schema: { successCount: { type: 'long' }, errorCount: { type: 'long' }, diff --git a/src/plugins/data/server/search/search_service.ts b/src/plugins/data/server/search/search_service.ts index 04db51fdce7fb0..d3b1c57b677792 100644 --- a/src/plugins/data/server/search/search_service.ts +++ b/src/plugins/data/server/search/search_service.ts @@ -184,7 +184,7 @@ export class SearchService implements Plugin { core.savedObjects.registerType(searchTelemetry); if (usageCollection) { - registerUsageCollector(usageCollection, this.initializerContext); + registerUsageCollector(usageCollection, core.savedObjects.getKibanaIndex()); } expressions.registerFunction(getEsaggs({ getStartServices: core.getStartServices })); diff --git a/src/plugins/home/server/services/sample_data/sample_data_registry.ts b/src/plugins/home/server/services/sample_data/sample_data_registry.ts index b88f42ca970af8..ef453592d9790f 100644 --- a/src/plugins/home/server/services/sample_data/sample_data_registry.ts +++ b/src/plugins/home/server/services/sample_data/sample_data_registry.ts @@ -61,7 +61,8 @@ export class SampleDataRegistry { customIntegrations?: CustomIntegrationsPluginSetup ) { if (usageCollections) { - makeSampleDataUsageCollector(usageCollections, this.initContext); + const kibanaIndex = core.savedObjects.getKibanaIndex(); + makeSampleDataUsageCollector(usageCollections, kibanaIndex); } const usageTracker = usage( core.getStartServices().then(([coreStart]) => coreStart.savedObjects), diff --git a/src/plugins/home/server/services/sample_data/usage/collector.ts b/src/plugins/home/server/services/sample_data/usage/collector.ts index df7d485c1f6fa1..06c0c9239942be 100644 --- a/src/plugins/home/server/services/sample_data/usage/collector.ts +++ b/src/plugins/home/server/services/sample_data/usage/collector.ts @@ -6,20 +6,16 @@ * Side Public License, v 1. */ -import type { PluginInitializerContext } from 'kibana/server'; import type { UsageCollectionSetup } from '../../../../../usage_collection/server'; import { fetchProvider, TelemetryResponse } from './collector_fetch'; export function makeSampleDataUsageCollector( usageCollection: UsageCollectionSetup, - context: PluginInitializerContext + kibanaIndex: string ) { - const config = context.config.legacy.get(); - const index = config.kibana.index; - const collector = usageCollection.makeUsageCollector({ type: 'sample-data', - fetch: fetchProvider(index), + fetch: fetchProvider(kibanaIndex), isReady: () => true, schema: { installed: { type: 'array', items: { type: 'keyword' } }, diff --git a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.test.ts b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.test.ts index fc9f9a6e8c2d3d..d61b8ca2c77790 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.test.ts @@ -6,11 +6,7 @@ * Side Public License, v 1. */ -import { - loggingSystemMock, - pluginInitializerContextConfigMock, - elasticsearchServiceMock, -} from '../../../../../core/server/mocks'; +import { loggingSystemMock, elasticsearchServiceMock } from '../../../../../core/server/mocks'; import { Collector, createCollectorFetchContextMock, @@ -29,7 +25,7 @@ describe('kibana_usage', () => { return createUsageCollectionSetupMock().makeUsageCollector(config); }); - const legacyConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$; + const kibanaIndex = '.kibana-tests'; const getMockFetchClients = (hits?: unknown[]) => { const fetchParamsMock = createCollectorFetchContextMock(); @@ -40,7 +36,7 @@ describe('kibana_usage', () => { return fetchParamsMock; }; - beforeAll(() => registerKibanaUsageCollector(usageCollectionMock, legacyConfig$)); + beforeAll(() => registerKibanaUsageCollector(usageCollectionMock, kibanaIndex)); afterAll(() => jest.clearAllTimers()); test('registered collector is set', () => { diff --git a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.ts index 75d5af2737772a..9bd8da2be54df7 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/kibana_usage_collector.ts @@ -6,10 +6,8 @@ * Side Public License, v 1. */ -import type { Observable } from 'rxjs'; -import type { ElasticsearchClient, SharedGlobalConfig } from 'src/core/server'; +import type { ElasticsearchClient } from 'src/core/server'; import type { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { take } from 'rxjs/operators'; import { snakeCase } from 'lodash'; import { getSavedObjectsCounts } from './get_saved_object_counts'; @@ -46,7 +44,7 @@ export async function getKibanaSavedObjectCounts( export function registerKibanaUsageCollector( usageCollection: UsageCollectionSetup, - legacyConfig$: Observable + kibanaIndex: string ) { usageCollection.registerCollector( usageCollection.makeUsageCollector({ @@ -83,12 +81,9 @@ export function registerKibanaUsageCollector( }, }, async fetch({ esClient }) { - const { - kibana: { index }, - } = await legacyConfig$.pipe(take(1)).toPromise(); return { - index, - ...(await getKibanaSavedObjectCounts(esClient, index)), + index: kibanaIndex, + ...(await getKibanaSavedObjectCounts(esClient, kibanaIndex)), }; }, }) diff --git a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.test.ts b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.test.ts index 0ef5bffd40ff75..1f507dcc446662 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.test.ts @@ -6,7 +6,6 @@ * Side Public License, v 1. */ -import { pluginInitializerContextConfigMock } from '../../../../../core/server/mocks'; import { createCollectorFetchContextMock, createUsageCollectionSetupMock, @@ -16,9 +15,9 @@ import { registerSavedObjectsCountUsageCollector } from './saved_objects_count_c describe('saved_objects_count_collector', () => { const usageCollectionMock = createUsageCollectionSetupMock(); - const legacyConfig$ = pluginInitializerContextConfigMock({}).legacy.globalConfig$; + const kibanaIndex = '.kibana-tests'; - beforeAll(() => registerSavedObjectsCountUsageCollector(usageCollectionMock, legacyConfig$)); + beforeAll(() => registerSavedObjectsCountUsageCollector(usageCollectionMock, kibanaIndex)); afterAll(() => jest.clearAllTimers()); test('registered collector is set', () => { diff --git a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.ts b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.ts index 71bf2da7dc270e..f541b1ef452e61 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/saved_objects_counts/saved_objects_count_collector.ts @@ -6,9 +6,6 @@ * Side Public License, v 1. */ -import type { Observable } from 'rxjs'; -import { take } from 'rxjs/operators'; -import type { SharedGlobalConfig } from 'src/core/server'; import type { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { getSavedObjectsCounts } from './get_saved_object_counts'; @@ -23,7 +20,7 @@ interface SavedObjectsCountUsage { export function registerSavedObjectsCountUsageCollector( usageCollection: UsageCollectionSetup, - legacyConfig$: Observable + kibanaIndex: string ) { usageCollection.registerCollector( usageCollection.makeUsageCollector({ @@ -45,10 +42,7 @@ export function registerSavedObjectsCountUsageCollector( }, }, async fetch({ esClient }) { - const { - kibana: { index }, - } = await legacyConfig$.pipe(take(1)).toPromise(); - const buckets = await getSavedObjectsCounts(esClient, index); + const buckets = await getSavedObjectsCounts(esClient, kibanaIndex); return { by_type: buckets.map(({ key: type, doc_count: count }) => { return { type, count }; diff --git a/src/plugins/kibana_usage_collection/server/plugin.ts b/src/plugins/kibana_usage_collection/server/plugin.ts index 07a70dfd56fb4b..96d37c0303482a 100644 --- a/src/plugins/kibana_usage_collection/server/plugin.ts +++ b/src/plugins/kibana_usage_collection/server/plugin.ts @@ -7,14 +7,13 @@ */ import type { UsageCollectionSetup, UsageCounter } from 'src/plugins/usage_collection/server'; -import { Subject, Observable } from 'rxjs'; +import { Subject } from 'rxjs'; import type { PluginInitializerContext, CoreSetup, Plugin, ISavedObjectsRepository, IUiSettingsClient, - SharedGlobalConfig, CoreStart, SavedObjectsServiceSetup, OpsMetrics, @@ -55,7 +54,6 @@ type SavedObjectsRegisterType = SavedObjectsServiceSetup['registerType']; export class KibanaUsageCollectionPlugin implements Plugin { private readonly logger: Logger; - private readonly legacyConfig$: Observable; private readonly instanceUuid: string; private savedObjectsClient?: ISavedObjectsRepository; private uiSettingsClient?: IUiSettingsClient; @@ -66,7 +64,6 @@ export class KibanaUsageCollectionPlugin implements Plugin { constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); - this.legacyConfig$ = initializerContext.config.legacy.globalConfig$; this.metric$ = new Subject(); this.pluginStop$ = new Subject(); this.instanceUuid = initializerContext.env.instanceUuid; @@ -121,6 +118,7 @@ export class KibanaUsageCollectionPlugin implements Plugin { pluginStop$: Subject, registerType: SavedObjectsRegisterType ) { + const kibanaIndex = coreSetup.savedObjects.getKibanaIndex(); const getSavedObjectsClient = () => this.savedObjectsClient; const getUiSettingsClient = () => this.uiSettingsClient; const getCoreUsageDataService = () => this.coreUsageData!; @@ -133,8 +131,8 @@ export class KibanaUsageCollectionPlugin implements Plugin { registerUsageCountersUsageCollector(usageCollection); registerOpsStatsCollector(usageCollection, metric$); - registerKibanaUsageCollector(usageCollection, this.legacyConfig$); - registerSavedObjectsCountUsageCollector(usageCollection, this.legacyConfig$); + registerKibanaUsageCollector(usageCollection, kibanaIndex); + registerSavedObjectsCountUsageCollector(usageCollection, kibanaIndex); registerManagementUsageCollector(usageCollection, getUiSettingsClient); registerUiMetricUsageCollector(usageCollection, registerType, getSavedObjectsClient); registerApplicationUsageCollector( diff --git a/src/plugins/usage_collection/server/plugin.ts b/src/plugins/usage_collection/server/plugin.ts index 1c537ccfbb22bf..12b2db43016e4b 100644 --- a/src/plugins/usage_collection/server/plugin.ts +++ b/src/plugins/usage_collection/server/plugin.ts @@ -113,6 +113,7 @@ export class UsageCollectionPlugin implements Plugin { public setup(core: CoreSetup): UsageCollectionSetup { const config = this.initializerContext.config.get(); + const kibanaIndex = core.savedObjects.getKibanaIndex(); const collectorSet = new CollectorSet({ logger: this.logger.get('usage-collection', 'collector-set'), @@ -128,7 +129,6 @@ export class UsageCollectionPlugin implements Plugin { const { createUsageCounter, getUsageCounterByType } = this.usageCountersService.setup(core); const uiCountersUsageCounter = createUsageCounter('uiCounter'); - const globalConfig = this.initializerContext.config.legacy.get(); const router = core.http.createRouter(); setupRoutes({ router, @@ -137,7 +137,7 @@ export class UsageCollectionPlugin implements Plugin { collectorSet, config: { allowAnonymous: core.status.isStatusPageAnonymous(), - kibanaIndex: globalConfig.kibana.index, + kibanaIndex, kibanaVersion: this.initializerContext.env.packageInfo.version, server: core.http.getServerInfo(), uuid: this.initializerContext.env.instanceUuid, diff --git a/x-pack/plugins/actions/server/plugin.ts b/x-pack/plugins/actions/server/plugin.ts index d0404a253c0d9b..2942c7492906a8 100644 --- a/x-pack/plugins/actions/server/plugin.ts +++ b/x-pack/plugins/actions/server/plugin.ts @@ -96,19 +96,25 @@ export interface PluginSetupContract { >( actionType: ActionType ): void; + isPreconfiguredConnector(connectorId: string): boolean; } export interface PluginStartContract { isActionTypeEnabled(id: string, options?: { notifyUsage: boolean }): boolean; + isActionExecutable( actionId: string, actionTypeId: string, options?: { notifyUsage: boolean } ): boolean; + getActionsClientWithRequest(request: KibanaRequest): Promise>; + getActionsAuthorizationWithRequest(request: KibanaRequest): PublicMethodsOf; + preconfiguredActions: PreConfiguredAction[]; + renderActionParameterTemplates( actionTypeId: string, actionId: string, @@ -127,6 +133,7 @@ export interface ActionsPluginsSetup { features: FeaturesPluginSetup; spaces?: SpacesPluginSetup; } + export interface ActionsPluginsStart { encryptedSavedObjects: EncryptedSavedObjectsPluginStart; taskManager: TaskManagerStartContract; @@ -154,7 +161,7 @@ export class ActionsPlugin implements Plugin, plugins: ActionsPluginsSetup ): PluginSetupContract { + this.kibanaIndex = core.savedObjects.getKibanaIndex(); + this.licenseState = new LicenseState(plugins.licensing.license$); this.isESOCanEncrypt = plugins.encryptedSavedObjects.canEncrypt; @@ -253,14 +261,14 @@ export class ActionsPlugin implements Plugin( 'actions', - this.createRouteHandlerContext(core, this.kibanaIndexConfig.kibana.index) + this.createRouteHandlerContext(core, this.kibanaIndex) ); if (usageCollection) { initializeActionsTelemetry( this.telemetryLogger, plugins.taskManager, core, - this.kibanaIndexConfig.kibana.index, + this.kibanaIndex, this.preconfiguredActions ); } @@ -282,7 +290,7 @@ export class ActionsPlugin implements Plugin; + getAlertingAuthorizationWithRequest( request: KibanaRequest ): PublicMethodsOf; + getFrameworkHealth: () => Promise; } @@ -125,6 +128,7 @@ export interface AlertingPluginsSetup { eventLog: IEventLogService; statusService: StatusServiceSetup; } + export interface AlertingPluginsStart { actions: ActionsPluginStartContract; taskManager: TaskManagerStartContract; @@ -150,7 +154,6 @@ export class AlertingPlugin { private readonly kibanaVersion: PluginInitializerContext['env']['packageInfo']['version']; private eventLogService?: IEventLogService; private eventLogger?: IEventLogger; - private readonly kibanaIndexConfig: Observable<{ kibana: { index: string } }>; private kibanaBaseUrl: string | undefined; constructor(initializerContext: PluginInitializerContext) { @@ -160,7 +163,6 @@ export class AlertingPlugin { this.rulesClientFactory = new RulesClientFactory(); this.alertingAuthorizationClientFactory = new AlertingAuthorizationClientFactory(); this.telemetryLogger = initializerContext.logger.get('usage'); - this.kibanaIndexConfig = initializerContext.config.legacy.globalConfig$; this.kibanaVersion = initializerContext.env.packageInfo.version; } @@ -168,6 +170,7 @@ export class AlertingPlugin { core: CoreSetup, plugins: AlertingPluginsSetup ): PluginSetupContract { + const kibanaIndex = core.savedObjects.getKibanaIndex(); this.kibanaBaseUrl = core.http.basePath.publicBaseUrl; this.licenseState = new LicenseState(plugins.licensing.license$); this.security = plugins.security; @@ -211,14 +214,7 @@ export class AlertingPlugin { usageCollection, core.getStartServices().then(([_, { taskManager }]) => taskManager) ); - this.kibanaIndexConfig.subscribe((config) => { - initializeAlertingTelemetry( - this.telemetryLogger, - core, - plugins.taskManager, - config.kibana.index - ); - }); + initializeAlertingTelemetry(this.telemetryLogger, core, plugins.taskManager, kibanaIndex); } // Usage counter for telemetry diff --git a/x-pack/plugins/canvas/server/plugin.ts b/x-pack/plugins/canvas/server/plugin.ts index 35b1d0025ea5f9..4071b891e4c3d7 100644 --- a/x-pack/plugins/canvas/server/plugin.ts +++ b/x-pack/plugins/canvas/server/plugin.ts @@ -78,9 +78,9 @@ export class CanvasPlugin implements Plugin { plugins.home.sampleData.addAppLinksToSampleDataset ); - // we need the kibana index provided by global config for the Canvas usage collector - const globalConfig = this.initializerContext.config.legacy.get(); - registerCanvasUsageCollector(plugins.usageCollection, globalConfig.kibana.index); + // we need the kibana index for the Canvas usage collector + const kibanaIndex = coreSetup.savedObjects.getKibanaIndex(); + registerCanvasUsageCollector(plugins.usageCollection, kibanaIndex); setupInterpreter(expressionsFork); diff --git a/x-pack/plugins/data_enhanced/server/collectors/fetch.test.ts b/x-pack/plugins/data_enhanced/server/collectors/fetch.test.ts index 380cc0e3545021..47e6fb05c23293 100644 --- a/x-pack/plugins/data_enhanced/server/collectors/fetch.test.ts +++ b/x-pack/plugins/data_enhanced/server/collectors/fetch.test.ts @@ -6,12 +6,10 @@ */ import { - SharedGlobalConfig, ElasticsearchClient, SavedObjectsErrorHelpers, Logger, } from '../../../../../src/core/server'; -import { BehaviorSubject } from 'rxjs'; import { fetchProvider } from './fetch'; import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; @@ -21,17 +19,13 @@ describe('fetchProvider', () => { let mockLogger: Logger; beforeEach(async () => { - const config$ = new BehaviorSubject({ - kibana: { - index: '123', - }, - } as any); + const kibanaIndex = '123'; mockLogger = { warn: jest.fn(), debug: jest.fn(), } as any; esClient = elasticsearchServiceMock.createElasticsearchClient(); - fetchFn = fetchProvider(config$, mockLogger); + fetchFn = fetchProvider(kibanaIndex, mockLogger); }); test('returns when ES returns no results', async () => { diff --git a/x-pack/plugins/data_enhanced/server/collectors/fetch.ts b/x-pack/plugins/data_enhanced/server/collectors/fetch.ts index 27f72986dd537c..73dcc89a79b39d 100644 --- a/x-pack/plugins/data_enhanced/server/collectors/fetch.ts +++ b/x-pack/plugins/data_enhanced/server/collectors/fetch.ts @@ -5,9 +5,7 @@ * 2.0. */ import type { estypes } from '@elastic/elasticsearch'; -import { Observable } from 'rxjs'; -import { first } from 'rxjs/operators'; -import { SharedGlobalConfig, Logger } from 'kibana/server'; +import { Logger } from 'kibana/server'; import { CollectorFetchContext } from '../../../../../src/plugins/usage_collection/server'; import { SEARCH_SESSION_TYPE } from '../../../../../src/plugins/data/common'; import { ReportedUsage } from './register'; @@ -17,12 +15,11 @@ interface SessionPersistedTermsBucket { doc_count: number; } -export function fetchProvider(config$: Observable, logger: Logger) { +export function fetchProvider(kibanaIndex: string, logger: Logger) { return async ({ esClient }: CollectorFetchContext): Promise => { try { - const config = await config$.pipe(first()).toPromise(); const { body: esResponse } = await esClient.search({ - index: config.kibana.index, + index: kibanaIndex, body: { size: 0, aggs: { diff --git a/x-pack/plugins/data_enhanced/server/collectors/register.ts b/x-pack/plugins/data_enhanced/server/collectors/register.ts index fe96b7f7ced1b4..6e482a618a2923 100644 --- a/x-pack/plugins/data_enhanced/server/collectors/register.ts +++ b/x-pack/plugins/data_enhanced/server/collectors/register.ts @@ -5,7 +5,7 @@ * 2.0. */ -import { PluginInitializerContext, Logger } from 'kibana/server'; +import { Logger } from 'kibana/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { fetchProvider } from './fetch'; @@ -15,16 +15,16 @@ export interface ReportedUsage { totalCount: number; } -export async function registerUsageCollector( +export function registerUsageCollector( usageCollection: UsageCollectionSetup, - context: PluginInitializerContext, + kibanaIndex: string, logger: Logger ) { try { const collector = usageCollection.makeUsageCollector({ type: 'search-session', isReady: () => true, - fetch: fetchProvider(context.config.legacy.globalConfig$, logger), + fetch: fetchProvider(kibanaIndex, logger), schema: { transientCount: { type: 'long' }, persistedCount: { type: 'long' }, diff --git a/x-pack/plugins/data_enhanced/server/plugin.ts b/x-pack/plugins/data_enhanced/server/plugin.ts index 60a5de6323f507..28df0a5aa70cfc 100644 --- a/x-pack/plugins/data_enhanced/server/plugin.ts +++ b/x-pack/plugins/data_enhanced/server/plugin.ts @@ -53,7 +53,7 @@ export class EnhancedDataServerPlugin }); if (deps.usageCollection) { - registerUsageCollector(deps.usageCollection, this.initializerContext, this.logger); + registerUsageCollector(deps.usageCollection, core.savedObjects.getKibanaIndex(), this.logger); } } diff --git a/x-pack/plugins/event_log/server/plugin.ts b/x-pack/plugins/event_log/server/plugin.ts index 77cad86cefdc67..83bd8582636dde 100644 --- a/x-pack/plugins/event_log/server/plugin.ts +++ b/x-pack/plugins/event_log/server/plugin.ts @@ -12,7 +12,6 @@ import { Plugin as CorePlugin, PluginInitializerContext, IClusterClient, - SharedGlobalConfig, IContextProvider, } from 'src/core/server'; import { SpacesPluginStart } from '../../spaces/server'; @@ -50,7 +49,6 @@ export class Plugin implements CorePlugin(); - this.globalConfig = this.context.config.legacy.get(); this.savedObjectProviderRegistry = new SavedObjectProviderRegistry(); this.kibanaVersion = this.context.env.packageInfo.version; } setup(core: CoreSetup): IEventLogService { - const kibanaIndex = this.globalConfig.kibana.index; + const kibanaIndex = core.savedObjects.getKibanaIndex(); this.systemLogger.debug('setting up plugin'); diff --git a/x-pack/plugins/lens/server/plugin.tsx b/x-pack/plugins/lens/server/plugin.tsx index e242fc8e4c5d60..42e68c6223b6d7 100644 --- a/x-pack/plugins/lens/server/plugin.tsx +++ b/x-pack/plugins/lens/server/plugin.tsx @@ -7,7 +7,6 @@ import { Plugin, CoreSetup, CoreStart, PluginInitializerContext, Logger } from 'src/core/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { Observable } from 'rxjs'; import { PluginStart as DataPluginStart } from 'src/plugins/data/server'; import { ExpressionsServerSetup } from 'src/plugins/expressions/server'; import { FieldFormatsStart } from 'src/plugins/field_formats/server'; @@ -41,13 +40,12 @@ export interface LensServerPluginSetup { } export class LensServerPlugin implements Plugin { - private readonly kibanaIndexConfig: Observable<{ kibana: { index: string } }>; private readonly telemetryLogger: Logger; constructor(private initializerContext: PluginInitializerContext) { - this.kibanaIndexConfig = initializerContext.config.legacy.globalConfig$; this.telemetryLogger = initializerContext.logger.get('usage'); } + setup(core: CoreSetup, plugins: PluginSetupContract) { setupSavedObjects(core); setupRoutes(core, this.initializerContext.logger.get()); @@ -60,12 +58,7 @@ export class LensServerPlugin implements Plugin taskManager as TaskManagerStartContract) ); - initializeLensTelemetry( - this.telemetryLogger, - core, - this.kibanaIndexConfig, - plugins.taskManager - ); + initializeLensTelemetry(this.telemetryLogger, core, plugins.taskManager); } plugins.embeddable.registerEmbeddableFactory(lensEmbeddableFactory()); diff --git a/x-pack/plugins/lens/server/usage/task.ts b/x-pack/plugins/lens/server/usage/task.ts index 9227ca885359bb..6dfeb736eb45e0 100644 --- a/x-pack/plugins/lens/server/usage/task.ts +++ b/x-pack/plugins/lens/server/usage/task.ts @@ -6,8 +6,6 @@ */ import { CoreSetup, Logger, ElasticsearchClient } from 'kibana/server'; -import { Observable } from 'rxjs'; -import { first } from 'rxjs/operators'; import moment from 'moment'; import { RunContext, @@ -28,10 +26,9 @@ export const TASK_ID = `Lens-${TELEMETRY_TASK_TYPE}`; export function initializeLensTelemetry( logger: Logger, core: CoreSetup, - config: Observable<{ kibana: { index: string } }>, taskManager: TaskManagerSetupContract ) { - registerLensTelemetryTask(logger, core, config, taskManager); + registerLensTelemetryTask(logger, core, taskManager); } export function scheduleLensTelemetry(logger: Logger, taskManager?: TaskManagerStartContract) { @@ -43,14 +40,13 @@ export function scheduleLensTelemetry(logger: Logger, taskManager?: TaskManagerS function registerLensTelemetryTask( logger: Logger, core: CoreSetup, - config: Observable<{ kibana: { index: string } }>, taskManager: TaskManagerSetupContract ) { taskManager.registerTaskDefinitions({ [TELEMETRY_TASK_TYPE]: { title: 'Lens usage fetch task', timeout: '1m', - createTaskRunner: telemetryTaskRunner(logger, core, config), + createTaskRunner: telemetryTaskRunner(logger, core), }, }); } @@ -177,11 +173,7 @@ export async function getDailyEvents( }; } -export function telemetryTaskRunner( - logger: Logger, - core: CoreSetup, - config: Observable<{ kibana: { index: string } }> -) { +export function telemetryTaskRunner(logger: Logger, core: CoreSetup) { return ({ taskInstance }: RunContext) => { const { state } = taskInstance; const getEsClient = async () => { @@ -191,7 +183,7 @@ export function telemetryTaskRunner( return { async run() { - const kibanaIndex = (await config.pipe(first()).toPromise()).kibana.index; + const kibanaIndex = core.savedObjects.getKibanaIndex(); return Promise.all([ getDailyEvents(kibanaIndex, getEsClient), diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index efa61593655ac7..d99beb20883b2e 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -16,7 +16,6 @@ import type { CapabilitiesStart, IClusterClient, SavedObjectsServiceStart, - SharedGlobalConfig, UiSettingsServiceStart, } from 'kibana/server'; import type { SecurityPluginSetup } from '../../security/server'; @@ -82,14 +81,11 @@ export class MlServerPlugin private dataViews: DataViewsPluginStart | null = null; private isMlReady: Promise; private setMlReady: () => void = () => {}; - private readonly kibanaIndexConfig: SharedGlobalConfig; constructor(ctx: PluginInitializerContext) { this.log = ctx.logger.get(); this.mlLicense = new MlLicense(); this.isMlReady = new Promise((resolve) => (this.setMlReady = resolve)); - - this.kibanaIndexConfig = ctx.config.legacy.get(); } public setup(coreSetup: CoreSetup, plugins: PluginsSetup): MlPluginSetup { @@ -235,7 +231,7 @@ export class MlServerPlugin } if (plugins.usageCollection) { - registerCollector(plugins.usageCollection, this.kibanaIndexConfig.kibana.index); + registerCollector(plugins.usageCollection, coreSetup.savedObjects.getKibanaIndex()); } return sharedServicesProviders; diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 25fffd94d86a46..557a9b5e2a3d26 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -104,7 +104,7 @@ export class MonitoringPlugin kibanaStats: { uuid: this.initializerContext.env.instanceUuid, name: serverInfo.name, - index: this.legacyConfig.kibana.index, + index: coreSetup.savedObjects.getKibanaIndex(), host: serverInfo.hostname, locale: i18n.getLocale(), port: serverInfo.port.toString(), diff --git a/x-pack/plugins/rollup/server/plugin.ts b/x-pack/plugins/rollup/server/plugin.ts index 5c15ec0263dc31..88da9a3eb87b13 100644 --- a/x-pack/plugins/rollup/server/plugin.ts +++ b/x-pack/plugins/rollup/server/plugin.ts @@ -5,15 +5,7 @@ * 2.0. */ -import { Observable } from 'rxjs'; -import { first } from 'rxjs/operators'; -import { - CoreSetup, - Plugin, - Logger, - PluginInitializerContext, - SharedGlobalConfig, -} from 'src/core/server'; +import { CoreSetup, Plugin, Logger, PluginInitializerContext } from 'src/core/server'; import { i18n } from '@kbn/i18n'; import { schema } from '@kbn/config-schema'; @@ -30,17 +22,15 @@ import { getCapabilitiesForRollupIndices } from '../../../../src/plugins/data/se export class RollupPlugin implements Plugin { private readonly logger: Logger; - private readonly globalConfig$: Observable; private readonly license: License; constructor(initializerContext: PluginInitializerContext) { this.logger = initializerContext.logger.get(); - this.globalConfig$ = initializerContext.config.legacy.globalConfig$; this.license = new License(); } public setup( - { http, uiSettings, getStartServices }: CoreSetup, + { http, uiSettings, savedObjects, getStartServices }: CoreSetup, { features, licensing, indexManagement, visTypeTimeseries, usageCollection }: Dependencies ) { this.license.setup( @@ -101,15 +91,11 @@ export class RollupPlugin implements Plugin { }); if (usageCollection) { - this.globalConfig$ - .pipe(first()) - .toPromise() - .then((globalConfig) => { - registerRollupUsageCollector(usageCollection, globalConfig.kibana.index); - }) - .catch((e: any) => { - this.logger.warn(`Registering Rollup collector failed: ${e}`); - }); + try { + registerRollupUsageCollector(usageCollection, savedObjects.getKibanaIndex()); + } catch (e) { + this.logger.warn(`Registering Rollup collector failed: ${e}`); + } } if (indexManagement && indexManagement.indexDataEnricher) { diff --git a/x-pack/plugins/rule_registry/server/plugin.ts b/x-pack/plugins/rule_registry/server/plugin.ts index 334216ce413614..2e27ed7ba03c2d 100644 --- a/x-pack/plugins/rule_registry/server/plugin.ts +++ b/x-pack/plugins/rule_registry/server/plugin.ts @@ -13,7 +13,6 @@ import { KibanaRequest, CoreStart, IContextProvider, - SharedGlobalConfig, } from 'src/core/server'; import { PluginStartContract as AlertingStart } from '../../alerting/server'; @@ -53,7 +52,6 @@ export class RuleRegistryPlugin > { private readonly config: RuleRegistryPluginConfig; - private readonly legacyConfig: SharedGlobalConfig; private readonly logger: Logger; private readonly kibanaVersion: string; private readonly alertsClientFactory: AlertsClientFactory; @@ -62,8 +60,6 @@ export class RuleRegistryPlugin constructor(initContext: PluginInitializerContext) { this.config = initContext.config.get(); - // TODO: Can be removed in 8.0.0. Exists to work around multi-tenancy users. - this.legacyConfig = initContext.config.legacy.get(); this.logger = initContext.logger.get(); this.kibanaVersion = initContext.env.packageInfo.version; this.ruleDataService = null; @@ -85,25 +81,10 @@ export class RuleRegistryPlugin this.security = plugins.security; - const isWriteEnabled = (config: RuleRegistryPluginConfig, legacyConfig: SharedGlobalConfig) => { - const hasEnabledWrite = config.write.enabled; - const hasSetCustomKibanaIndex = legacyConfig.kibana.index !== '.kibana'; - const hasSetUnsafeAccess = config.unsafe.legacyMultiTenancy.enabled; - - if (!hasEnabledWrite) return false; - - // Not using legacy multi-tenancy - if (!hasSetCustomKibanaIndex) { - return hasEnabledWrite; - } else { - return hasSetUnsafeAccess; - } - }; - this.ruleDataService = new RuleDataService({ logger, kibanaVersion, - isWriteEnabled: isWriteEnabled(this.config, this.legacyConfig), + isWriteEnabled: this.config.write.enabled, getClusterClient: async () => { const deps = await startDependencies; return deps.core.elasticsearch.client.asInternalUser; diff --git a/x-pack/plugins/saved_objects_tagging/server/index.ts b/x-pack/plugins/saved_objects_tagging/server/index.ts index f2809bd411fa6d..e45ddbe5d07c8e 100644 --- a/x-pack/plugins/saved_objects_tagging/server/index.ts +++ b/x-pack/plugins/saved_objects_tagging/server/index.ts @@ -11,4 +11,4 @@ import { SavedObjectTaggingPlugin } from './plugin'; export { config } from './config'; export const plugin = (initializerContext: PluginInitializerContext) => - new SavedObjectTaggingPlugin(initializerContext); + new SavedObjectTaggingPlugin(); diff --git a/x-pack/plugins/saved_objects_tagging/server/plugin.test.ts b/x-pack/plugins/saved_objects_tagging/server/plugin.test.ts index fe053bdaa48cd5..5b514ff4bdd5b4 100644 --- a/x-pack/plugins/saved_objects_tagging/server/plugin.test.ts +++ b/x-pack/plugins/saved_objects_tagging/server/plugin.test.ts @@ -19,7 +19,7 @@ describe('SavedObjectTaggingPlugin', () => { let usageCollectionSetup: ReturnType; beforeEach(() => { - plugin = new SavedObjectTaggingPlugin(coreMock.createPluginInitializerContext()); + plugin = new SavedObjectTaggingPlugin(); featuresPluginSetup = featuresPluginMock.createSetup(); usageCollectionSetup = usageCollectionPluginMock.createSetupContract(); // `usageCollection` 'mocked' implementation use the real `CollectorSet` implementation diff --git a/x-pack/plugins/saved_objects_tagging/server/plugin.ts b/x-pack/plugins/saved_objects_tagging/server/plugin.ts index c6bfb0f3cd390c..6c5cd66595f7c5 100644 --- a/x-pack/plugins/saved_objects_tagging/server/plugin.ts +++ b/x-pack/plugins/saved_objects_tagging/server/plugin.ts @@ -5,14 +5,7 @@ * 2.0. */ -import { Observable } from 'rxjs'; -import { - CoreSetup, - CoreStart, - PluginInitializerContext, - Plugin, - SharedGlobalConfig, -} from 'src/core/server'; +import { CoreSetup, CoreStart, Plugin } from 'src/core/server'; import { PluginSetupContract as FeaturesPluginSetup } from '../../features/server'; import { UsageCollectionSetup } from '../../../../src/plugins/usage_collection/server'; import { SecurityPluginSetup } from '../../security/server'; @@ -30,12 +23,6 @@ interface SetupDeps { } export class SavedObjectTaggingPlugin implements Plugin<{}, {}, SetupDeps, {}> { - private readonly legacyConfig$: Observable; - - constructor(context: PluginInitializerContext) { - this.legacyConfig$ = context.config.legacy.globalConfig$; - } - public setup( { savedObjects, http }: CoreSetup, { features, usageCollection, security }: SetupDeps @@ -58,7 +45,7 @@ export class SavedObjectTaggingPlugin implements Plugin<{}, {}, SetupDeps, {}> { usageCollection.registerCollector( createTagUsageCollector({ usageCollection, - legacyConfig$: this.legacyConfig$, + kibanaIndex: savedObjects.getKibanaIndex(), }) ); } diff --git a/x-pack/plugins/saved_objects_tagging/server/usage/tag_usage_collector.ts b/x-pack/plugins/saved_objects_tagging/server/usage/tag_usage_collector.ts index 0e1f29124df9c5..3362965044bfd8 100644 --- a/x-pack/plugins/saved_objects_tagging/server/usage/tag_usage_collector.ts +++ b/x-pack/plugins/saved_objects_tagging/server/usage/tag_usage_collector.ts @@ -5,9 +5,6 @@ * 2.0. */ -import { Observable } from 'rxjs'; -import { take } from 'rxjs/operators'; -import { SharedGlobalConfig } from 'src/core/server'; import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/server'; import { TaggingUsageData } from './types'; import { fetchTagUsageData } from './fetch_tag_usage_data'; @@ -15,18 +12,17 @@ import { tagUsageCollectorSchema } from './schema'; export const createTagUsageCollector = ({ usageCollection, - legacyConfig$, + kibanaIndex, }: { usageCollection: UsageCollectionSetup; - legacyConfig$: Observable; + kibanaIndex: string; }) => { return usageCollection.makeUsageCollector({ type: 'saved_objects_tagging', isReady: () => true, schema: tagUsageCollectorSchema, - fetch: async ({ esClient }) => { - const { kibana } = await legacyConfig$.pipe(take(1)).toPromise(); - return fetchTagUsageData({ esClient, kibanaIndex: kibana.index }); + fetch: ({ esClient }) => { + return fetchTagUsageData({ esClient, kibanaIndex }); }, }); }; diff --git a/x-pack/plugins/security/server/plugin.ts b/x-pack/plugins/security/server/plugin.ts index 1e42d10b205aaf..0ebdae44c865c8 100644 --- a/x-pack/plugins/security/server/plugin.ts +++ b/x-pack/plugins/security/server/plugin.ts @@ -6,7 +6,6 @@ */ import type { Subscription } from 'rxjs'; -import { combineLatest } from 'rxjs'; import { map } from 'rxjs/operators'; import type { TypeOf } from '@kbn/config-schema'; @@ -203,6 +202,7 @@ export class SecurityPlugin core: CoreSetup, { features, licensing, taskManager, usageCollection, spaces }: PluginSetupDependencies ) { + this.kibanaIndexName = core.savedObjects.getKibanaIndex(); const config$ = this.initializerContext.config.create>().pipe( map((rawConfig) => createConfig(rawConfig, this.initializerContext.logger.get('config'), { @@ -210,12 +210,8 @@ export class SecurityPlugin }) ) ); - this.configSubscription = combineLatest([ - config$, - this.initializerContext.config.legacy.globalConfig$, - ]).subscribe(([config, { kibana }]) => { + this.configSubscription = config$.subscribe((config) => { this.config = config; - this.kibanaIndexName = kibana.index; }); const config = this.getConfig(); diff --git a/x-pack/plugins/security_solution/server/config.mock.ts b/x-pack/plugins/security_solution/server/config.mock.ts index c1d1e02ca35f46..1c404104fb3f2b 100644 --- a/x-pack/plugins/security_solution/server/config.mock.ts +++ b/x-pack/plugins/security_solution/server/config.mock.ts @@ -34,7 +34,6 @@ export const createMockConfig = (): ConfigType => { underlyingClient: UnderlyingLogClient.savedObjects, }, - kibanaIndex: '.kibana', experimentalFeatures: parseExperimentalConfigValue(enableExperimental), }; }; diff --git a/x-pack/plugins/security_solution/server/config.ts b/x-pack/plugins/security_solution/server/config.ts index 072e23b7a773c1..16a69eeb8e05fc 100644 --- a/x-pack/plugins/security_solution/server/config.ts +++ b/x-pack/plugins/security_solution/server/config.ts @@ -139,20 +139,15 @@ export const configSchema = schema.object({ export type ConfigSchema = TypeOf; export type ConfigType = ConfigSchema & { - kibanaIndex: string; experimentalFeatures: ExperimentalFeatures; }; export const createConfig = (context: PluginInitializerContext): ConfigType => { - const globalConfig = context.config.legacy.get(); const pluginConfig = context.config.get>(); - - const kibanaIndex = globalConfig.kibana.index; const experimentalFeatures = parseExperimentalConfigValue(pluginConfig.enableExperimental); return { ...pluginConfig, - kibanaIndex, experimentalFeatures, }; }; diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 14cf6f0a48799b..39aa1fb069f20e 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -107,6 +107,7 @@ export class Plugin implements ISecuritySolutionPlugin { private checkMetadataTransformsTask: CheckMetadataTransformsTask | undefined; private artifactsCache: LRU; private telemetryUsageCounter?: UsageCounter; + private kibanaIndex?: string; constructor(context: PluginInitializerContext) { this.pluginContext = context; @@ -130,6 +131,7 @@ export class Plugin implements ISecuritySolutionPlugin { const { pluginContext, config, logger, appClientFactory } = this; const experimentalFeatures = config.experimentalFeatures; + this.kibanaIndex = core.savedObjects.getKibanaIndex(); appClientFactory.setup({ getSpaceId: plugins.spaces?.spacesService?.getSpaceId, @@ -162,7 +164,7 @@ export class Plugin implements ISecuritySolutionPlugin { initUsageCollectors({ core, - kibanaIndex: config.kibanaIndex, + kibanaIndex: core.savedObjects.getKibanaIndex(), signalsIndex: config.signalsIndex, ml: plugins.ml, usageCollection: plugins.usageCollection, @@ -411,7 +413,8 @@ export class Plugin implements ISecuritySolutionPlugin { this.telemetryReceiver.start( core, - config.kibanaIndex, + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + this.kibanaIndex!, this.endpointAppContextService, exceptionListClient ); diff --git a/x-pack/plugins/spaces/server/plugin.ts b/x-pack/plugins/spaces/server/plugin.ts index 9455321c4eaa31..7f1abdb0a806c7 100644 --- a/x-pack/plugins/spaces/server/plugin.ts +++ b/x-pack/plugins/spaces/server/plugin.ts @@ -94,8 +94,6 @@ export class SpacesPlugin { private readonly config$: Observable; - private readonly kibanaIndexConfig$: Observable<{ kibana: { index: string } }>; - private readonly log: Logger; private readonly spacesLicenseService = new SpacesLicenseService(); @@ -110,7 +108,6 @@ export class SpacesPlugin constructor(initializerContext: PluginInitializerContext) { this.config$ = initializerContext.config.create(); - this.kibanaIndexConfig$ = initializerContext.config.legacy.globalConfig$; this.log = initializerContext.logger.get(); this.spacesService = new SpacesService(); this.spacesClientService = new SpacesClientService((message) => this.log.debug(message)); @@ -180,7 +177,7 @@ export class SpacesPlugin if (plugins.usageCollection) { registerSpacesUsageCollector(plugins.usageCollection, { - kibanaIndexConfig$: this.kibanaIndexConfig$, + kibanaIndex: core.savedObjects.getKibanaIndex(), features: plugins.features, licensing: plugins.licensing, usageStatsServicePromise, diff --git a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts index bdcb8afac30094..6bf410e21dcb3b 100644 --- a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts +++ b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.test.ts @@ -7,10 +7,7 @@ import * as Rx from 'rxjs'; -import { - elasticsearchServiceMock, - pluginInitializerContextConfigMock, -} from 'src/core/server/mocks'; +import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { createCollectorFetchContextMock } from '../../../../../src/plugins/usage_collection/server/mocks'; import type { KibanaFeature } from '../../../features/server'; @@ -43,6 +40,8 @@ const MOCK_USAGE_STATS: UsageStats = { 'apiCalls.disableLegacyUrlAliases.total': 17, }; +const kibanaIndex = '.kibana-tests'; + function setup({ license = { isAvailable: true }, features = [{ id: 'feature1' } as KibanaFeature, { id: 'feature2' } as KibanaFeature], @@ -53,6 +52,7 @@ function setup({ constructor({ fetch }: any) { this.fetch = fetch; } + // to make typescript happy public fakeFetchUsage() { return this.fetch; @@ -121,7 +121,7 @@ describe('error handling', () => { license: { isAvailable: true, type: 'basic' }, }); const collector = getSpacesUsageCollector(usageCollection as any, { - kibanaIndexConfig$: Rx.of({ kibana: { index: '.kibana' } }), + kibanaIndex, features, licensing, usageStatsServicePromise: Promise.resolve(usageStatsService), @@ -145,7 +145,7 @@ describe('with a basic license', () => { beforeAll(async () => { const collector = getSpacesUsageCollector(usageCollection as any, { - kibanaIndexConfig$: pluginInitializerContextConfigMock({}).legacy.globalConfig$, + kibanaIndex, features, licensing, usageStatsServicePromise: Promise.resolve(usageStatsService), @@ -164,7 +164,7 @@ describe('with a basic license', () => { size: 0, track_total_hits: true, }, - index: '.kibana-tests', + index: kibanaIndex, }); }); @@ -204,7 +204,7 @@ describe('with no license', () => { beforeAll(async () => { const collector = getSpacesUsageCollector(usageCollection as any, { - kibanaIndexConfig$: pluginInitializerContextConfigMock({}).legacy.globalConfig$, + kibanaIndex, features, licensing, usageStatsServicePromise: Promise.resolve(usageStatsService), @@ -245,7 +245,7 @@ describe('with platinum license', () => { beforeAll(async () => { const collector = getSpacesUsageCollector(usageCollection as any, { - kibanaIndexConfig$: pluginInitializerContextConfigMock({}).legacy.globalConfig$, + kibanaIndex, features, licensing, usageStatsServicePromise: Promise.resolve(usageStatsService), diff --git a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts index 27bc935b0ee3fe..f2ca7a9ebb3322 100644 --- a/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts +++ b/x-pack/plugins/spaces/server/usage_collection/spaces_usage_collector.ts @@ -5,7 +5,6 @@ * 2.0. */ -import type { Observable } from 'rxjs'; import { take } from 'rxjs/operators'; import type { ElasticsearchClient } from 'src/core/server'; @@ -150,7 +149,7 @@ export interface UsageData extends UsageStats { } interface CollectorDeps { - kibanaIndexConfig$: Observable<{ kibana: { index: string } }>; + kibanaIndex: string; features: PluginsSetup['features']; licensing: PluginsSetup['licensing']; usageStatsServicePromise: Promise; @@ -426,12 +425,10 @@ export function getSpacesUsageCollector( }, }, fetch: async ({ esClient }: CollectorFetchContext) => { - const { licensing, kibanaIndexConfig$, features, usageStatsServicePromise } = deps; + const { licensing, kibanaIndex, features, usageStatsServicePromise } = deps; const license = await licensing.license$.pipe(take(1)).toPromise(); const available = license.isAvailable; // some form of spaces is available for all valid licenses - const kibanaIndex = (await kibanaIndexConfig$.pipe(take(1)).toPromise()).kibana.index; - const usageData = await getSpacesUsage(esClient, kibanaIndex, features, available); const usageStats = await getUsageStats(usageStatsServicePromise, available); From 436c74a9ceb3b15550a63b74bb2c2773e3c60592 Mon Sep 17 00:00:00 2001 From: Xavier Mouligneau <189600+XavierM@users.noreply.github.com> Date: Mon, 25 Oct 2021 18:16:52 -0400 Subject: [PATCH 45/66] [SECURITY SOLUTION] [CASES] Allow cases to be there when security solutions privileges is none (#113573) * allow case to itself when security solutions privileges is none * bring back the right owner for cases * bring no privilege msg when needed it * fix types * fix test * adding test * review * deepLinks generation fixed * register home solution with old app id * fix get deep links * fix home link * fix unit test * add test * fix telemetry Co-authored-by: semd Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- packages/kbn-optimizer/limits.yml | 2 +- .../collectors/application_usage/schema.ts | 2 +- src/plugins/telemetry/schema/oss_plugins.json | 2 +- .../security_solution/common/constants.ts | 1 + .../public/app/deep_links/index.test.ts | 36 ++- .../public/app/deep_links/index.ts | 59 ++-- .../app/home/template_wrapper/index.tsx | 8 +- .../security_solution/public/app/index.tsx | 27 +- .../public/app/no_privileges.tsx | 47 +++ .../public/app/translations.ts | 18 ++ .../security_solution/public/app/types.ts | 4 +- .../cases/components/all_cases/index.tsx | 8 +- .../cases/components/case_view/index.tsx | 12 +- .../cases/components/create/index.test.tsx | 6 +- .../public/cases/components/create/index.tsx | 6 +- .../public/cases/pages/case_details.tsx | 4 +- .../public/cases/pages/configure_cases.tsx | 4 +- .../public/cases/pages/create_case.tsx | 4 +- .../public/cases/pages/utils.ts | 8 +- .../components/endpoint/link_to_app.tsx | 4 +- .../components/event_details/reason.tsx | 4 +- .../public/common/components/links/index.tsx | 12 +- .../navigation/breadcrumbs/index.test.ts | 72 ++--- .../navigation/breadcrumbs/index.ts | 4 +- .../navigation/tab_navigation/index.test.tsx | 2 +- .../index.test.tsx | 54 ++-- .../use_navigation_items.tsx | 79 +++-- .../components/user_privileges/index.tsx | 15 +- .../common/lib/kibana/__mocks__/index.ts | 4 +- .../public/common/lib/kibana/hooks.ts | 6 +- .../mock/endpoint/app_context_render.tsx | 6 +- .../public/common/mock/test_providers.tsx | 6 +- .../alerts_histogram_panel/index.test.tsx | 2 +- .../alerts_histogram_panel/index.tsx | 4 +- .../use_add_to_case_actions.tsx | 4 +- .../rules/rule_actions_overflow/index.tsx | 4 +- .../rules/step_rule_actions/index.tsx | 4 +- .../components/user_info/index.test.tsx | 4 +- .../use_fetch_detection_engine_privileges.ts | 6 +- .../use_fetch_list_privileges.ts | 6 +- .../detection_engine/rules/all/actions.tsx | 4 +- .../detection_engine/rules/all/columns.tsx | 6 +- .../detection_engine/rules/create/index.tsx | 8 +- .../detection_engine/rules/details/index.tsx | 6 +- .../detection_engine/rules/edit/index.tsx | 10 +- .../pages/detection_engine/rules/index.tsx | 6 +- .../pages/detection_engine/rules/utils.ts | 6 +- .../security_solution/public/helpers.test.ts | 62 ---- .../security_solution/public/helpers.test.tsx | 276 ++++++++++++++++++ .../public/{helpers.ts => helpers.tsx} | 80 ++++- .../public/hosts/pages/details/utils.ts | 6 +- .../context_menu_with_router_support.test.tsx | 6 +- .../view/hooks/use_endpoint_action_items.tsx | 8 +- .../pages/policy/view/policy_details.tsx | 4 +- .../components/policy_form_layout.test.tsx | 2 +- .../components/policy_form_layout.tsx | 4 +- .../policy_forms/protections/behavior.tsx | 4 +- .../view/policy_forms/protections/malware.tsx | 4 +- .../view/policy_forms/protections/memory.tsx | 4 +- .../policy_forms/protections/ransomware.tsx | 4 +- .../use_policy_trusted_apps_empty_hooks.ts | 8 +- .../list/policy_trusted_apps_list.test.tsx | 4 +- .../list/policy_trusted_apps_list.tsx | 8 +- .../components/trusted_apps_grid/index.tsx | 7 +- .../public/network/pages/details/utils.ts | 6 +- .../components/alerts_by_category/index.tsx | 4 +- .../components/endpoint_notice/index.tsx | 6 +- .../components/events_by_dataset/index.tsx | 4 +- .../components/overview_host/index.tsx | 4 +- .../overview_network/index.test.tsx | 2 +- .../components/overview_network/index.tsx | 4 +- .../navigate_to_host.tsx | 4 +- .../components/recent_cases/index.tsx | 8 +- .../components/recent_timelines/index.tsx | 4 +- .../security_solution/public/plugin.tsx | 43 +-- .../flyout/add_to_case_button/index.test.tsx | 4 +- .../flyout/add_to_case_button/index.tsx | 6 +- .../expandable_host.test.tsx.snap | 30 +- .../renderers/formatted_field_helpers.tsx | 6 +- .../public/timelines/pages/index.tsx | 4 +- .../plugins/security_solution/public/types.ts | 5 +- .../public/ueba/pages/details/utils.ts | 6 +- 82 files changed, 800 insertions(+), 447 deletions(-) create mode 100644 x-pack/plugins/security_solution/public/app/no_privileges.tsx delete mode 100644 x-pack/plugins/security_solution/public/helpers.test.ts create mode 100644 x-pack/plugins/security_solution/public/helpers.test.tsx rename x-pack/plugins/security_solution/public/{helpers.ts => helpers.tsx} (63%) diff --git a/packages/kbn-optimizer/limits.yml b/packages/kbn-optimizer/limits.yml index d1491ba63e6e60..453e5c174452d0 100644 --- a/packages/kbn-optimizer/limits.yml +++ b/packages/kbn-optimizer/limits.yml @@ -94,7 +94,7 @@ pageLoadAssetSize: expressionShape: 34008 interactiveSetup: 80000 expressionTagcloud: 27505 - securitySolution: 231753 + securitySolution: 273763 customIntegrations: 28810 expressionMetricVis: 23121 visTypeMetric: 23332 diff --git a/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts b/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts index 5f268a6fdfee76..7c112083875d15 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/application_usage/schema.ts @@ -156,7 +156,7 @@ export const applicationUsageSchema = { security_login: commonSchema, security_logout: commonSchema, security_overwritten_session: commonSchema, - securitySolution: commonSchema, + securitySolutionUI: commonSchema, siem: commonSchema, space_selector: commonSchema, uptime: commonSchema, diff --git a/src/plugins/telemetry/schema/oss_plugins.json b/src/plugins/telemetry/schema/oss_plugins.json index f9ca99a26ec198..437d50ad82473d 100644 --- a/src/plugins/telemetry/schema/oss_plugins.json +++ b/src/plugins/telemetry/schema/oss_plugins.json @@ -5018,7 +5018,7 @@ } } }, - "securitySolution": { + "securitySolutionUI": { "properties": { "appId": { "type": "keyword", diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 515f2beb539803..618497d8ea11bf 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -12,6 +12,7 @@ import { ENABLE_CASE_CONNECTOR } from '../../cases/common'; import { METADATA_TRANSFORMS_PATTERN } from './endpoint/constants'; export const APP_ID = 'securitySolution'; +export const APP_UI_ID = 'securitySolutionUI'; export const CASES_FEATURE_ID = 'securitySolutionCases'; export const SERVER_APP_ID = 'siem'; export const APP_NAME = 'Security'; diff --git a/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts b/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts index a3dc6565b19c6c..479ff4753dd759 100644 --- a/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts +++ b/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts @@ -8,7 +8,7 @@ import { getDeepLinks, PREMIUM_DEEP_LINK_IDS } from '.'; import { AppDeepLink, Capabilities } from '../../../../../../src/core/public'; import { SecurityPageName } from '../types'; import { mockGlobalState } from '../../common/mock'; -import { CASES_FEATURE_ID } from '../../../common/constants'; +import { CASES_FEATURE_ID, SERVER_APP_ID } from '../../../common/constants'; const findDeepLink = (id: string, deepLinks: AppDeepLink[]): AppDeepLink | null => deepLinks.reduce((deepLinkFound: AppDeepLink | null, deepLink) => { @@ -24,10 +24,11 @@ const findDeepLink = (id: string, deepLinks: AppDeepLink[]): AppDeepLink | null return null; }, null); +const basicLicense = 'basic'; +const platinumLicense = 'platinum'; + describe('deepLinks', () => { it('should return a subset of links for basic license and the full set for platinum', () => { - const basicLicense = 'basic'; - const platinumLicense = 'platinum'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense); const platinumLinks = getDeepLinks(mockGlobalState.app.enableExperimental, platinumLicense); @@ -57,26 +58,25 @@ describe('deepLinks', () => { }); it('should return case links for basic license with only read_cases capabilities', () => { - const basicLicense = 'basic'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, + [SERVER_APP_ID]: { show: true }, } as unknown as Capabilities); - expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy(); }); it('should return case links with NO deepLinks for basic license with only read_cases capabilities', () => { - const basicLicense = 'basic'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, + [SERVER_APP_ID]: { show: true }, } as unknown as Capabilities); expect(findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length === 0).toBeTruthy(); }); it('should return case links with deepLinks for basic license with crud_cases capabilities', () => { - const basicLicense = 'basic'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { [CASES_FEATURE_ID]: { read_cases: true, crud_cases: true }, + [SERVER_APP_ID]: { show: true }, } as unknown as Capabilities); expect( @@ -84,17 +84,32 @@ describe('deepLinks', () => { ).toBeTruthy(); }); + it('should return case links with deepLinks for basic license with crud_cases capabilities and security disabled', () => { + const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, platinumLicense, { + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: true }, + [SERVER_APP_ID]: { show: false }, + } as unknown as Capabilities); + expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy(); + }); + it('should return NO case links for basic license with NO read_cases capabilities', () => { - const basicLicense = 'basic'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, + [SERVER_APP_ID]: { show: true }, } as unknown as Capabilities); - expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeFalsy(); }); + it('should return empty links for any license', () => { + const emptyDeepLinks = getDeepLinks( + mockGlobalState.app.enableExperimental, + basicLicense, + {} as unknown as Capabilities + ); + expect(emptyDeepLinks.length).toBe(0); + }); + it('should return case links for basic license with undefined capabilities', () => { - const basicLicense = 'basic'; const basicLinks = getDeepLinks( mockGlobalState.app.enableExperimental, basicLicense, @@ -105,7 +120,6 @@ describe('deepLinks', () => { }); it('should return case deepLinks for basic license with undefined capabilities', () => { - const basicLicense = 'basic'; const basicLinks = getDeepLinks( mockGlobalState.app.enableExperimental, basicLicense, diff --git a/x-pack/plugins/security_solution/public/app/deep_links/index.ts b/x-pack/plugins/security_solution/public/app/deep_links/index.ts index aaa8ce789591ff..8daec76f280b20 100644 --- a/x-pack/plugins/security_solution/public/app/deep_links/index.ts +++ b/x-pack/plugins/security_solution/public/app/deep_links/index.ts @@ -6,16 +6,11 @@ */ import { i18n } from '@kbn/i18n'; -import { Subject } from 'rxjs'; +import { isEmpty } from 'lodash'; import { LicenseType } from '../../../../licensing/common/types'; import { SecurityPageName } from '../types'; -import { - AppDeepLink, - ApplicationStart, - AppNavLinkStatus, - AppUpdater, -} from '../../../../../../src/core/public'; +import { AppDeepLink, ApplicationStart, AppNavLinkStatus } from '../../../../../../src/core/public'; import { OVERVIEW, DETECT, @@ -50,6 +45,7 @@ import { UEBA_PATH, CASES_FEATURE_ID, HOST_ISOLATION_EXCEPTIONS_PATH, + SERVER_APP_ID, } from '../../../common/constants'; import { ExperimentalFeatures } from '../../../common/experimental_features'; @@ -356,25 +352,18 @@ export function getDeepLinks( ): AppDeepLink[] { const isPremium = isPremiumLicense(licenseType); + /** + * Recursive DFS function to filter deepLinks by permissions (licence and capabilities). + * Checks "end" deepLinks with no children first, the other parent deepLinks will be included if + * they still have children deepLinks after filtering + */ const filterDeepLinks = (deepLinks: AppDeepLink[]): AppDeepLink[] => { return deepLinks - .filter((deepLink) => { - if (!isPremium && PREMIUM_DEEP_LINK_IDS.has(deepLink.id)) { - return false; - } - if (deepLink.id === SecurityPageName.case) { - return capabilities == null || capabilities[CASES_FEATURE_ID].read_cases === true; - } - if (deepLink.id === SecurityPageName.ueba) { - return enableExperimental.uebaEnabled; - } - return true; - }) .map((deepLink) => { if ( deepLink.id === SecurityPageName.case && capabilities != null && - capabilities[CASES_FEATURE_ID].crud_cases === false + capabilities[CASES_FEATURE_ID]?.crud_cases === false ) { return { ...deepLink, @@ -388,6 +377,21 @@ export function getDeepLinks( }; } return deepLink; + }) + .filter((deepLink) => { + if (!isPremium && PREMIUM_DEEP_LINK_IDS.has(deepLink.id)) { + return false; + } + if (deepLink.path && deepLink.path.startsWith(CASES_PATH)) { + return capabilities == null || capabilities[CASES_FEATURE_ID]?.read_cases === true; + } + if (deepLink.id === SecurityPageName.ueba) { + return enableExperimental.uebaEnabled; + } + if (!isEmpty(deepLink.deepLinks)) { + return true; + } + return capabilities == null || capabilities[SERVER_APP_ID]?.show === true; }); }; @@ -402,18 +406,3 @@ export function isPremiumLicense(licenseType?: LicenseType): boolean { licenseType === 'trial' ); } - -export function updateGlobalNavigation({ - capabilities, - updater$, - enableExperimental, -}: { - capabilities: ApplicationStart['capabilities']; - updater$: Subject; - enableExperimental: ExperimentalFeatures; -}) { - updater$.next(() => ({ - navLinkStatus: AppNavLinkStatus.hidden, // needed to prevent showing main nav link - deepLinks: getDeepLinks(enableExperimental, undefined, capabilities), - })); -} diff --git a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx index 1803ab2b67455c..8588539c47a60a 100644 --- a/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx +++ b/x-pack/plugins/security_solution/public/app/home/template_wrapper/index.tsx @@ -78,8 +78,12 @@ export const SecuritySolutionTemplateWrapper: React.FC void) => { const ApplicationUsageTrackingProvider = usageCollection?.components.ApplicationUsageTrackingProvider ?? React.Fragment; @@ -36,25 +35,9 @@ export const renderApp = ({ > - {[ - ...subPlugins.overview.routes, - ...subPlugins.alerts.routes, - ...subPlugins.rules.routes, - ...subPlugins.exceptions.routes, - ...subPlugins.hosts.routes, - ...subPlugins.network.routes, - // will be undefined if enabledExperimental.uebaEnabled === false - ...(subPlugins.ueba != null ? subPlugins.ueba.routes : []), - ...subPlugins.timelines.routes, - ...subPlugins.cases.routes, - ...subPlugins.management.routes, - ].map((route, index) => ( - - ))} - - - - + {subPluginRoutes.map((route, index) => { + return ; + })} diff --git a/x-pack/plugins/security_solution/public/app/no_privileges.tsx b/x-pack/plugins/security_solution/public/app/no_privileges.tsx new file mode 100644 index 00000000000000..354e6eaf27198e --- /dev/null +++ b/x-pack/plugins/security_solution/public/app/no_privileges.tsx @@ -0,0 +1,47 @@ +/* + * 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, { useMemo } from 'react'; + +import { EuiPageTemplate } from '@elastic/eui'; +import { SecuritySolutionPageWrapper } from '../common/components/page_wrapper'; +import { EmptyPage } from '../common/components/empty_page'; +import { useKibana } from '../common/lib/kibana'; +import * as i18n from './translations'; + +interface NoPrivilegesPageProps { + subPluginKey: string; +} + +export const NoPrivilegesPage = React.memo(({ subPluginKey }) => { + const { docLinks } = useKibana().services; + const emptyPageActions = useMemo( + () => ({ + feature: { + icon: 'documents', + label: i18n.GO_TO_DOCUMENTATION, + url: `${docLinks.links.siem.privileges}`, + target: '_blank', + }, + }), + [docLinks] + ); + return ( + + + + + + ); +}); + +NoPrivilegesPage.displayName = 'NoPrivilegePage'; diff --git a/x-pack/plugins/security_solution/public/app/translations.ts b/x-pack/plugins/security_solution/public/app/translations.ts index e383725a7e40c9..7287739566e68c 100644 --- a/x-pack/plugins/security_solution/public/app/translations.ts +++ b/x-pack/plugins/security_solution/public/app/translations.ts @@ -80,3 +80,21 @@ export const INVESTIGATE = i18n.translate('xpack.securitySolution.navigation.inv export const MANAGE = i18n.translate('xpack.securitySolution.navigation.manage', { defaultMessage: 'Manage', }); + +export const GO_TO_DOCUMENTATION = i18n.translate( + 'xpack.securitySolution.goToDocumentationButton', + { + defaultMessage: 'View documentation', + } +); + +export const NO_PERMISSIONS_MSG = (subPluginKey: string) => + i18n.translate('xpack.securitySolution.noPermissionsMessage', { + values: { subPluginKey }, + defaultMessage: + 'To view {subPluginKey}, you must update privileges. For more information, contact your Kibana administrator.', + }); + +export const NO_PERMISSIONS_TITLE = i18n.translate('xpack.securitySolution.noPermissionsTitle', { + defaultMessage: 'Privileges required', +}); diff --git a/x-pack/plugins/security_solution/public/app/types.ts b/x-pack/plugins/security_solution/public/app/types.ts index 1942d2f836b1c9..52d69d7c4e7d98 100644 --- a/x-pack/plugins/security_solution/public/app/types.ts +++ b/x-pack/plugins/security_solution/public/app/types.ts @@ -18,7 +18,7 @@ import { import { RouteProps } from 'react-router-dom'; import { AppMountParameters } from '../../../../../src/core/public'; import { UsageCollectionSetup } from '../../../../../src/plugins/usage_collection/public'; -import { StartedSubPlugins, StartServices } from '../types'; +import { StartServices } from '../types'; /** * The React properties used to render `SecurityApp` as well as the `element` to render it into. @@ -26,7 +26,7 @@ import { StartedSubPlugins, StartServices } from '../types'; export interface RenderAppProps extends AppMountParameters { services: StartServices; store: Store; - subPlugins: StartedSubPlugins; + subPluginRoutes: RouteProps[]; usageCollection?: UsageCollectionSetup; } diff --git a/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx b/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx index 3c788e05530794..81eeae9866b7f8 100644 --- a/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/all_cases/index.tsx @@ -15,7 +15,7 @@ import { } from '../../../common/components/link_to'; import { SecurityPageName } from '../../../app/types'; import { useKibana } from '../../../common/lib/kibana'; -import { APP_ID } from '../../../../common/constants'; +import { APP_ID, APP_UI_ID } from '../../../../common/constants'; export interface AllCasesNavProps { detailName: string; @@ -36,7 +36,7 @@ export const AllCases = React.memo(({ userCanCrud }) => { const goToCreateCase = useCallback( async (ev) => { ev.preventDefault(); - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCreateCaseUrl(urlSearch), }); @@ -47,7 +47,7 @@ export const AllCases = React.memo(({ userCanCrud }) => { const goToCaseConfigure = useCallback( async (ev) => { ev.preventDefault(); - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getConfigureCasesUrl(urlSearch), }); @@ -61,7 +61,7 @@ export const AllCases = React.memo(({ userCanCrud }) => { return formatUrl(getCaseDetailsUrl({ id: detailName, subCaseId })); }, onClick: async ({ detailName, subCaseId, search }: AllCasesNavProps) => { - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseDetailsUrl({ id: detailName, search, subCaseId }), }); diff --git a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx index 47ba9e1e9cb8ff..bdf4a1dbc15793 100644 --- a/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/case_view/index.tsx @@ -19,7 +19,7 @@ import { Case, CaseViewRefreshPropInterface } from '../../../../../cases/common' import { TimelineId } from '../../../../common/types/timeline'; import { SecurityPageName } from '../../../app/types'; import { useKibana } from '../../../common/lib/kibana'; -import { APP_ID } from '../../../../common/constants'; +import { APP_UI_ID } from '../../../../common/constants'; import { timelineActions } from '../../../timelines/store/timeline'; import { useSourcererScope } from '../../../common/containers/sourcerer'; import { SourcererScopeName } from '../../../common/store/sourcerer/model'; @@ -153,7 +153,7 @@ export const CaseView = React.memo( if (e) { e.preventDefault(); } - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: allCasesLink, }); @@ -165,7 +165,7 @@ export const CaseView = React.memo( if (e) { e.preventDefault(); } - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseDetailsUrl({ id: caseId }), }); @@ -178,7 +178,7 @@ export const CaseView = React.memo( if (e) { e.preventDefault(); } - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getConfigureCasesUrl(search), }); @@ -193,7 +193,7 @@ export const CaseView = React.memo( if (e) { e.preventDefault(); } - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { path: getEndpointDetailsPath({ name: 'endpointActivityLog', selected_endpoint: endpointId, @@ -207,7 +207,7 @@ export const CaseView = React.memo( if (e) { e.preventDefault(); } - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId ?? ''), }); diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx index 42579c6fbc0ac0..2ce5f2904cb3b2 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.test.tsx @@ -16,7 +16,7 @@ import { Create } from '.'; import { useKibana } from '../../../common/lib/kibana'; import { Case } from '../../../../../cases/public/containers/types'; import { basicCase } from '../../../../../cases/public/containers/mock'; -import { APP_ID, SecurityPageName } from '../../../../common/constants'; +import { APP_ID, APP_UI_ID, SecurityPageName } from '../../../../common/constants'; import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search'; jest.mock('../use_insert_timeline'); @@ -71,7 +71,7 @@ describe('Create case', () => { ); await waitFor(() => - expect(mockNavigateToApp).toHaveBeenCalledWith(APP_ID, { + expect(mockNavigateToApp).toHaveBeenCalledWith(APP_UI_ID, { path: `?${mockRes}`, deepLinkId: SecurityPageName.case, }) @@ -96,7 +96,7 @@ describe('Create case', () => { ); await waitFor(() => - expect(mockNavigateToApp).toHaveBeenNthCalledWith(1, APP_ID, { + expect(mockNavigateToApp).toHaveBeenNthCalledWith(1, APP_UI_ID, { path: `/basic-case-id?${mockRes}`, deepLinkId: SecurityPageName.case, }) diff --git a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx index 72a41acf1d4567..6e6a536cd84371 100644 --- a/x-pack/plugins/security_solution/public/cases/components/create/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/create/index.tsx @@ -11,7 +11,7 @@ import { getCaseDetailsUrl, getCaseUrl } from '../../../common/components/link_t import { useKibana } from '../../../common/lib/kibana'; import * as timelineMarkdownPlugin from '../../../common/components/markdown_editor/plugins/timeline'; import { useInsertTimeline } from '../use_insert_timeline'; -import { APP_ID } from '../../../../common/constants'; +import { APP_ID, APP_UI_ID } from '../../../../common/constants'; import { useGetUrlSearch } from '../../../common/components/navigation/use_get_url_search'; import { navTabs } from '../../../app/home/home_navigations'; import { SecurityPageName } from '../../../app/types'; @@ -24,7 +24,7 @@ export const Create = React.memo(() => { const search = useGetUrlSearch(navTabs.case); const onSuccess = useCallback( async ({ id }) => - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseDetailsUrl({ id, search }), }), @@ -32,7 +32,7 @@ export const Create = React.memo(() => { ); const handleSetIsCancel = useCallback( async () => - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseUrl(search), }), diff --git a/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx b/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx index ea8205cddad599..6f35209ee1c9f5 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/case_details.tsx @@ -16,7 +16,7 @@ import { useGetUserCasesPermissions, useKibana } from '../../common/lib/kibana'; import { getCaseUrl } from '../../common/components/link_to'; import { navTabs } from '../../app/home/home_navigations'; import { CaseView } from '../components/case_view'; -import { APP_ID } from '../../../common/constants'; +import { APP_UI_ID } from '../../../common/constants'; import { Case } from '../../../../cases/common'; export const CaseDetailsPage = React.memo(() => { @@ -32,7 +32,7 @@ export const CaseDetailsPage = React.memo(() => { useEffect(() => { if (userPermissions != null && !userPermissions.read) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseUrl(search), }); diff --git a/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx index c5ed3454f1ca57..b5feb3dc698b7b 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/configure_cases.tsx @@ -18,7 +18,7 @@ import { navTabs } from '../../app/home/home_navigations'; import { CaseHeaderPage } from '../components/case_header_page'; import { WhitePageWrapper, SectionWrapper } from '../components/wrappers'; import * as i18n from './translations'; -import { APP_ID } from '../../../common/constants'; +import { APP_ID, APP_UI_ID } from '../../../common/constants'; const ConfigureCasesPageComponent: React.FC = () => { const { @@ -39,7 +39,7 @@ const ConfigureCasesPageComponent: React.FC = () => { useEffect(() => { if (userPermissions != null && !userPermissions.read) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseUrl(search), }); diff --git a/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx b/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx index 933e890ea2d9f2..2d7d83cb1b50ca 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx +++ b/x-pack/plugins/security_solution/public/cases/pages/create_case.tsx @@ -17,7 +17,7 @@ import { navTabs } from '../../app/home/home_navigations'; import { CaseHeaderPage } from '../components/case_header_page'; import { Create } from '../components/create'; import * as i18n from './translations'; -import { APP_ID } from '../../../common/constants'; +import { APP_UI_ID } from '../../../common/constants'; export const CreateCasePage = React.memo(() => { const userPermissions = useGetUserCasesPermissions(); @@ -37,7 +37,7 @@ export const CreateCasePage = React.memo(() => { useEffect(() => { if (userPermissions != null && !userPermissions.crud) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseUrl(search), }); diff --git a/x-pack/plugins/security_solution/public/cases/pages/utils.ts b/x-pack/plugins/security_solution/public/cases/pages/utils.ts index 968712009e1103..f791bc677d5c6d 100644 --- a/x-pack/plugins/security_solution/public/cases/pages/utils.ts +++ b/x-pack/plugins/security_solution/public/cases/pages/utils.ts @@ -13,7 +13,7 @@ import { getCaseDetailsUrl, getCreateCaseUrl } from '../../common/components/lin import { RouteSpyState } from '../../common/utils/route/types'; import * as i18n from './translations'; import { GetUrlForApp } from '../../common/components/navigation/types'; -import { APP_ID } from '../../../common/constants'; +import { APP_UI_ID } from '../../../common/constants'; import { SecurityPageName } from '../../app/types'; export const getBreadcrumbs = ( @@ -26,7 +26,7 @@ export const getBreadcrumbs = ( let breadcrumb = [ { text: i18n.PAGE_TITLE, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: queryParameters, }), @@ -37,7 +37,7 @@ export const getBreadcrumbs = ( ...breadcrumb, { text: i18n.CREATE_BC_TITLE, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCreateCaseUrl(queryParameters), }), @@ -48,7 +48,7 @@ export const getBreadcrumbs = ( ...breadcrumb, { text: params.state?.caseTitle ?? '', - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseDetailsUrl({ id: params.detailName, search: queryParameters }), }), diff --git a/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx b/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx index 201738d3293b2b..dba8dce6d2df74 100644 --- a/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx +++ b/x-pack/plugins/security_solution/public/common/components/endpoint/link_to_app.tsx @@ -8,7 +8,7 @@ import React, { memo, MouseEventHandler } from 'react'; import { EuiLink, EuiLinkProps, EuiButton, EuiButtonProps } from '@elastic/eui'; import { useNavigateToAppEventHandler } from '../../hooks/endpoint/use_navigate_to_app_event_handler'; -import { APP_ID } from '../../../../common/constants'; +import { APP_UI_ID } from '../../../../common/constants'; export type LinkToAppProps = (EuiLinkProps | EuiButtonProps) & { /** the app id - normally the value of the `id` in that plugin's `kibana.json` */ @@ -30,7 +30,7 @@ export type LinkToAppProps = (EuiLinkProps | EuiButtonProps) & { */ export const LinkToApp = memo( ({ - appId = APP_ID, + appId = APP_UI_ID, deepLinkId, appPath: path, appState: state, diff --git a/x-pack/plugins/security_solution/public/common/components/event_details/reason.tsx b/x-pack/plugins/security_solution/public/common/components/event_details/reason.tsx index aab0e866817838..88672e5e2f5dc6 100644 --- a/x-pack/plugins/security_solution/public/common/components/event_details/reason.tsx +++ b/x-pack/plugins/security_solution/public/common/components/event_details/reason.tsx @@ -14,7 +14,7 @@ import * as i18n from './translations'; import { TimelineEventsDetailsItem } from '../../../../common'; import { LinkAnchor } from '../links'; import { useKibana } from '../../lib/kibana'; -import { APP_ID, SecurityPageName } from '../../../../common/constants'; +import { APP_UI_ID, SecurityPageName } from '../../../../common/constants'; import { EVENT_DETAILS_PLACEHOLDER } from '../../../timelines/components/side_panel/event_details/translations'; import { getFieldValue } from '../../../detections/components/host_isolation/helpers'; @@ -64,7 +64,7 @@ export const ReasonComponent: React.FC = ({ eventId, data }) => { data-test-subj="ruleName" onClick={(ev: { preventDefault: () => void }) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId), }); diff --git a/x-pack/plugins/security_solution/public/common/components/links/index.tsx b/x-pack/plugins/security_solution/public/common/components/links/index.tsx index c74791b8b3aa7a..8b9188af7725cf 100644 --- a/x-pack/plugins/security_solution/public/common/components/links/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/links/index.tsx @@ -16,7 +16,7 @@ import { import React, { useMemo, useCallback, SyntheticEvent } from 'react'; import { isNil } from 'lodash/fp'; -import { IP_REPUTATION_LINKS_SETTING, APP_ID } from '../../../../common/constants'; +import { IP_REPUTATION_LINKS_SETTING, APP_UI_ID } from '../../../../common/constants'; import { DefaultFieldRendererOverflow, DEFAULT_MORE_MAX_HEIGHT, @@ -56,7 +56,7 @@ const UebaDetailsLinkComponent: React.FC<{ const goToUebaDetails = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.ueba, path: getUebaDetailsUrl(encodeURIComponent(hostName), search), }); @@ -99,7 +99,7 @@ const HostDetailsLinkComponent: React.FC<{ const goToHostDetails = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, path: getHostDetailsUrl(encodeURIComponent(hostName), search), }); @@ -183,7 +183,7 @@ const NetworkDetailsLinkComponent: React.FC<{ const goToNetworkDetails = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.network, path: getNetworkDetailsUrl(encodeURIComponent(encodeIpv6(ip)), flowTarget, search), }); @@ -229,7 +229,7 @@ const CaseDetailsLinkComponent: React.FC<{ const goToCaseDetails = useCallback( async (ev) => { ev.preventDefault(); - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseDetailsUrl({ id: detailName, search, subCaseId }), }); @@ -257,7 +257,7 @@ export const CreateCaseLink = React.memo<{ children: React.ReactNode }>(({ child const goToCreateCase = useCallback( async (ev) => { ev.preventDefault(); - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCreateCaseUrl(search), }); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts index 08f2ef2267f978..de934e00c91172 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.test.ts @@ -158,11 +158,11 @@ describe('Navigation Breadcrumbs', () => { ); expect(breadcrumbs).toEqual([ { - href: 'securitySolution/overview', + href: 'securitySolutionUI/overview', text: 'Security', }, { - href: "securitySolution/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", text: 'Hosts', }, { @@ -178,10 +178,10 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Network', - href: "securitySolution/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'Flows', @@ -196,10 +196,10 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Timelines', - href: "securitySolution/timelines?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/timelines?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, ]); }); @@ -210,14 +210,14 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Hosts', - href: "securitySolution/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'siem-kibana', - href: "securitySolution/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'Authentications', href: '' }, ]); @@ -229,14 +229,14 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Network', - href: "securitySolution/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: ipv4, - href: `securitySolution/network/ip/${ipv4}/source?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, + href: `securitySolutionUI/network/ip/${ipv4}/source?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, }, { text: 'Flows', href: '' }, ]); @@ -248,14 +248,14 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Network', - href: "securitySolution/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/network?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: ipv6, - href: `securitySolution/network/ip/${ipv6Encoded}/source?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, + href: `securitySolutionUI/network/ip/${ipv6Encoded}/source?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, }, { text: 'Flows', href: '' }, ]); @@ -267,7 +267,7 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Alerts', href: '', @@ -281,7 +281,7 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Exceptions', href: '', @@ -295,10 +295,10 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Rules', - href: "securitySolution/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, ]); }); @@ -309,10 +309,10 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Rules', - href: "securitySolution/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'Create', @@ -335,14 +335,14 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Rules', - href: "securitySolution/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: mockRuleName, - href: `securitySolution/rules/id/${mockDetailName}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, + href: `securitySolutionUI/rules/id/${mockDetailName}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, }, ]); }); @@ -361,14 +361,14 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Rules', - href: "securitySolution/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/rules?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: 'ALERT_RULE_NAME', - href: `securitySolution/rules/id/${mockDetailName}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, + href: `securitySolutionUI/rules/id/${mockDetailName}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, }, { text: 'Edit', @@ -383,10 +383,10 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Cases', - href: "securitySolution/case?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/case?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, ]); }); @@ -403,14 +403,14 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Cases', - href: "securitySolution/case?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/case?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", }, { text: sampleCase.name, - href: `securitySolution/case/${sampleCase.id}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, + href: `securitySolutionUI/case/${sampleCase.id}?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))`, }, ]); }); @@ -420,7 +420,7 @@ describe('Navigation Breadcrumbs', () => { getUrlForAppMock ); expect(breadcrumbs).toEqual([ - { text: 'Security', href: 'securitySolution/overview' }, + { text: 'Security', href: 'securitySolutionUI/overview' }, { text: 'Endpoints', href: '', @@ -442,17 +442,17 @@ describe('Navigation Breadcrumbs', () => { expect(setBreadcrumbsMock).toBeCalledWith([ expect.objectContaining({ text: 'Security', - href: 'securitySolution/overview', + href: 'securitySolutionUI/overview', onClick: expect.any(Function), }), expect.objectContaining({ text: 'Hosts', - href: "securitySolution/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/hosts?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", onClick: expect.any(Function), }), expect.objectContaining({ text: 'siem-kibana', - href: "securitySolution/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", + href: "securitySolutionUI/hosts/siem-kibana?sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2019-05-16T23:10:43.696Z',fromStr:now-24h,kind:relative,to:'2019-05-17T23:10:43.697Z',toStr:now)))", onClick: expect.any(Function), }), { diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts index 7262264d721035..029dc70c398e32 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts +++ b/x-pack/plugins/security_solution/public/common/components/navigation/breadcrumbs/index.ts @@ -9,7 +9,7 @@ import { getOr, omit } from 'lodash/fp'; import { useDispatch } from 'react-redux'; import { ChromeBreadcrumb } from '../../../../../../../../src/core/public'; -import { APP_NAME, APP_ID } from '../../../../../common/constants'; +import { APP_NAME, APP_UI_ID } from '../../../../../common/constants'; import { StartServices } from '../../../../types'; import { getBreadcrumbs as getHostDetailsBreadcrumbs } from '../../../../hosts/pages/details/utils'; import { getBreadcrumbs as getIPDetailsBreadcrumbs } from '../../../../network/pages/details'; @@ -92,7 +92,7 @@ export const getBreadcrumbsForRoute = ( getUrlForApp: GetUrlForApp ): ChromeBreadcrumb[] | null => { const spyState: RouteSpyState = omit('navTabs', object); - const overviewPath = getUrlForApp(APP_ID, { deepLinkId: SecurityPageName.overview }); + const overviewPath = getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.overview }); const siemRootBreadcrumb: ChromeBreadcrumb = { text: APP_NAME, href: getAppOverviewUrl(overviewPath), diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx index 18dd07a99824e1..b123a26257683b 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/tab_navigation/index.test.tsx @@ -116,7 +116,7 @@ describe('Table Navigation', () => { `EuiTab[data-test-subj="navigation-${HostsTableType.authentications}"]` ); expect(firstTab.props().href).toBe( - `/app/securitySolution/hosts/siem-window/authentications${SEARCH_QUERY}` + `/app/securitySolutionUI/hosts/siem-window/authentications${SEARCH_QUERY}` ); }); }); diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx index 396f431a3232de..3db485f87a68f4 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/index.test.tsx @@ -18,6 +18,7 @@ import { UrlInputsModel } from '../../../store/inputs/model'; import { useRouteSpy } from '../../../utils/route/use_route_spy'; import { useIsExperimentalFeatureEnabled } from '../../../hooks/use_experimental_features'; import { TestProviders } from '../../../mock'; +import { CASES_FEATURE_ID } from '../../../../../common/constants'; import { useCanSeeHostIsolationExceptionsMenu } from '../../../../management/pages/host_isolation_exceptions/view/hooks'; jest.mock('../../../lib/kibana/kibana_react'); @@ -88,9 +89,10 @@ describe('useSecuritySolutionNavigation', () => { `${appId}/${options?.deepLinkId ?? ''}${options?.path ?? ''}`, capabilities: { siem: { - crud_alerts: true, - read_alerts: true, + show: true, + crud: true, }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, }, }, chrome: { @@ -114,10 +116,10 @@ describe('useSecuritySolutionNavigation', () => { "id": "main", "items": Array [ Object { - "data-href": "securitySolution/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-overview", "disabled": false, - "href": "securitySolution/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/overview?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "overview", "isSelected": false, "name": "Overview", @@ -130,30 +132,30 @@ describe('useSecuritySolutionNavigation', () => { "id": "detect", "items": Array [ Object { - "data-href": "securitySolution/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-alerts", "disabled": false, - "href": "securitySolution/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/alerts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "alerts", "isSelected": false, "name": "Alerts", "onClick": [Function], }, Object { - "data-href": "securitySolution/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-rules", "disabled": false, - "href": "securitySolution/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/rules?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "rules", "isSelected": false, "name": "Rules", "onClick": [Function], }, Object { - "data-href": "securitySolution/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-exceptions", "disabled": false, - "href": "securitySolution/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/exceptions?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "exceptions", "isSelected": false, "name": "Exceptions", @@ -166,20 +168,20 @@ describe('useSecuritySolutionNavigation', () => { "id": "explore", "items": Array [ Object { - "data-href": "securitySolution/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-hosts", "disabled": false, - "href": "securitySolution/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/hosts?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "hosts", "isSelected": true, "name": "Hosts", "onClick": [Function], }, Object { - "data-href": "securitySolution/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-network", "disabled": false, - "href": "securitySolution/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/network?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "network", "isSelected": false, "name": "Network", @@ -192,10 +194,10 @@ describe('useSecuritySolutionNavigation', () => { "id": "investigate", "items": Array [ Object { - "data-href": "securitySolution/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-timelines", "disabled": false, - "href": "securitySolution/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/timelines?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "timelines", "isSelected": false, "name": "Timelines", @@ -208,40 +210,40 @@ describe('useSecuritySolutionNavigation', () => { "id": "manage", "items": Array [ Object { - "data-href": "securitySolution/endpoints", + "data-href": "securitySolutionUI/endpoints", "data-test-subj": "navigation-endpoints", "disabled": false, - "href": "securitySolution/endpoints", + "href": "securitySolutionUI/endpoints", "id": "endpoints", "isSelected": false, "name": "Endpoints", "onClick": [Function], }, Object { - "data-href": "securitySolution/trusted_apps", + "data-href": "securitySolutionUI/trusted_apps", "data-test-subj": "navigation-trusted_apps", "disabled": false, - "href": "securitySolution/trusted_apps", + "href": "securitySolutionUI/trusted_apps", "id": "trusted_apps", "isSelected": false, "name": "Trusted applications", "onClick": [Function], }, Object { - "data-href": "securitySolution/event_filters", + "data-href": "securitySolutionUI/event_filters", "data-test-subj": "navigation-event_filters", "disabled": false, - "href": "securitySolution/event_filters", + "href": "securitySolutionUI/event_filters", "id": "event_filters", "isSelected": false, "name": "Event filters", "onClick": [Function], }, Object { - "data-href": "securitySolution/host_isolation_exceptions", + "data-href": "securitySolutionUI/host_isolation_exceptions", "data-test-subj": "navigation-host_isolation_exceptions", "disabled": false, - "href": "securitySolution/host_isolation_exceptions", + "href": "securitySolutionUI/host_isolation_exceptions", "id": "host_isolation_exceptions", "isSelected": false, "name": "Host isolation exceptions", @@ -299,10 +301,10 @@ describe('useSecuritySolutionNavigation', () => { ); expect(caseNavItem).toMatchInlineSnapshot(` Object { - "data-href": "securitySolution/case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "data-href": "securitySolutionUI/case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "data-test-subj": "navigation-case", "disabled": false, - "href": "securitySolution/case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", + "href": "securitySolutionUI/case?query=(language:kuery,query:'host.name:%22security-solution-es%22')&sourcerer=()&timerange=(global:(linkTo:!(timeline),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)),timeline:(linkTo:!(global),timerange:(from:'2020-07-07T08:20:18.966Z',fromStr:now-24h,kind:relative,to:'2020-07-08T08:20:18.966Z',toStr:now)))", "id": "case", "isSelected": false, "name": "Cases", diff --git a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx index a1be69dd077ade..961090a01ba197 100644 --- a/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx +++ b/x-pack/plugins/security_solution/public/common/components/navigation/use_security_solution_navigation/use_navigation_items.tsx @@ -11,6 +11,7 @@ import { EuiSideNavItemType } from '@elastic/eui/src/components/side_nav/side_na import { securityNavGroup } from '../../../../app/home/home_navigations'; import { getSearch } from '../helpers'; import { PrimaryNavigationItemsProps } from './types'; +import { useKibana } from '../../../lib/kibana/kibana_react'; import { useGetUserCasesPermissions } from '../../../lib/kibana'; import { useNavigation } from '../../../lib/kibana/hooks'; import { NavTab } from '../types'; @@ -64,34 +65,52 @@ export const usePrimaryNavigationItems = ({ function usePrimaryNavigationItemsToDisplay(navTabs: Record) { const hasCasesReadPermissions = useGetUserCasesPermissions()?.read; const canSeeHostIsolationExceptions = useCanSeeHostIsolationExceptionsMenu(); - return useMemo(() => { - return [ - { - id: 'main', - name: '', - items: [navTabs.overview], - }, - { - ...securityNavGroup.detect, - items: [navTabs.alerts, navTabs.rules, navTabs.exceptions], - }, - { - ...securityNavGroup.explore, - items: [navTabs.hosts, navTabs.network, ...(navTabs.ueba != null ? [navTabs.ueba] : [])], - }, - { - ...securityNavGroup.investigate, - items: hasCasesReadPermissions ? [navTabs.timelines, navTabs.case] : [navTabs.timelines], - }, - { - ...securityNavGroup.manage, - items: [ - navTabs.endpoints, - navTabs.trusted_apps, - navTabs.event_filters, - ...(canSeeHostIsolationExceptions ? [navTabs.host_isolation_exceptions] : []), - ], - }, - ]; - }, [navTabs, hasCasesReadPermissions, canSeeHostIsolationExceptions]); + const uiCapabilities = useKibana().services.application.capabilities; + return useMemo( + () => + uiCapabilities.siem.show + ? [ + { + id: 'main', + name: '', + items: [navTabs.overview], + }, + { + ...securityNavGroup.detect, + items: [navTabs.alerts, navTabs.rules, navTabs.exceptions], + }, + { + ...securityNavGroup.explore, + items: [ + navTabs.hosts, + navTabs.network, + ...(navTabs.ueba != null ? [navTabs.ueba] : []), + ], + }, + { + ...securityNavGroup.investigate, + items: hasCasesReadPermissions + ? [navTabs.timelines, navTabs.case] + : [navTabs.timelines], + }, + { + ...securityNavGroup.manage, + items: [ + navTabs.endpoints, + navTabs.trusted_apps, + navTabs.event_filters, + ...(canSeeHostIsolationExceptions ? [navTabs.host_isolation_exceptions] : []), + ], + }, + ] + : hasCasesReadPermissions + ? [ + { + ...securityNavGroup.investigate, + items: [navTabs.case], + }, + ] + : [], + [uiCapabilities.siem.show, navTabs, hasCasesReadPermissions, canSeeHostIsolationExceptions] + ); } diff --git a/x-pack/plugins/security_solution/public/common/components/user_privileges/index.tsx b/x-pack/plugins/security_solution/public/common/components/user_privileges/index.tsx index bc0640296b33dc..05ccadeaf67ace 100644 --- a/x-pack/plugins/security_solution/public/common/components/user_privileges/index.tsx +++ b/x-pack/plugins/security_solution/public/common/components/user_privileges/index.tsx @@ -40,15 +40,16 @@ export const UserPrivilegesProvider = ({ kibanaCapabilities, children, }: UserPrivilegesProviderProps) => { - const listPrivileges = useFetchListPrivileges(); - const detectionEnginePrivileges = useFetchDetectionEnginePrivileges(); - const endpointPrivileges = useEndpointPrivileges(); - const [kibanaSecuritySolutionsPrivileges, setKibanaSecuritySolutionsPrivileges] = useState({ - crud: false, - read: false, - }); const crud: boolean = kibanaCapabilities[SERVER_APP_ID].crud === true; const read: boolean = kibanaCapabilities[SERVER_APP_ID].show === true; + const [kibanaSecuritySolutionsPrivileges, setKibanaSecuritySolutionsPrivileges] = useState({ + crud, + read, + }); + + const listPrivileges = useFetchListPrivileges(read); + const detectionEnginePrivileges = useFetchDetectionEnginePrivileges(read); + const endpointPrivileges = useEndpointPrivileges(); useEffect(() => { setKibanaSecuritySolutionsPrivileges((currPrivileges) => { diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts index 61ce5a8238b52f..5975977988a503 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/__mocks__/index.ts @@ -17,7 +17,7 @@ import { createStartServicesMock, createWithKibanaMock, } from '../kibana_react.mock'; -import { APP_ID } from '../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../common/constants'; const mockStartServicesMock = createStartServicesMock(); export const KibanaServices = { get: jest.fn(), getKibanaVersion: jest.fn(() => '8.0.0') }; @@ -65,7 +65,7 @@ export const useGetUserCasesPermissions = jest.fn(); export const useAppUrl = jest.fn().mockReturnValue({ getAppUrl: jest .fn() - .mockImplementation(({ appId = APP_ID, ...options }) => + .mockImplementation(({ appId = APP_UI_ID, ...options }) => mockStartServicesMock.application.getUrlForApp(appId, options) ), }); diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts index fdaed64ba91d7f..411dd5542038b6 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts @@ -13,7 +13,7 @@ import { i18n } from '@kbn/i18n'; import { camelCase, isArray, isObject } from 'lodash'; import { set } from '@elastic/safer-lodash-set'; import { - APP_ID, + APP_UI_ID, CASES_FEATURE_ID, DEFAULT_DATE_FORMAT, DEFAULT_DATE_FORMAT_TZ, @@ -174,7 +174,7 @@ export const useAppUrl = () => { const getAppUrl = useCallback( ({ - appId = APP_ID, + appId = APP_UI_ID, ...options }: { appId?: string; @@ -197,7 +197,7 @@ export const useNavigateTo = () => { const navigateTo = useCallback( ({ url, - appId = APP_ID, + appId = APP_UI_ID, ...options }: { url?: string; diff --git a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx index ed2a2252bd0d20..56f5dc28652aac 100644 --- a/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/endpoint/app_context_render.tsx @@ -22,7 +22,7 @@ import { createStartServicesMock } from '../../lib/kibana/kibana_react.mock'; import { SUB_PLUGINS_REDUCER, mockGlobalState, createSecuritySolutionStorageMock } from '..'; import { ExperimentalFeatures } from '../../../../common/experimental_features'; import { PLUGIN_ID } from '../../../../../fleet/common'; -import { APP_ID, APP_PATH } from '../../../../common/constants'; +import { APP_UI_ID, APP_PATH } from '../../../../common/constants'; import { KibanaContextProvider, KibanaServices } from '../../lib/kibana'; import { getDeepLinks } from '../../../app/deep_links'; import { fleetGetPackageListHttpMock } from '../../../management/pages/mocks'; @@ -176,7 +176,7 @@ const createCoreStartMock = ( switch (appId) { case PLUGIN_ID: return '/app/fleet'; - case APP_ID: + case APP_UI_ID: return `${APP_PATH}${ deepLinkId && deepLinkPaths[deepLinkId] ? deepLinkPaths[deepLinkId] : '' }${path ?? ''}`; @@ -186,7 +186,7 @@ const createCoreStartMock = ( }); coreStart.application.navigateToApp.mockImplementation((appId, { deepLinkId, path } = {}) => { - if (appId === APP_ID) { + if (appId === APP_UI_ID) { history.push( `${deepLinkId && deepLinkPaths[deepLinkId] ? deepLinkPaths[deepLinkId] : ''}${path ?? ''}` ); diff --git a/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx b/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx index 975487bb2b384e..7ea93bb7ce8fb2 100644 --- a/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx +++ b/x-pack/plugins/security_solution/public/common/mock/test_providers.tsx @@ -26,6 +26,7 @@ import { FieldHook } from '../../shared_imports'; import { SUB_PLUGINS_REDUCER } from './utils'; import { createSecuritySolutionStorageMock, localStorageMock } from './mock_local_storage'; import { UserPrivilegesProvider } from '../components/user_privileges'; +import { CASES_FEATURE_ID } from '../../../common/constants'; const state: State = mockGlobalState; @@ -76,7 +77,10 @@ const TestProvidersWithPrivilegesComponent: React.FC = ({ ({ eui: euiDarkVars, darkMode: true })}> {children} diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx index 484cd66575005b..54964de684ed76 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.test.tsx @@ -122,7 +122,7 @@ describe('AlertsHistogramPanel', () => { preventDefault: jest.fn(), }); - expect(mockNavigateToApp).toBeCalledWith('securitySolution', { + expect(mockNavigateToApp).toBeCalledWith('securitySolutionUI', { deepLinkId: SecurityPageName.alerts, path: '', }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx index 07fa81f27684ca..147d41e8533df8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_kpis/alerts_histogram_panel/index.tsx @@ -14,7 +14,7 @@ import { isEmpty } from 'lodash/fp'; import uuid from 'uuid'; import { useGlobalTime } from '../../../../common/containers/use_global_time'; -import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../../common/constants'; +import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../../common/constants'; import type { UpdateDateRange } from '../../../../common/components/charts/common'; import type { LegendItem } from '../../../../common/components/charts/draggable_legend_item'; import { escapeDataProviderId } from '../../../../common/components/drag_and_drop/helpers'; @@ -147,7 +147,7 @@ export const AlertsHistogramPanel = memo( const goToDetectionEngine = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.alerts, path: getDetectionEngineUrl(urlSearch), }); diff --git a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_to_case_actions.tsx b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_to_case_actions.tsx index a342b01b038cae..e14c3e916a35e8 100644 --- a/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_to_case_actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/alerts_table/timeline_actions/use_add_to_case_actions.tsx @@ -8,7 +8,7 @@ import { useMemo } from 'react'; import { useGetUserCasesPermissions, useKibana } from '../../../../common/lib/kibana'; import { TimelineId, TimelineNonEcsData } from '../../../../../common'; -import { APP_ID } from '../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../common/constants'; import { useInsertTimeline } from '../../../../cases/components/use_insert_timeline'; import { Ecs } from '../../../../../common/ecs'; @@ -39,7 +39,7 @@ export const useAddToCaseActions = ({ event: { data: nonEcsData ?? [], ecs: ecsData, _id: ecsData?._id }, useInsertTimeline: insertTimelineHook, casePermissions, - appId: APP_ID, + appId: APP_UI_ID, onClose: afterCaseSelection, } : null, diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx index 9f2728e0813f4e..eac1c2800955fb 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/rule_actions_overflow/index.tsx @@ -30,7 +30,7 @@ import { getRulesUrl } from '../../../../common/components/link_to/redirect_to_d import { getToolTipContent } from '../../../../common/utils/privileges'; import { useBoolState } from '../../../../common/hooks/use_bool_state'; import { useKibana } from '../../../../common/lib/kibana'; -import { APP_ID, SecurityPageName } from '../../../../../common/constants'; +import { APP_UI_ID, SecurityPageName } from '../../../../../common/constants'; const MyEuiButtonIcon = styled(EuiButtonIcon)` &.euiButtonIcon { @@ -62,7 +62,7 @@ const RuleActionsOverflowComponent = ({ const [, dispatchToaster] = useStateToaster(); const onRuleDeletedCallback = useCallback(() => { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRulesUrl(), }); diff --git a/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx b/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx index 2c7ca301002e16..72730deec6a19f 100644 --- a/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/rules/step_rule_actions/index.tsx @@ -35,7 +35,7 @@ import { RuleActionsField } from '../rule_actions_field'; import { useKibana } from '../../../../common/lib/kibana'; import { getSchema } from './schema'; import * as I18n from './translations'; -import { APP_ID } from '../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../common/constants'; import { useManageCaseAction } from './use_manage_case_action'; interface StepRuleActionsProps extends RuleStepProps { @@ -80,7 +80,7 @@ const StepRuleActionsComponent: FC = ({ } = useKibana(); const kibanaAbsoluteUrl = useMemo( () => - application.getUrlForApp(`${APP_ID}`, { + application.getUrlForApp(`${APP_UI_ID}`, { absolute: true, }), [application] diff --git a/x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx b/x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx index 1a8588017e4d6d..0447130e1bd144 100644 --- a/x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/user_info/index.test.tsx @@ -69,9 +69,7 @@ describe('useUserInfo', () => { const wrapper = ({ children }: { children: JSX.Element }) => ( {children} diff --git a/x-pack/plugins/security_solution/public/detections/components/user_privileges/use_fetch_detection_engine_privileges.ts b/x-pack/plugins/security_solution/public/detections/components/user_privileges/use_fetch_detection_engine_privileges.ts index 259245d25c4018..81fc83f3fdb1a6 100644 --- a/x-pack/plugins/security_solution/public/detections/components/user_privileges/use_fetch_detection_engine_privileges.ts +++ b/x-pack/plugins/security_solution/public/detections/components/user_privileges/use_fetch_detection_engine_privileges.ts @@ -13,7 +13,7 @@ import * as i18n from './translations'; export const useFetchPrivileges = () => useAsync(withOptionalSignal(getUserPrivilege)); -export const useFetchDetectionEnginePrivileges = () => { +export const useFetchDetectionEnginePrivileges = (isAppAvailable: boolean = true) => { const { start, ...detectionEnginePrivileges } = useFetchPrivileges(); const { addError } = useAppToasts(); const abortCtrlRef = useRef(new AbortController()); @@ -21,12 +21,12 @@ export const useFetchDetectionEnginePrivileges = () => { useEffect(() => { const { loading, result, error } = detectionEnginePrivileges; - if (!loading && !(result || error)) { + if (isAppAvailable && !loading && !(result || error)) { abortCtrlRef.current.abort(); abortCtrlRef.current = new AbortController(); start({ signal: abortCtrlRef.current.signal }); } - }, [start, detectionEnginePrivileges]); + }, [start, detectionEnginePrivileges, isAppAvailable]); useEffect(() => { return () => { diff --git a/x-pack/plugins/security_solution/public/detections/components/user_privileges/use_fetch_list_privileges.ts b/x-pack/plugins/security_solution/public/detections/components/user_privileges/use_fetch_list_privileges.ts index 2d0e6ee0248e7f..e1d6a90da1b0ac 100644 --- a/x-pack/plugins/security_solution/public/detections/components/user_privileges/use_fetch_list_privileges.ts +++ b/x-pack/plugins/security_solution/public/detections/components/user_privileges/use_fetch_list_privileges.ts @@ -22,7 +22,7 @@ interface ListPrivileges { }; } -export const useFetchListPrivileges = () => { +export const useFetchListPrivileges = (isAppAvailable: boolean = true) => { const http = useHttp(); const { lists } = useKibana().services; const { start: fetchListPrivileges, ...listPrivileges } = useReadListPrivileges(); @@ -32,12 +32,12 @@ export const useFetchListPrivileges = () => { useEffect(() => { const { loading, result, error } = listPrivileges; - if (lists && !loading && !(result || error)) { + if (isAppAvailable && lists && !loading && !(result || error)) { abortCtrlRef.current.abort(); abortCtrlRef.current = new AbortController(); fetchListPrivileges({ http, signal: abortCtrlRef.current.signal }); } - }, [http, lists, fetchListPrivileges, listPrivileges]); + }, [http, lists, fetchListPrivileges, listPrivileges, isAppAvailable]); useEffect(() => { return () => { diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.tsx index 214a7ac24da8a6..06e026ba8f6e11 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/actions.tsx @@ -7,7 +7,7 @@ import React, { Dispatch } from 'react'; import { NavigateToAppOptions } from '../../../../../../../../../src/core/public'; -import { APP_ID } from '../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../common/constants'; import { BulkAction } from '../../../../../../common/detection_engine/schemas/common/schemas'; import { CreateRulesSchema } from '../../../../../../common/detection_engine/schemas/request'; import { SecurityPageName } from '../../../../../app/types'; @@ -37,7 +37,7 @@ export const editRuleAction = ( ruleId: string, navigateToApp: (appId: string, options?: NavigateToAppOptions | undefined) => Promise ) => { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getEditRuleUrl(ruleId ?? ''), }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx index 6b05ee6403db38..6ca987a8d005c0 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx @@ -42,7 +42,7 @@ import { getToolTipContent, canEditRuleWithActions } from '../../../../../common import { PopoverTooltip } from './popover_tooltip'; import { TagsDisplay } from './tag_display'; import { getRuleStatusText } from '../../../../../../common/detection_engine/utils'; -import { APP_ID, SecurityPageName } from '../../../../../../common/constants'; +import { APP_UI_ID, SecurityPageName } from '../../../../../../common/constants'; import { DocLinksStart, NavigateToAppOptions } from '../../../../../../../../../src/core/public'; export const getActions = ( @@ -164,7 +164,7 @@ export const getColumns = ({ data-test-subj="ruleName" onClick={(ev: { preventDefault: () => void }) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(item.id), }); @@ -329,7 +329,7 @@ export const getMonitoringColumns = ( data-test-subj="ruleName" onClick={(ev: { preventDefault: () => void }) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(item.id), }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx index d37acaeb0ffee0..db41df644b3dc5 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/create/index.tsx @@ -47,7 +47,7 @@ import { formatRule, stepIsValid } from './helpers'; import * as i18n from './translations'; import { SecurityPageName } from '../../../../../app/types'; import { ruleStepsOrder } from '../utils'; -import { APP_ID } from '../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../common/constants'; import { useKibana } from '../../../../../common/lib/kibana'; const formHookNoop = async (): Promise => undefined; @@ -269,7 +269,7 @@ const CreateRulePageComponent: React.FC = () => { if (ruleName && ruleId) { displaySuccessToast(i18n.SUCCESSFULLY_CREATED_RULES(ruleName), dispatchToaster); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId), }); @@ -284,13 +284,13 @@ const CreateRulePageComponent: React.FC = () => { needsListsConfiguration ) ) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.alerts, path: getDetectionEngineUrl(), }); return null; } else if (!userHasPermissions(canUserCRUD)) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRulesUrl(), }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx index 774b9463bed695..ca71ac6783f59b 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/details/index.tsx @@ -89,7 +89,7 @@ import { LinkButton } from '../../../../../common/components/links'; import { useFormatUrl } from '../../../../../common/components/link_to'; import { ExceptionsViewer } from '../../../../../common/components/exceptions/viewer'; import { - APP_ID, + APP_UI_ID, DEFAULT_INDEX_PATTERN, DEFAULT_INDEX_PATTERN_EXPERIMENTAL, } from '../../../../../../common/constants'; @@ -574,7 +574,7 @@ const RuleDetailsPageComponent: React.FC = ({ const goToEditRule = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getEditRuleUrl(ruleId ?? ''), }); @@ -683,7 +683,7 @@ const RuleDetailsPageComponent: React.FC = ({ needsListsConfiguration ) ) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.alerts, path: getDetectionEngineUrl(), }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx index cea97aed28cc17..784290ad80d478 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/edit/index.tsx @@ -56,7 +56,7 @@ import * as i18n from './translations'; import { SecurityPageName } from '../../../../../app/types'; import { ruleStepsOrder } from '../utils'; import { useKibana } from '../../../../../common/lib/kibana'; -import { APP_ID } from '../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../common/constants'; const formHookNoop = async (): Promise => undefined; @@ -300,7 +300,7 @@ const EditRulePageComponent: FC = () => { const goToDetailsRule = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId ?? ''), }); @@ -318,7 +318,7 @@ const EditRulePageComponent: FC = () => { if (isSaved) { displaySuccessToast(i18n.SUCCESSFULLY_SAVED_RULE(rule?.name ?? ''), dispatchToaster); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId ?? ''), }); @@ -333,13 +333,13 @@ const EditRulePageComponent: FC = () => { needsListsConfiguration ) ) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.alerts, path: getDetectionEngineUrl(), }); return null; } else if (!userHasPermissions(canUserCRUD)) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId ?? ''), }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx index f957f77ac4c1a3..15ffd3579614a9 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/index.tsx @@ -36,7 +36,7 @@ import { useFormatUrl } from '../../../../common/components/link_to'; import { NeedAdminForUpdateRulesCallOut } from '../../../components/callouts/need_admin_for_update_callout'; import { MlJobCompatibilityCallout } from '../../../components/callouts/ml_job_compatibility_callout'; import { MissingPrivilegesCallOut } from '../../../components/callouts/missing_privileges_callout'; -import { APP_ID } from '../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../common/constants'; import { useKibana } from '../../../../common/lib/kibana'; type Func = () => Promise; @@ -125,7 +125,7 @@ const RulesPageComponent: React.FC = () => { const goToNewRule = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { deepLinkId: SecurityPageName.rules, path: getCreateRuleUrl() }); + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getCreateRuleUrl() }); }, [navigateToApp] ); @@ -156,7 +156,7 @@ const RulesPageComponent: React.FC = () => { needsListsConfiguration ) ) { - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.alerts, path: getDetectionEngineUrl(), }); diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts index 92c828b6cbf79c..d4ce5da4a14132 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/utils.ts @@ -16,7 +16,7 @@ import * as i18nRules from './translations'; import { RouteSpyState } from '../../../../common/utils/route/types'; import { GetUrlForApp } from '../../../../common/components/navigation/types'; import { SecurityPageName } from '../../../../app/types'; -import { APP_ID, RULES_PATH } from '../../../../../common/constants'; +import { APP_UI_ID, RULES_PATH } from '../../../../../common/constants'; import { RuleStep, RuleStepsOrder } from './types'; export const ruleStepsOrder: RuleStepsOrder = [ @@ -32,7 +32,7 @@ const getRulesBreadcrumb = (pathname: string, search: string[], getUrlForApp: Ge if (tabPath === 'rules') { return { text: i18nRules.PAGE_TITLE, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRulesUrl(!isEmpty(search[0]) ? search[0] : ''), }), @@ -64,7 +64,7 @@ export const getBreadcrumbs = ( ...breadcrumb, { text: params.state.ruleName, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(params.detailName, !isEmpty(search[0]) ? search[0] : ''), }), diff --git a/x-pack/plugins/security_solution/public/helpers.test.ts b/x-pack/plugins/security_solution/public/helpers.test.ts deleted file mode 100644 index f2e37cd995a4fe..00000000000000 --- a/x-pack/plugins/security_solution/public/helpers.test.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 { parseRoute, getHostRiskIndex } from './helpers'; - -describe('public helpers parseRoute', () => { - it('should properly parse hash route', () => { - const hashSearch = - '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))'; - const hashLocation = { - hash: `#/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`, - pathname: '/app/siem', - search: '', - }; - - expect(parseRoute(hashLocation)).toEqual({ - pageName: 'detections', - path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`, - search: hashSearch, - }); - }); - - it('should properly parse non-hash route', () => { - const nonHashLocation = { - hash: '', - pathname: '/app/security/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit', - search: - '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))', - }; - - expect(parseRoute(nonHashLocation)).toEqual({ - pageName: 'detections', - path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${nonHashLocation.search}`, - search: nonHashLocation.search, - }); - }); - - it('should properly parse non-hash subplugin route', () => { - const nonHashLocation = { - hash: '', - pathname: '/app/security/detections', - search: - '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))', - }; - - expect(parseRoute(nonHashLocation)).toEqual({ - pageName: 'detections', - path: `${nonHashLocation.search}`, - search: nonHashLocation.search, - }); - }); -}); - -describe('public helpers export getHostRiskIndex', () => { - it('should properly return index if space is specified', () => { - expect(getHostRiskIndex('testName')).toEqual('ml_host_risk_score_latest_testName'); - }); -}); diff --git a/x-pack/plugins/security_solution/public/helpers.test.tsx b/x-pack/plugins/security_solution/public/helpers.test.tsx new file mode 100644 index 00000000000000..3475ac7c28f7ae --- /dev/null +++ b/x-pack/plugins/security_solution/public/helpers.test.tsx @@ -0,0 +1,276 @@ +/* + * 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 { shallow } from 'enzyme'; +import { Capabilities } from '../../../../src/core/public'; +import { CASES_FEATURE_ID, SERVER_APP_ID } from '../common/constants'; +import { + parseRoute, + getHostRiskIndex, + isSubPluginAvailable, + getSubPluginRoutesByCapabilities, + RedirectRoute, +} from './helpers'; +import { StartedSubPlugins } from './types'; + +describe('public helpers parseRoute', () => { + it('should properly parse hash route', () => { + const hashSearch = + '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))'; + const hashLocation = { + hash: `#/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`, + pathname: '/app/siem', + search: '', + }; + + expect(parseRoute(hashLocation)).toEqual({ + pageName: 'detections', + path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${hashSearch}`, + search: hashSearch, + }); + }); + + it('should properly parse non-hash route', () => { + const nonHashLocation = { + hash: '', + pathname: '/app/security/detections/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit', + search: + '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))', + }; + + expect(parseRoute(nonHashLocation)).toEqual({ + pageName: 'detections', + path: `/rules/id/78acc090-bbaa-4a86-916b-ea44784324ae/edit${nonHashLocation.search}`, + search: nonHashLocation.search, + }); + }); + + it('should properly parse non-hash subplugin route', () => { + const nonHashLocation = { + hash: '', + pathname: '/app/security/detections', + search: + '?timerange=(global:(linkTo:!(timeline),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)),timeline:(linkTo:!(global),timerange:(from:%272020-09-06T11:43:55.814Z%27,fromStr:now-24h,kind:relative,to:%272020-09-07T11:43:55.814Z%27,toStr:now)))', + }; + + expect(parseRoute(nonHashLocation)).toEqual({ + pageName: 'detections', + path: `${nonHashLocation.search}`, + search: nonHashLocation.search, + }); + }); +}); + +describe('public helpers export getHostRiskIndex', () => { + it('should properly return index if space is specified', () => { + expect(getHostRiskIndex('testName')).toEqual('ml_host_risk_score_latest_testName'); + }); +}); + +describe('#getSubPluginRoutesByCapabilities', () => { + const mockRender = () => null; + const mockSubPlugins = { + alerts: { routes: [{ path: 'alerts', render: mockRender }] }, + cases: { routes: [{ path: 'cases', render: mockRender }] }, + } as unknown as StartedSubPlugins; + it('cases routes should return NoPrivilegesPage component when cases plugin is NOT available ', () => { + const routes = getSubPluginRoutesByCapabilities(mockSubPlugins, { + [SERVER_APP_ID]: { show: true, crud: false }, + [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, + } as unknown as Capabilities); + const casesRoute = routes.find((r) => r.path === 'cases'); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const CasesView = (casesRoute?.component ?? mockRender) as React.ComponentType; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); + + it('alerts should return NoPrivilegesPage component when siem plugin is NOT available ', () => { + const routes = getSubPluginRoutesByCapabilities(mockSubPlugins, { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, + } as unknown as Capabilities); + const alertsRoute = routes.find((r) => r.path === 'alerts'); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const AlertsView = (alertsRoute?.component ?? mockRender) as React.ComponentType; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); + + it('should return NoPrivilegesPage for each route when both plugins are NOT available ', () => { + const routes = getSubPluginRoutesByCapabilities(mockSubPlugins, { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, + } as unknown as Capabilities); + const casesRoute = routes.find((r) => r.path === 'cases'); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const CasesView = (casesRoute?.component ?? mockRender) as React.ComponentType; + + const alertsRoute = routes.find((r) => r.path === 'alerts'); + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const AlertsView = (alertsRoute?.component ?? mockRender) as React.ComponentType; + + expect(shallow()).toMatchInlineSnapshot(` + + `); + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); +}); + +describe('#isSubPluginAvailable', () => { + it('plugin outsides of cases should be available if siem privilege is all and independently of cases privileges', () => { + expect( + isSubPluginAvailable('pluginKey', { + [SERVER_APP_ID]: { show: true, crud: true }, + [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, + } as unknown as Capabilities) + ).toBeTruthy(); + }); + + it('plugin outsides of cases should be available if siem privilege is read and independently of cases privileges', () => { + expect( + isSubPluginAvailable('pluginKey', { + [SERVER_APP_ID]: { show: true, crud: false }, + [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, + } as unknown as Capabilities) + ).toBeTruthy(); + }); + + it('plugin outsides of cases should NOT be available if siem privilege is none and independently of cases privileges', () => { + expect( + isSubPluginAvailable('pluginKey', { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, + } as unknown as Capabilities) + ).toBeFalsy(); + }); + + it('cases plugin should be available if cases privilege is all and independently of siem privileges', () => { + expect( + isSubPluginAvailable('cases', { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: true }, + } as unknown as Capabilities) + ).toBeTruthy(); + }); + + it('cases plugin should be available if cases privilege is read and independently of siem privileges', () => { + expect( + isSubPluginAvailable('cases', { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, + } as unknown as Capabilities) + ).toBeTruthy(); + }); + + it('cases plugin should NOT be available if cases privilege is none independently of siem privileges', () => { + expect( + isSubPluginAvailable('pluginKey', { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, + } as unknown as Capabilities) + ).toBeFalsy(); + }); +}); + +describe('RedirectRoute', () => { + it('RedirectRoute should redirect to overview page when siem and case privileges are all', () => { + const mockCapabilitities = { + [SERVER_APP_ID]: { show: true, crud: true }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: true }, + } as unknown as Capabilities; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); + + it('RedirectRoute should redirect to overview page when siem and case privileges are read', () => { + const mockCapabilitities = { + [SERVER_APP_ID]: { show: true, crud: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, + } as unknown as Capabilities; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); + + it('RedirectRoute should redirect to overview page when siem and case privileges are off', () => { + const mockCapabilitities = { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, + } as unknown as Capabilities; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); + + it('RedirectRoute should redirect to overview page when siem privilege is read and case privilege is all', () => { + const mockCapabilitities = { + [SERVER_APP_ID]: { show: true, crud: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: true }, + } as unknown as Capabilities; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); + + it('RedirectRoute should redirect to overview page when siem privilege is read and case privilege is read', () => { + const mockCapabilitities = { + [SERVER_APP_ID]: { show: true, crud: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: true }, + } as unknown as Capabilities; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); + + it('RedirectRoute should redirect to cases page when siem privilege is none and case privilege is read', () => { + const mockCapabilitities = { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, + } as unknown as Capabilities; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); + + it('RedirectRoute should redirect to cases page when siem privilege is none and case privilege is all', () => { + const mockCapabilitities = { + [SERVER_APP_ID]: { show: false, crud: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: true }, + } as unknown as Capabilities; + expect(shallow()).toMatchInlineSnapshot(` + + `); + }); +}); diff --git a/x-pack/plugins/security_solution/public/helpers.ts b/x-pack/plugins/security_solution/public/helpers.tsx similarity index 63% rename from x-pack/plugins/security_solution/public/helpers.ts rename to x-pack/plugins/security_solution/public/helpers.tsx index aba46cffee193d..066e6a4cb4684e 100644 --- a/x-pack/plugins/security_solution/public/helpers.ts +++ b/x-pack/plugins/security_solution/public/helpers.tsx @@ -6,24 +6,30 @@ */ import { isEmpty } from 'lodash/fp'; -import { matchPath } from 'react-router-dom'; +import React from 'react'; +import { matchPath, RouteProps, Redirect } from 'react-router-dom'; -import { CoreStart } from '../../../../src/core/public'; +import { Capabilities, CoreStart } from '../../../../src/core/public'; import { ALERTS_PATH, - APP_ID, + APP_UI_ID, EXCEPTIONS_PATH, RULES_PATH, UEBA_PATH, RISKY_HOSTS_INDEX_PREFIX, + SERVER_APP_ID, + CASES_FEATURE_ID, + OVERVIEW_PATH, + CASES_PATH, } from '../common/constants'; import { FactoryQueryTypes, StrategyResponseType, } from '../common/search_strategy/security_solution'; import { TimelineEqlResponse } from '../common/search_strategy/timeline'; +import { NoPrivilegesPage } from './app/no_privileges'; import { SecurityPageName } from './app/types'; -import { InspectResponse } from './types'; +import { CASES_SUB_PLUGIN_KEY, InspectResponse, StartedSubPlugins } from './types'; export const parseRoute = (location: Pick) => { if (!isEmpty(location.hash)) { @@ -59,49 +65,49 @@ export const manageOldSiemRoutes = async (coreStart: CoreStart) => { switch (pageName) { case SecurityPageName.overview: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.overview, replace: true, path, }); break; case 'ml-hosts': - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, replace: true, path: `/ml-hosts${path}`, }); break; case SecurityPageName.hosts: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, replace: true, path, }); break; case 'ml-network': - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.network, replace: true, path: `/ml-network${path}`, }); break; case SecurityPageName.network: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.network, replace: true, path, }); break; case SecurityPageName.timelines: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.timelines, replace: true, path, }); break; case SecurityPageName.case: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, replace: true, path, @@ -109,28 +115,28 @@ export const manageOldSiemRoutes = async (coreStart: CoreStart) => { break; case SecurityPageName.detections: case SecurityPageName.alerts: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.alerts, replace: true, path, }); break; case SecurityPageName.rules: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, replace: true, path, }); break; case SecurityPageName.exceptions: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.exceptions, replace: true, path, }); break; default: - application.navigateToApp(APP_ID, { + application.navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.overview, replace: true, path, @@ -158,3 +164,47 @@ export const isDetectionsPath = (pathname: string): boolean => { export const getHostRiskIndex = (spaceId: string): string => { return `${RISKY_HOSTS_INDEX_PREFIX}${spaceId}`; }; + +export const getSubPluginRoutesByCapabilities = ( + subPlugins: StartedSubPlugins, + capabilities: Capabilities +): RouteProps[] => { + return [ + ...Object.entries(subPlugins).reduce((acc, [key, value]) => { + if (isSubPluginAvailable(key, capabilities)) { + return [...acc, ...value.routes]; + } + return [ + ...acc, + ...value.routes.map((route: RouteProps) => ({ + path: route.path, + component: () => , + })), + ]; + }, []), + { + path: '', + component: () => , + }, + ]; +}; + +export const isSubPluginAvailable = (pluginKey: string, capabilities: Capabilities): boolean => { + if (CASES_SUB_PLUGIN_KEY === pluginKey) { + return capabilities[CASES_FEATURE_ID].read_cases === true; + } + return capabilities[SERVER_APP_ID].show === true; +}; + +export const RedirectRoute = React.memo<{ capabilities: Capabilities }>(({ capabilities }) => { + const overviewAvailable = isSubPluginAvailable('overview', capabilities); + const casesAvailable = isSubPluginAvailable(CASES_SUB_PLUGIN_KEY, capabilities); + if (overviewAvailable) { + return ; + } + if (casesAvailable) { + return ; + } + return ; +}); +RedirectRoute.displayName = 'RedirectRoute'; diff --git a/x-pack/plugins/security_solution/public/hosts/pages/details/utils.ts b/x-pack/plugins/security_solution/public/hosts/pages/details/utils.ts index f4e14605cab477..3a584f7fefb500 100644 --- a/x-pack/plugins/security_solution/public/hosts/pages/details/utils.ts +++ b/x-pack/plugins/security_solution/public/hosts/pages/details/utils.ts @@ -15,7 +15,7 @@ import { getHostDetailsUrl } from '../../../common/components/link_to/redirect_t import * as i18n from '../translations'; import { HostRouteSpyState } from '../../../common/utils/route/types'; import { GetUrlForApp } from '../../../common/components/navigation/types'; -import { APP_ID } from '../../../../common/constants'; +import { APP_UI_ID } from '../../../../common/constants'; import { SecurityPageName } from '../../../app/types'; export const type = hostsModel.HostsType.details; @@ -37,7 +37,7 @@ export const getBreadcrumbs = ( let breadcrumb = [ { text: i18n.PAGE_TITLE, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { path: !isEmpty(search[0]) ? search[0] : '', deepLinkId: SecurityPageName.hosts, }), @@ -49,7 +49,7 @@ export const getBreadcrumbs = ( ...breadcrumb, { text: params.detailName, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { path: getHostDetailsUrl(params.detailName, !isEmpty(search[0]) ? search[0] : ''), deepLinkId: SecurityPageName.hosts, }), diff --git a/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.test.tsx b/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.test.tsx index ae343a57c734ff..288c0c074e93d3 100644 --- a/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.test.tsx +++ b/x-pack/plugins/security_solution/public/management/components/context_menu_with_router_support/context_menu_with_router_support.test.tsx @@ -13,7 +13,7 @@ import { ContextMenuWithRouterSupportProps, } from './context_menu_with_router_support'; import { act, fireEvent, waitForElementToBeRemoved } from '@testing-library/react'; -import { APP_ID } from '../../../../common/constants'; +import { APP_UI_ID } from '../../../../common/constants'; describe('When using the ContextMenuWithRouterSupport component', () => { let appTestContext: AppContextTestRender; @@ -42,7 +42,7 @@ describe('When using the ContextMenuWithRouterSupport component', () => { }, { children: 'click me 2', - navigateAppId: APP_ID, + navigateAppId: APP_UI_ID, navigateOptions: { path: '/one/two/three', }, @@ -126,7 +126,7 @@ describe('When using the ContextMenuWithRouterSupport component', () => { }); expect(appTestContext.coreStart.application.navigateToApp).toHaveBeenCalledWith( - APP_ID, + APP_UI_ID, expect.objectContaining({ path: '/one/two/three' }) ); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx index 81432edbdd5fe8..a766b9a23082a6 100644 --- a/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/endpoint_hosts/view/hooks/use_endpoint_action_items.tsx @@ -7,7 +7,7 @@ import React, { useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { APP_ID } from '../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../common/constants'; import { pagePathGetters } from '../../../../../../../fleet/public'; import { getEndpointDetailsPath } from '../../../../common/routing'; import { HostMetadata, MaybeImmutable } from '../../../../../../common/endpoint/types'; @@ -67,7 +67,7 @@ export const useEndpointActionItems = ( 'data-test-subj': 'unIsolateLink', icon: 'logoSecurity', key: 'unIsolateHost', - navigateAppId: APP_ID, + navigateAppId: APP_UI_ID, navigateOptions: { path: endpointUnIsolatePath, }, @@ -85,7 +85,7 @@ export const useEndpointActionItems = ( 'data-test-subj': 'isolateLink', icon: 'logoSecurity', key: 'isolateHost', - navigateAppId: APP_ID, + navigateAppId: APP_UI_ID, navigateOptions: { path: endpointIsolatePath, }, @@ -105,7 +105,7 @@ export const useEndpointActionItems = ( 'data-test-subj': 'hostLink', icon: 'logoSecurity', key: 'hostDetailsLink', - navigateAppId: APP_ID, + navigateAppId: APP_UI_ID, navigateOptions: { path: `/hosts/${endpointHostName}` }, href: getAppUrl({ path: `/hosts/${endpointHostName}` }), children: ( diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx index 65308012df0807..6b5d6f03aca286 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_details.tsx @@ -28,7 +28,7 @@ import { import { PolicyDetailsRouteState } from '../../../../../common/endpoint/types'; import { getEndpointListPath } from '../../../common/routing'; import { useAppUrl } from '../../../../common/lib/kibana'; -import { APP_ID } from '../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../common/constants'; export const PolicyDetails = React.memo(() => { // TODO: Remove this and related code when removing FF @@ -68,7 +68,7 @@ export const PolicyDetails = React.memo(() => { ), backButtonUrl: getAppUrl({ path: endpointListPath }), onBackButtonNavigateTo: [ - APP_ID, + APP_UI_ID, { path: endpointListPath, }, diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx index 650bf6115c9d9c..28f2ecf7eb98ef 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.test.tsx @@ -118,7 +118,7 @@ describe('Policy Form Layout', () => { cancelbutton.simulate('click', { button: 0 }); const navigateToAppMockedCalls = coreStart.application.navigateToApp.mock.calls; expect(navigateToAppMockedCalls[navigateToAppMockedCalls.length - 1]).toEqual([ - 'securitySolution', + 'securitySolutionUI', { path: endpointListPath }, ]); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx index bae2c21242d97f..2345deabb5101d 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/components/policy_form_layout.tsx @@ -35,7 +35,7 @@ import { SpyRoute } from '../../../../../../common/utils/route/spy_routes'; import { SecurityPageName } from '../../../../../../app/types'; import { getEndpointListPath } from '../../../../../common/routing'; import { useNavigateToAppEventHandler } from '../../../../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; -import { APP_ID } from '../../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../../common/constants'; import { PolicyDetailsRouteState } from '../../../../../../../common/endpoint/types'; import { SecuritySolutionPageWrapper } from '../../../../../../common/components/page_wrapper'; import { PolicyDetailsForm } from '../../policy_details_form'; @@ -65,7 +65,7 @@ export const PolicyFormLayout = React.memo(() => { const routingOnCancelNavigateTo = routeState?.onCancelNavigateTo; const navigateToAppArguments = useMemo((): Parameters => { - return routingOnCancelNavigateTo ?? [APP_ID, { path: hostListRouterPath }]; + return routingOnCancelNavigateTo ?? [APP_UI_ID, { path: hostListRouterPath }]; }, [hostListRouterPath, routingOnCancelNavigateTo]); // Handle showing update statuses diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/behavior.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/behavior.tsx index 06cf666f2950ee..ccb19da4a4ada5 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/behavior.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/policy_forms/protections/behavior.tsx @@ -15,7 +15,7 @@ import { ConfigForm } from '../../components/config_form'; import { RadioButtons } from '../components/radio_buttons'; import { UserNotification } from '../components/user_notification'; import { ProtectionSwitch } from '../components/protection_switch'; -import { APP_ID } from '../../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../../common/constants'; import { LinkToApp } from '../../../../../../common/components/endpoint/link_to_app'; import { SecurityPageName } from '../../../../../../app/types'; @@ -51,7 +51,7 @@ export const BehaviorProtection = React.memo(() => { defaultMessage="View {detectionRulesLink}. Prebuilt rules are tagged “Elastic” on the Detection Rules page." values={{ detectionRulesLink: ( - + { defaultMessage="View {detectionRulesLink}. Prebuilt rules are tagged “Elastic” on the Detection Rules page." values={{ detectionRulesLink: ( - + { defaultMessage="View {detectionRulesLink}. Prebuilt rules are tagged “Elastic” on the Detection Rules page." values={{ detectionRulesLink: ( - + { defaultMessage="View {detectionRulesLink}. Prebuilt rules are tagged “Elastic” on the Detection Rules page." values={{ detectionRulesLink: ( - + { const { getAppUrl } = useAppUrl(); @@ -35,19 +35,19 @@ export const useGetLinkTo = (policyId: string, policyName: string) => { } ), onBackButtonNavigateTo: [ - APP_ID, + APP_UI_ID, { path: policyTrustedAppsPath, }, ], backButtonUrl: getAppUrl({ - appId: APP_ID, + appId: APP_UI_ID, path: policyTrustedAppsPath, }), }; }, [getAppUrl, policyName, policyTrustedAppsPath]); - const onClickHandler = useNavigateToAppEventHandler(APP_ID, { + const onClickHandler = useNavigateToAppEventHandler(APP_UI_ID, { state: policyTrustedAppRouteState, path: toRoutePath, }); diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.test.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.test.tsx index 9165aec3bef8d4..b136eef9566eb2 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.test.tsx @@ -20,7 +20,7 @@ import { isLoadedResourceState, } from '../../../../../state'; import { fireEvent, within, act, waitFor } from '@testing-library/react'; -import { APP_ID } from '../../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../../common/constants'; import { EndpointPrivileges, useEndpointPrivileges, @@ -203,7 +203,7 @@ describe('when rendering the PolicyTrustedAppsList', () => { }); expect(appTestContext.coreStart.application.navigateToApp).toHaveBeenCalledWith( - APP_ID, + APP_UI_ID, expect.objectContaining({ path: '/administration/trusted_apps?filter=89f72d8a-05b5-4350-8cad-0dc3661d6e67', }) diff --git a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx index 89ff6bd099be4c..48f66806b46b49 100644 --- a/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/policy/view/trusted_apps/list/policy_trusted_apps_list.tsx @@ -33,7 +33,7 @@ import { } from '../../../../../common/routing'; import { Immutable, TrustedApp } from '../../../../../../../common/endpoint/types'; import { useAppUrl, useToasts } from '../../../../../../common/lib/kibana'; -import { APP_ID } from '../../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../../common/constants'; import { ContextMenuItemNavByRouterProps } from '../../../../../components/context_menu_with_router_support/context_menu_item_nav_by_router'; import { ArtifactEntryCollapsibleCardProps } from '../../../../../components/artifact_entry_card'; import { useTestIdGenerator } from '../../../../../components/hooks/use_test_id_generator'; @@ -130,7 +130,7 @@ export const PolicyTrustedAppsList = memo( const policyDetailsPath = getPolicyDetailPath(trustedAppAssignedPolicyId); const thisPolicyMenuProps: ContextMenuItemNavByRouterProps = { - navigateAppId: APP_ID, + navigateAppId: APP_UI_ID, navigateOptions: { path: policyDetailsPath, }, @@ -150,8 +150,8 @@ export const PolicyTrustedAppsList = memo( 'xpack.securitySolution.endpoint.policy.trustedApps.list.viewAction', { defaultMessage: 'View full details' } ), - href: getAppUrl({ appId: APP_ID, path: viewUrlPath }), - navigateAppId: APP_ID, + href: getAppUrl({ appId: APP_UI_ID, path: viewUrlPath }), + navigateAppId: APP_UI_ID, navigateOptions: { path: viewUrlPath }, 'data-test-subj': getTestId('viewFullDetailsAction'), }, diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx index dd9a15eb3266a6..72b52b0f352781 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/trusted_apps_grid/index.tsx @@ -37,7 +37,7 @@ import { ArtifactEntryCardProps, } from '../../../../../components/artifact_entry_card'; import { AppAction } from '../../../../../../common/store/actions'; -import { APP_ID } from '../../../../../../../common/constants'; +import { APP_UI_ID } from '../../../../../../../common/constants'; import { useAppUrl } from '../../../../../../common/lib/kibana'; export interface PaginationBarProps { @@ -115,7 +115,7 @@ export const TrustedAppsGrid = memo(() => { backLink: { label: BACK_TO_TRUSTED_APPS_LABEL, navigateTo: [ - APP_ID, + APP_UI_ID, { path: currentPagePath, }, @@ -123,7 +123,7 @@ export const TrustedAppsGrid = memo(() => { href: getAppUrl({ path: currentPagePath }), }, onCancelNavigateTo: [ - APP_ID, + APP_UI_ID, { path: currentPagePath, }, @@ -131,6 +131,7 @@ export const TrustedAppsGrid = memo(() => { }; policyToNavOptionsMap[policyId] = { + navigateAppId: APP_UI_ID, navigateOptions: { path: policyDetailsPath, state: routeState, diff --git a/x-pack/plugins/security_solution/public/network/pages/details/utils.ts b/x-pack/plugins/security_solution/public/network/pages/details/utils.ts index 637180203c6d1d..7bcf79ba4b4348 100644 --- a/x-pack/plugins/security_solution/public/network/pages/details/utils.ts +++ b/x-pack/plugins/security_solution/public/network/pages/details/utils.ts @@ -15,7 +15,7 @@ import * as i18n from '../translations'; import { NetworkRouteType } from '../navigation/types'; import { NetworkRouteSpyState } from '../../../common/utils/route/types'; import { GetUrlForApp } from '../../../common/components/navigation/types'; -import { APP_ID } from '../../../../common/constants'; +import { APP_UI_ID } from '../../../../common/constants'; import { SecurityPageName } from '../../../app/types'; export const type = networkModel.NetworkType.details; @@ -36,7 +36,7 @@ export const getBreadcrumbs = ( let breadcrumb = [ { text: i18n.PAGE_TITLE, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.network, path: !isEmpty(search[0]) ? search[0] : '', }), @@ -47,7 +47,7 @@ export const getBreadcrumbs = ( ...breadcrumb, { text: decodeIpv6(params.detailName), - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.network, path: getNetworkDetailsUrl( params.detailName, diff --git a/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.tsx b/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.tsx index 11270fe377733e..e74e8f82d82442 100644 --- a/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/alerts_by_category/index.tsx @@ -9,7 +9,7 @@ import numeral from '@elastic/numeral'; import React, { useEffect, useMemo, useCallback } from 'react'; import { Position } from '@elastic/charts'; -import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../common/constants'; +import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants'; import { SHOWING, UNIT } from '../../../common/components/alerts_viewer/translations'; import { MatrixHistogram } from '../../../common/components/matrix_histogram'; import { useKibana, useUiSetting$ } from '../../../common/lib/kibana'; @@ -68,7 +68,7 @@ const AlertsByCategoryComponent: React.FC = ({ const goToHostAlerts = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, path: getTabsOnHostsUrl(HostsTableType.alerts, urlSearch), }); diff --git a/x-pack/plugins/security_solution/public/overview/components/endpoint_notice/index.tsx b/x-pack/plugins/security_solution/public/overview/components/endpoint_notice/index.tsx index 715663b60c7dcf..39193742021f15 100644 --- a/x-pack/plugins/security_solution/public/overview/components/endpoint_notice/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/endpoint_notice/index.tsx @@ -9,15 +9,15 @@ import React, { memo } from 'react'; import { EuiCallOut, EuiButton, EuiButtonEmpty } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { useKibana } from '../../../common/lib/kibana'; -import { APP_ID } from '../../../../common/constants'; +import { APP_UI_ID } from '../../../../common/constants'; import { getEndpointListPath } from '../../../management/common/routing'; import { useNavigateToAppEventHandler } from '../../../common/hooks/endpoint/use_navigate_to_app_event_handler'; export const EndpointNotice = memo<{ onDismiss: () => void }>(({ onDismiss }) => { const { getUrlForApp } = useKibana().services.application; const endpointsPath = getEndpointListPath({ name: 'endpointList' }); - const endpointsLink = getUrlForApp(APP_ID, { path: endpointsPath }); - const handleGetStartedClick = useNavigateToAppEventHandler(APP_ID, { + const endpointsLink = getUrlForApp(APP_UI_ID, { path: endpointsPath }); + const handleGetStartedClick = useNavigateToAppEventHandler(APP_UI_ID, { path: endpointsPath, }); diff --git a/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx b/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx index 7de1d9d9f40c1f..562d1d1fd7aadb 100644 --- a/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/events_by_dataset/index.tsx @@ -10,7 +10,7 @@ import numeral from '@elastic/numeral'; import React, { useEffect, useMemo, useCallback } from 'react'; import uuid from 'uuid'; -import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../common/constants'; +import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants'; import { SHOWING, UNIT } from '../../../common/components/events_viewer/translations'; import { getTabsOnHostsUrl } from '../../../common/components/link_to/redirect_to_hosts'; import { MatrixHistogram } from '../../../common/components/matrix_histogram'; @@ -101,7 +101,7 @@ const EventsByDatasetComponent: React.FC = ({ const goToHostEvents = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, path: getTabsOnHostsUrl(HostsTableType.events, urlSearch), }); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.tsx index a0307380ce8025..723c768190cb5a 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_host/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_host/index.tsx @@ -11,7 +11,7 @@ import numeral from '@elastic/numeral'; import { FormattedMessage } from '@kbn/i18n/react'; import React, { useMemo, useCallback } from 'react'; -import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../common/constants'; +import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants'; import { ESQuery } from '../../../../common/typed_json'; import { ID as OverviewHostQueryId, useHostOverview } from '../../containers/overview_host'; import { HeaderSection } from '../../../common/components/header_section'; @@ -57,7 +57,7 @@ const OverviewHostComponent: React.FC = ({ const goToHost = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, path: getHostDetailsUrl('allHosts', urlSearch), }); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx index 08b2392f60488c..dfc144be8e5bb8 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.test.tsx @@ -138,7 +138,7 @@ describe('OverviewNetwork', () => { preventDefault: jest.fn(), }); - expect(mockNavigateToApp).toBeCalledWith('securitySolution', { + expect(mockNavigateToApp).toBeCalledWith('securitySolutionUI', { path: '', deepLinkId: SecurityPageName.network, }); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx index 214cd7b3f055b5..dd779f1656e92b 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_network/index.tsx @@ -11,7 +11,7 @@ import numeral from '@elastic/numeral'; import { FormattedMessage } from '@kbn/i18n/react'; import React, { useMemo, useCallback } from 'react'; -import { DEFAULT_NUMBER_FORMAT, APP_ID } from '../../../../common/constants'; +import { DEFAULT_NUMBER_FORMAT, APP_UI_ID } from '../../../../common/constants'; import { ESQuery } from '../../../../common/typed_json'; import { HeaderSection } from '../../../common/components/header_section'; import { useUiSetting$, useKibana } from '../../../common/lib/kibana'; @@ -59,7 +59,7 @@ const OverviewNetworkComponent: React.FC = ({ const goToNetwork = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.network, path: getNetworkUrl(urlSearch), }); diff --git a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/navigate_to_host.tsx b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/navigate_to_host.tsx index 4680aedc0ba600..2c8e281b376d65 100644 --- a/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/navigate_to_host.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/overview_risky_host_links/navigate_to_host.tsx @@ -7,7 +7,7 @@ import React, { useCallback } from 'react'; import { EuiButtonEmpty, EuiText } from '@elastic/eui'; -import { APP_ID, SecurityPageName } from '../../../../common/constants'; +import { APP_UI_ID, SecurityPageName } from '../../../../common/constants'; import { useKibana } from '../../../common/lib/kibana'; export const NavigateToHost: React.FC<{ name: string }> = ({ name }): JSX.Element => { @@ -27,7 +27,7 @@ export const NavigateToHost: React.FC<{ name: string }> = ({ name }): JSX.Elemen query: { match_phrase: { 'host.name': name } }, }, ]); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.hosts, }); }, diff --git a/x-pack/plugins/security_solution/public/overview/components/recent_cases/index.tsx b/x-pack/plugins/security_solution/public/overview/components/recent_cases/index.tsx index 207c6ef16bd160..e2d7d8264e9f95 100644 --- a/x-pack/plugins/security_solution/public/overview/components/recent_cases/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/recent_cases/index.tsx @@ -14,7 +14,7 @@ import { } from '../../../common/components/link_to/redirect_to_case'; import { useFormatUrl } from '../../../common/components/link_to'; import { useGetUserCasesPermissions, useKibana } from '../../../common/lib/kibana'; -import { APP_ID } from '../../../../common/constants'; +import { APP_ID, APP_UI_ID } from '../../../../common/constants'; import { SecurityPageName } from '../../../app/types'; import { AllCasesNavProps } from '../../../cases/components/all_cases'; @@ -33,7 +33,7 @@ const RecentCasesComponent = () => { href: formatUrl(getCaseUrl()), onClick: async (e) => { e?.preventDefault(); - return navigateToApp(APP_ID, { deepLinkId: SecurityPageName.case }); + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case }); }, }, caseDetailsNavigation: { @@ -42,7 +42,7 @@ const RecentCasesComponent = () => { }, onClick: async ({ detailName, subCaseId, search }, e) => { e?.preventDefault(); - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCaseDetailsUrl({ id: detailName, search, subCaseId }), }); @@ -52,7 +52,7 @@ const RecentCasesComponent = () => { href: formatUrl(getCreateCaseUrl()), onClick: async (e) => { e?.preventDefault(); - return navigateToApp(APP_ID, { + return navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCreateCaseUrl(), }); diff --git a/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx b/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx index dcd8783688ca7d..ed59918ad4499d 100644 --- a/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx +++ b/x-pack/plugins/security_solution/public/overview/components/recent_timelines/index.tsx @@ -25,7 +25,7 @@ import { LoadingPlaceholders } from '../loading_placeholders'; import { useTimelineStatus } from '../../../timelines/components/open_timeline/use_timeline_status'; import { useKibana } from '../../../common/lib/kibana'; import { SecurityPageName } from '../../../app/types'; -import { APP_ID } from '../../../../common/constants'; +import { APP_UI_ID } from '../../../../common/constants'; import { useFormatUrl } from '../../../common/components/link_to'; import { LinkAnchor } from '../../../common/components/links'; import { Direction } from '../../../../common/search_strategy'; @@ -61,7 +61,7 @@ const StatefulRecentTimelinesComponent: React.FC = ({ filterBy }) => { const goToTimelines = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.timelines, }); }, diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index f016c9712c6502..6167aa72a47b43 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -37,16 +37,16 @@ import { SOLUTION_NAME } from './common/translations'; import { APP_ID, - OVERVIEW_PATH, - APP_OVERVIEW_PATH, + APP_UI_ID, APP_PATH, DEFAULT_INDEX_KEY, APP_ICON_SOLUTION, DETECTION_ENGINE_INDEX_URL, + SERVER_APP_ID, } from '../common/constants'; -import { getDeepLinks, updateGlobalNavigation } from './app/deep_links'; -import { manageOldSiemRoutes } from './helpers'; +import { getDeepLinks } from './app/deep_links'; +import { getSubPluginRoutesByCapabilities, manageOldSiemRoutes } from './helpers'; import { IndexFieldsStrategyRequest, IndexFieldsStrategyResponse, @@ -98,7 +98,7 @@ export class Plugin implements IPlugin ({ + navLinkStatus: AppNavLinkStatus.hidden, // workaround to prevent main navLink to switch to visible after update. should not be needed + deepLinks: getDeepLinks( + this.experimentalFeatures, + undefined, + core.application.capabilities + ), + })); } return {}; @@ -313,9 +318,9 @@ export class Plugin implements IPlugin { wrapper.find(`[data-test-subj="attach-timeline-case-button"]`).first().simulate('click'); wrapper.find(`[data-test-subj="attach-timeline-existing-case"]`).first().simulate('click'); - expect(navigateToApp).toHaveBeenCalledWith('securitySolution', { + expect(navigateToApp).toHaveBeenCalledWith('securitySolutionUI', { path: '/create', deepLinkId: SecurityPageName.case, }); @@ -84,7 +84,7 @@ describe('AddToCaseButton', () => { wrapper.find(`[data-test-subj="attach-timeline-case-button"]`).first().simulate('click'); wrapper.find(`[data-test-subj="attach-timeline-existing-case"]`).first().simulate('click'); - expect(navigateToApp).toHaveBeenCalledWith('securitySolution', { + expect(navigateToApp).toHaveBeenCalledWith('securitySolutionUI', { path: '/case-id', deepLinkId: SecurityPageName.case, }); diff --git a/x-pack/plugins/security_solution/public/timelines/components/flyout/add_to_case_button/index.tsx b/x-pack/plugins/security_solution/public/timelines/components/flyout/add_to_case_button/index.tsx index 553b827f2a64c1..ff8746f4729d74 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/flyout/add_to_case_button/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/components/flyout/add_to_case_button/index.tsx @@ -11,7 +11,7 @@ import React, { useCallback, useMemo, useState } from 'react'; import { useDispatch } from 'react-redux'; import { Case, SubCase } from '../../../../../../cases/common'; -import { APP_ID } from '../../../../../common/constants'; +import { APP_ID, APP_UI_ID } from '../../../../../common/constants'; import { timelineSelectors } from '../../../../timelines/store/timeline'; import { setInsertTimeline, showTimeline } from '../../../store/timeline/actions'; import { useDeepEqualSelector } from '../../../../common/hooks/use_selector'; @@ -55,7 +55,7 @@ const AddToCaseButtonComponent: React.FC = ({ timelineId }) => { const onRowClick = useCallback( async (theCase?: Case | SubCase) => { openCaseModal(false); - await navigateToApp(APP_ID, { + await navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: theCase != null ? getCaseDetailsUrl({ id: theCase.id }) : getCreateCaseUrl(), }); @@ -90,7 +90,7 @@ const AddToCaseButtonComponent: React.FC = ({ timelineId }) => { const handleNewCaseClick = useCallback(() => { handlePopoverClose(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.case, path: getCreateCaseUrl(), }).then(() => { diff --git a/x-pack/plugins/security_solution/public/timelines/components/side_panel/host_details/__snapshots__/expandable_host.test.tsx.snap b/x-pack/plugins/security_solution/public/timelines/components/side_panel/host_details/__snapshots__/expandable_host.test.tsx.snap index 01ef89cd35c9f9..ad149cbcd63d0b 100644 --- a/x-pack/plugins/security_solution/public/timelines/components/side_panel/host_details/__snapshots__/expandable_host.test.tsx.snap +++ b/x-pack/plugins/security_solution/public/timelines/components/side_panel/host_details/__snapshots__/expandable_host.test.tsx.snap @@ -33,21 +33,6 @@ exports[`Expandable Host Component ExpandableHostDetails: rendering it should re opacity: 1; } -.c4 { - padding: 16px; - background: rgba(250,251,253,0.9); - bottom: 0; - left: 0; - position: absolute; - right: 0; - top: 0; - z-index: 1000; -} - -.c5 { - height: 100%; -} - .c2 dt { font-size: 12px !important; } @@ -75,6 +60,21 @@ exports[`Expandable Host Component ExpandableHostDetails: rendering it should re z-index: 2; } +.c4 { + padding: 16px; + background: rgba(250,251,253,0.9); + bottom: 0; + left: 0; + position: absolute; + right: 0; + top: 0; + z-index: 1000; +} + +.c5 { + height: 100%; +} + = ({ const goToRuleDetails = useCallback( (ev) => { ev.preventDefault(); - navigateToApp(APP_ID, { + navigateToApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId ?? '', search), }); @@ -83,7 +83,7 @@ export const RenderRuleName: React.FC = ({ const href = useMemo( () => - getUrlForApp(APP_ID, { + getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.rules, path: getRuleDetailsUrl(ruleId ?? '', search), }), diff --git a/x-pack/plugins/security_solution/public/timelines/pages/index.tsx b/x-pack/plugins/security_solution/public/timelines/pages/index.tsx index 2bf6e1259ff75e..58049ef164e15f 100644 --- a/x-pack/plugins/security_solution/public/timelines/pages/index.tsx +++ b/x-pack/plugins/security_solution/public/timelines/pages/index.tsx @@ -18,7 +18,7 @@ import { TimelinesPage } from './timelines_page'; import { PAGE_TITLE } from './translations'; import { appendSearch } from '../../common/components/link_to/helpers'; import { GetUrlForApp } from '../../common/components/navigation/types'; -import { APP_ID, TIMELINES_PATH } from '../../../common/constants'; +import { APP_UI_ID, TIMELINES_PATH } from '../../../common/constants'; import { SecurityPageName } from '../../app/types'; const timelinesPagePath = `${TIMELINES_PATH}/:tabName(${TimelineType.default}|${TimelineType.template})`; @@ -31,7 +31,7 @@ export const getBreadcrumbs = ( ): ChromeBreadcrumb[] => [ { text: PAGE_TITLE, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { deepLinkId: SecurityPageName.timelines, path: !isEmpty(search[0]) ? search[0] : '', }), diff --git a/x-pack/plugins/security_solution/public/types.ts b/x-pack/plugins/security_solution/public/types.ts index 61813d1a122b4e..376cfbf31afe28 100644 --- a/x-pack/plugins/security_solution/public/types.ts +++ b/x-pack/plugins/security_solution/public/types.ts @@ -87,11 +87,12 @@ export interface AppObservableLibs { export type InspectResponse = Inspect & { response: string[] }; +export const CASES_SUB_PLUGIN_KEY = 'cases'; export interface SubPlugins { alerts: Detections; rules: Rules; exceptions: Exceptions; - cases: Cases; + [CASES_SUB_PLUGIN_KEY]: Cases; hosts: Hosts; network: Network; ueba: Ueba; @@ -105,7 +106,7 @@ export interface StartedSubPlugins { alerts: ReturnType; rules: ReturnType; exceptions: ReturnType; - cases: ReturnType; + [CASES_SUB_PLUGIN_KEY]: ReturnType; hosts: ReturnType; network: ReturnType; ueba: ReturnType; diff --git a/x-pack/plugins/security_solution/public/ueba/pages/details/utils.ts b/x-pack/plugins/security_solution/public/ueba/pages/details/utils.ts index d5f346d3ece64d..8fcc0fce0b7a37 100644 --- a/x-pack/plugins/security_solution/public/ueba/pages/details/utils.ts +++ b/x-pack/plugins/security_solution/public/ueba/pages/details/utils.ts @@ -15,7 +15,7 @@ import { getUebaDetailsUrl } from '../../../common/components/link_to/redirect_t import * as i18n from '../translations'; import { UebaRouteSpyState } from '../../../common/utils/route/types'; import { GetUrlForApp } from '../../../common/components/navigation/types'; -import { APP_ID } from '../../../../common/constants'; +import { APP_UI_ID } from '../../../../common/constants'; import { SecurityPageName } from '../../../app/types'; export const type = uebaModel.UebaType.details; @@ -35,7 +35,7 @@ export const getBreadcrumbs = ( let breadcrumb = [ { text: i18n.PAGE_TITLE, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { path: !isEmpty(search[0]) ? search[0] : '', deepLinkId: SecurityPageName.ueba, }), @@ -47,7 +47,7 @@ export const getBreadcrumbs = ( ...breadcrumb, { text: params.detailName, - href: getUrlForApp(APP_ID, { + href: getUrlForApp(APP_UI_ID, { path: getUebaDetailsUrl(params.detailName, !isEmpty(search[0]) ? search[0] : ''), deepLinkId: SecurityPageName.ueba, }), From 6d6cb5c836270f8d1c19bc3e175ed80b4ae546d8 Mon Sep 17 00:00:00 2001 From: Chris Roberson Date: Mon, 25 Oct 2021 19:10:03 -0400 Subject: [PATCH 46/66] Remove ability to configure index (#114558) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../advanced/running-elasticsearch.asciidoc | 1 - docs/settings/task-manager-settings.asciidoc | 3 --- ...task-manager-production-considerations.asciidoc | 2 +- .../resources/base/bin/kibana-docker | 1 - x-pack/plugins/task_manager/server/config.test.ts | 14 -------------- x-pack/plugins/task_manager/server/config.ts | 9 --------- x-pack/plugins/task_manager/server/constants.ts | 7 +++++++ .../server/ephemeral_task_lifecycle.test.ts | 1 - x-pack/plugins/task_manager/server/index.test.ts | 11 ----------- .../managed_configuration.test.ts | 1 - .../monitoring/configuration_statistics.test.ts | 1 - .../monitoring/monitoring_stats_stream.test.ts | 1 - x-pack/plugins/task_manager/server/plugin.test.ts | 3 --- x-pack/plugins/task_manager/server/plugin.ts | 5 +++-- .../task_manager/server/saved_objects/index.ts | 5 +++-- 15 files changed, 14 insertions(+), 51 deletions(-) create mode 100644 x-pack/plugins/task_manager/server/constants.ts diff --git a/docs/developer/advanced/running-elasticsearch.asciidoc b/docs/developer/advanced/running-elasticsearch.asciidoc index 324d2af2ed3af5..36f9ee420d41db 100644 --- a/docs/developer/advanced/running-elasticsearch.asciidoc +++ b/docs/developer/advanced/running-elasticsearch.asciidoc @@ -76,7 +76,6 @@ If many other users will be interacting with your remote cluster, you'll want to [source,bash] ---- kibana.index: '.{YourGitHubHandle}-kibana' -xpack.task_manager.index: '.{YourGitHubHandle}-task-manager-kibana' ---- ==== Running remote clusters diff --git a/docs/settings/task-manager-settings.asciidoc b/docs/settings/task-manager-settings.asciidoc index ef45c262f897b7..c61ef839533471 100644 --- a/docs/settings/task-manager-settings.asciidoc +++ b/docs/settings/task-manager-settings.asciidoc @@ -22,9 +22,6 @@ Task Manager runs background tasks by polling for work on an interval. You can | `xpack.task_manager.request_capacity` | How many requests can Task Manager buffer before it rejects new requests. Defaults to 1000. -| `xpack.task_manager.index` - | The name of the index used to store task information. Defaults to `.kibana_task_manager`. - | `xpack.task_manager.max_workers` | The maximum number of tasks that this Kibana instance will run simultaneously. Defaults to 10. Starting in 8.0, it will not be possible to set the value greater than 100. diff --git a/docs/user/production-considerations/task-manager-production-considerations.asciidoc b/docs/user/production-considerations/task-manager-production-considerations.asciidoc index 0de32bf00948bc..672c310f138e98 100644 --- a/docs/user/production-considerations/task-manager-production-considerations.asciidoc +++ b/docs/user/production-considerations/task-manager-production-considerations.asciidoc @@ -12,7 +12,7 @@ This has three major benefits: [IMPORTANT] ============================================== -Task definitions for alerts and actions are stored in the index specified by <>. The default is `.kibana_task_manager`. +Task definitions for alerts and actions are stored in the index called `.kibana_task_manager`. You must have at least one replica of this index for production deployments. diff --git a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker index 3a38789fbcac65..ad66e1a16e04cc 100755 --- a/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker +++ b/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker @@ -365,7 +365,6 @@ kibana_vars=( xpack.securitySolution.prebuiltRulesFromFileSystem xpack.securitySolution.prebuiltRulesFromSavedObjects xpack.spaces.maxSpaces - xpack.task_manager.index xpack.task_manager.max_attempts xpack.task_manager.max_poll_inactivity_cycles xpack.task_manager.max_workers diff --git a/x-pack/plugins/task_manager/server/config.test.ts b/x-pack/plugins/task_manager/server/config.test.ts index 8d7a6c7872e7eb..4c4db2aba71285 100644 --- a/x-pack/plugins/task_manager/server/config.test.ts +++ b/x-pack/plugins/task_manager/server/config.test.ts @@ -16,7 +16,6 @@ describe('config validation', () => { "enabled": false, "request_capacity": 10, }, - "index": ".kibana_task_manager", "max_attempts": 3, "max_poll_inactivity_cycles": 10, "max_workers": 10, @@ -44,17 +43,6 @@ describe('config validation', () => { `); }); - test('the ElastiSearch Tasks index cannot be used for task manager', () => { - const config: Record = { - index: '.tasks', - }; - expect(() => { - configSchema.validate(config); - }).toThrowErrorMatchingInlineSnapshot( - `"[index]: \\".tasks\\" is an invalid Kibana Task Manager index, as it is already in use by the ElasticSearch Tasks Manager"` - ); - }); - test('the required freshness of the monitored stats config must always be less-than-equal to the poll interval', () => { const config: Record = { monitored_stats_required_freshness: 100, @@ -74,7 +62,6 @@ describe('config validation', () => { "enabled": false, "request_capacity": 10, }, - "index": ".kibana_task_manager", "max_attempts": 3, "max_poll_inactivity_cycles": 10, "max_workers": 10, @@ -119,7 +106,6 @@ describe('config validation', () => { "enabled": false, "request_capacity": 10, }, - "index": ".kibana_task_manager", "max_attempts": 3, "max_poll_inactivity_cycles": 10, "max_workers": 10, diff --git a/x-pack/plugins/task_manager/server/config.ts b/x-pack/plugins/task_manager/server/config.ts index f2026ecac3adc0..5a58e45a70d96d 100644 --- a/x-pack/plugins/task_manager/server/config.ts +++ b/x-pack/plugins/task_manager/server/config.ts @@ -64,15 +64,6 @@ export const configSchema = schema.object( defaultValue: 1000, min: 1, }), - /* The name of the index used to store task information. */ - index: schema.string({ - defaultValue: '.kibana_task_manager', - validate: (val) => { - if (val.toLowerCase() === '.tasks') { - return `"${val}" is an invalid Kibana Task Manager index, as it is already in use by the ElasticSearch Tasks Manager`; - } - }, - }), /* The maximum number of tasks that this Kibana instance will run simultaneously. */ max_workers: schema.number({ defaultValue: DEFAULT_MAX_WORKERS, diff --git a/x-pack/plugins/task_manager/server/constants.ts b/x-pack/plugins/task_manager/server/constants.ts new file mode 100644 index 00000000000000..e843a0b4815d17 --- /dev/null +++ b/x-pack/plugins/task_manager/server/constants.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ +export const TASK_MANAGER_INDEX = '.kibana_task_manager'; diff --git a/x-pack/plugins/task_manager/server/ephemeral_task_lifecycle.test.ts b/x-pack/plugins/task_manager/server/ephemeral_task_lifecycle.test.ts index ec6f25b7f1b61a..639bb834eeb4c7 100644 --- a/x-pack/plugins/task_manager/server/ephemeral_task_lifecycle.test.ts +++ b/x-pack/plugins/task_manager/server/ephemeral_task_lifecycle.test.ts @@ -43,7 +43,6 @@ describe('EphemeralTaskLifecycle', () => { executionContext, config: { max_workers: 10, - index: 'foo', max_attempts: 9, poll_interval: 6000000, version_conflict_threshold: 80, diff --git a/x-pack/plugins/task_manager/server/index.test.ts b/x-pack/plugins/task_manager/server/index.test.ts index ad2d598fe1082e..6fb512bebbd855 100644 --- a/x-pack/plugins/task_manager/server/index.test.ts +++ b/x-pack/plugins/task_manager/server/index.test.ts @@ -37,17 +37,6 @@ const applyTaskManagerDeprecations = (settings: Record = {}) => }; describe('deprecations', () => { - ['.foo', '.kibana_task_manager'].forEach((index) => { - it('logs a warning if index is set', () => { - const { messages } = applyTaskManagerDeprecations({ index }); - expect(messages).toMatchInlineSnapshot(` - Array [ - "\\"xpack.task_manager.index\\" is deprecated. Multitenancy by changing \\"kibana.index\\" will not be supported starting in 8.0. See https://ela.st/kbn-remove-legacy-multitenancy for more details", - ] - `); - }); - }); - it('logs a warning if max_workers is over limit', () => { const { messages } = applyTaskManagerDeprecations({ max_workers: 1000 }); expect(messages).toMatchInlineSnapshot(` diff --git a/x-pack/plugins/task_manager/server/integration_tests/managed_configuration.test.ts b/x-pack/plugins/task_manager/server/integration_tests/managed_configuration.test.ts index c9cc5be2d5cd63..271d24d73357b0 100644 --- a/x-pack/plugins/task_manager/server/integration_tests/managed_configuration.test.ts +++ b/x-pack/plugins/task_manager/server/integration_tests/managed_configuration.test.ts @@ -30,7 +30,6 @@ describe('managed configuration', () => { const context = coreMock.createPluginInitializerContext({ max_workers: 10, - index: 'foo', max_attempts: 9, poll_interval: 3000, version_conflict_threshold: 80, diff --git a/x-pack/plugins/task_manager/server/monitoring/configuration_statistics.test.ts b/x-pack/plugins/task_manager/server/monitoring/configuration_statistics.test.ts index bbd5bc217ae3b8..77fd9a8f11fabe 100644 --- a/x-pack/plugins/task_manager/server/monitoring/configuration_statistics.test.ts +++ b/x-pack/plugins/task_manager/server/monitoring/configuration_statistics.test.ts @@ -14,7 +14,6 @@ describe('Configuration Statistics Aggregator', () => { test('merges the static config with the merged configs', async () => { const configuration: TaskManagerConfig = { max_workers: 10, - index: 'foo', max_attempts: 9, poll_interval: 6000000, version_conflict_threshold: 80, diff --git a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts index e29dbc978c64aa..8aa2d54d896238 100644 --- a/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts +++ b/x-pack/plugins/task_manager/server/monitoring/monitoring_stats_stream.test.ts @@ -18,7 +18,6 @@ beforeEach(() => { describe('createMonitoringStatsStream', () => { const configuration: TaskManagerConfig = { max_workers: 10, - index: 'foo', max_attempts: 9, poll_interval: 6000000, version_conflict_threshold: 80, diff --git a/x-pack/plugins/task_manager/server/plugin.test.ts b/x-pack/plugins/task_manager/server/plugin.test.ts index c2345d7bf81930..20e5f211a5b4ed 100644 --- a/x-pack/plugins/task_manager/server/plugin.test.ts +++ b/x-pack/plugins/task_manager/server/plugin.test.ts @@ -17,7 +17,6 @@ describe('TaskManagerPlugin', () => { test('throws if no valid UUID is available', async () => { const pluginInitializerContext = coreMock.createPluginInitializerContext({ max_workers: 10, - index: 'foo', max_attempts: 9, poll_interval: 3000, version_conflict_threshold: 80, @@ -59,7 +58,6 @@ describe('TaskManagerPlugin', () => { test('throws if setup methods are called after start', async () => { const pluginInitializerContext = coreMock.createPluginInitializerContext({ max_workers: 10, - index: 'foo', max_attempts: 9, poll_interval: 3000, version_conflict_threshold: 80, @@ -130,7 +128,6 @@ describe('TaskManagerPlugin', () => { test('it logs a warning when the unsafe `exclude_task_types` config is used', async () => { const pluginInitializerContext = coreMock.createPluginInitializerContext({ max_workers: 10, - index: 'foo', max_attempts: 9, poll_interval: 3000, version_conflict_threshold: 80, diff --git a/x-pack/plugins/task_manager/server/plugin.ts b/x-pack/plugins/task_manager/server/plugin.ts index 4c812c82b2cae0..9a43cd5b8c1d6c 100644 --- a/x-pack/plugins/task_manager/server/plugin.ts +++ b/x-pack/plugins/task_manager/server/plugin.ts @@ -31,6 +31,7 @@ import { createMonitoringStats, MonitoringStats } from './monitoring'; import { EphemeralTaskLifecycle } from './ephemeral_task_lifecycle'; import { EphemeralTask } from './task'; import { registerTaskManagerUsageCollector } from './usage'; +import { TASK_MANAGER_INDEX } from './constants'; export interface TaskManagerSetupContract { /** @@ -135,7 +136,7 @@ export class TaskManagerPlugin } return { - index: this.config.index, + index: TASK_MANAGER_INDEX, addMiddleware: (middleware: Middleware) => { this.assertStillInSetup('add Middleware'); this.middleware = addMiddlewareToChain(this.middleware, middleware); @@ -159,7 +160,7 @@ export class TaskManagerPlugin serializer, savedObjectsRepository, esClient: elasticsearch.createClient('taskManager').asInternalUser, - index: this.config!.index, + index: TASK_MANAGER_INDEX, definitions: this.definitions, taskManagerId: `kibana:${this.taskManagerId!}`, }); diff --git a/x-pack/plugins/task_manager/server/saved_objects/index.ts b/x-pack/plugins/task_manager/server/saved_objects/index.ts index abbd1af73b55a6..bb8b247af87b83 100644 --- a/x-pack/plugins/task_manager/server/saved_objects/index.ts +++ b/x-pack/plugins/task_manager/server/saved_objects/index.ts @@ -11,6 +11,7 @@ import mappings from './mappings.json'; import { getMigrations } from './migrations'; import { TaskManagerConfig } from '../config.js'; import { getOldestIdleActionTask } from '../queries/oldest_idle_action_task'; +import { TASK_MANAGER_INDEX } from '../constants'; export function setupSavedObjects( savedObjects: SavedObjectsServiceSetup, @@ -23,11 +24,11 @@ export function setupSavedObjects( convertToAliasScript: `ctx._id = ctx._source.type + ':' + ctx._id; ctx._source.remove("kibana")`, mappings: mappings.task as SavedObjectsTypeMappingDefinition, migrations: getMigrations(), - indexPattern: config.index, + indexPattern: TASK_MANAGER_INDEX, excludeOnUpgrade: async ({ readonlyEsClient }) => { const oldestNeededActionParams = await getOldestIdleActionTask( readonlyEsClient, - config.index + TASK_MANAGER_INDEX ); // Delete all action tasks that have failed and are no longer needed From edc43c0ff2b1684ac821159f3f455ff618b4ee4c Mon Sep 17 00:00:00 2001 From: Corey Robertson Date: Mon, 25 Oct 2021 19:21:02 -0400 Subject: [PATCH 47/66] [Dashboard] Make Dashboard Saved Objects multiple-isolated (#115817) * Make Dashboard SO multiple-isolated * Fix integration tests * Fix Saved Objects API Integration Tests * Fix more tests * Fix even more tests Co-authored-by: Joe Portner <5295965+jportner@users.noreply.github.com> Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../server/saved_objects/dashboard.ts | 3 +- .../apis/saved_objects_management/find.ts | 2 +- .../saved_objects_management/relationships.ts | 2 +- .../saved_objects/spaces/data.json | 9 ++-- .../common/suites/import.ts | 2 +- .../security_and_spaces/apis/import.ts | 7 +-- .../saved_objects/spaces/data.json | 35 ++++++-------- .../spaces_test_plugin/server/plugin.ts | 17 +++++++ .../common/suites/copy_to_space.ts | 35 +++++++++----- .../common/suites/delete.ts | 8 ++-- .../common/suites/get_shareable_references.ts | 2 +- .../suites/resolve_copy_to_space_conflicts.ts | 46 +++++++++++++++---- 12 files changed, 107 insertions(+), 61 deletions(-) diff --git a/src/plugins/dashboard/server/saved_objects/dashboard.ts b/src/plugins/dashboard/server/saved_objects/dashboard.ts index 068883c429e616..944ceda3b33b3f 100644 --- a/src/plugins/dashboard/server/saved_objects/dashboard.ts +++ b/src/plugins/dashboard/server/saved_objects/dashboard.ts @@ -19,7 +19,8 @@ export const createDashboardSavedObjectType = ({ }): SavedObjectsType => ({ name: 'dashboard', hidden: false, - namespaceType: 'single', + namespaceType: 'multiple-isolated', + convertToMultiNamespaceTypeVersion: '8.0.0', management: { icon: 'dashboardApp', defaultSearchField: 'title', diff --git a/test/api_integration/apis/saved_objects_management/find.ts b/test/api_integration/apis/saved_objects_management/find.ts index ea7f297dfeb084..d877a62eedc823 100644 --- a/test/api_integration/apis/saved_objects_management/find.ts +++ b/test/api_integration/apis/saved_objects_management/find.ts @@ -202,7 +202,7 @@ export default function ({ getService }: FtrProviderContext) { path: '/app/dashboards#/view/b70c7ae0-3224-11e8-a572-ffca06da1357', uiCapabilitiesPath: 'dashboard.show', }, - namespaceType: 'single', + namespaceType: 'multiple-isolated', }); })); diff --git a/test/api_integration/apis/saved_objects_management/relationships.ts b/test/api_integration/apis/saved_objects_management/relationships.ts index 838bc05346dda6..cc14ce0c760680 100644 --- a/test/api_integration/apis/saved_objects_management/relationships.ts +++ b/test/api_integration/apis/saved_objects_management/relationships.ts @@ -301,7 +301,7 @@ export default function ({ getService }: FtrProviderContext) { path: '/app/dashboards#/view/b70c7ae0-3224-11e8-a572-ffca06da1357', uiCapabilitiesPath: 'dashboard.show', }, - namespaceType: 'single', + namespaceType: 'multiple-isolated', hiddenType: false, }, }, diff --git a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json index d83c550c15ff60..56785f913262ac 100644 --- a/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json +++ b/x-pack/test/saved_object_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json @@ -134,6 +134,7 @@ "uiStateJSON": "{}", "version": 1 }, + "namespaces": ["default"], "type": "dashboard", "updated_at": "2017-09-21T18:57:40.826Z" }, @@ -205,7 +206,7 @@ { "type": "doc", "value": { - "id": "space_1:dashboard:space1-dashboard-id", + "id": "dashboard:space1-dashboard-id", "index": ".kibana", "source": { "dashboard": { @@ -228,7 +229,7 @@ "uiStateJSON": "{}", "version": 1 }, - "namespace": "space_1", + "namespaces": ["space_1"], "type": "dashboard", "updated_at": "2017-09-21T18:57:40.826Z" }, @@ -300,7 +301,7 @@ { "type": "doc", "value": { - "id": "space_2:dashboard:space2-dashboard-id", + "id": "dashboard:space2-dashboard-id", "index": ".kibana", "source": { "dashboard": { @@ -323,7 +324,7 @@ "uiStateJSON": "{}", "version": 1 }, - "namespace": "space_2", + "namespaces": ["space_2"], "type": "dashboard", "updated_at": "2017-09-21T18:57:40.826Z" }, diff --git a/x-pack/test/saved_object_api_integration/common/suites/import.ts b/x-pack/test/saved_object_api_integration/common/suites/import.ts index 4e1b783d698417..69b3b9925c6517 100644 --- a/x-pack/test/saved_object_api_integration/common/suites/import.ts +++ b/x-pack/test/saved_object_api_integration/common/suites/import.ts @@ -52,7 +52,7 @@ export const TEST_CASES: Record = Object.freeze({ expectedNewId: `${CID}3`, }), CONFLICT_4_OBJ: Object.freeze({ type: 'sharedtype', id: `${CID}4`, expectedNewId: `${CID}4a` }), - NEW_SINGLE_NAMESPACE_OBJ: Object.freeze({ type: 'dashboard', id: 'new-dashboard-id' }), + NEW_SINGLE_NAMESPACE_OBJ: Object.freeze({ type: 'isolatedtype', id: 'new-isolatedtype-id' }), NEW_MULTI_NAMESPACE_OBJ: Object.freeze({ type: 'sharedtype', id: 'new-sharedtype-id' }), NEW_NAMESPACE_AGNOSTIC_OBJ: Object.freeze({ type: 'globaltype', id: 'new-globaltype-id' }), }); diff --git a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/import.ts b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/import.ts index 42464af05a0b71..1992dd6fea2248 100644 --- a/x-pack/test/saved_object_api_integration/security_and_spaces/apis/import.ts +++ b/x-pack/test/saved_object_api_integration/security_and_spaces/apis/import.ts @@ -130,7 +130,6 @@ export default function ({ getService }: FtrProviderContext) { spaceId, singleRequest, responseBodyOverride: expectSavedObjectForbidden([ - 'dashboard', 'globaltype', 'isolatedtype', 'sharedtype', @@ -152,11 +151,7 @@ export default function ({ getService }: FtrProviderContext) { overwrite, spaceId, singleRequest, - responseBodyOverride: expectSavedObjectForbidden([ - 'dashboard', - 'globaltype', - 'isolatedtype', - ]), + responseBodyOverride: expectSavedObjectForbidden(['globaltype', 'isolatedtype']), }), createTestDefinitions(group2, true, { overwrite, spaceId, singleRequest }), createTestDefinitions(group3, true, { overwrite, spaceId, singleRequest }), diff --git a/x-pack/test/spaces_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json b/x-pack/test/spaces_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json index c1525409cfa3fc..c9b09456a9a492 100644 --- a/x-pack/test/spaces_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json +++ b/x-pack/test/spaces_api_integration/common/fixtures/es_archiver/saved_objects/spaces/data.json @@ -56,15 +56,11 @@ { "type": "_doc", "value": { - "id": "space_2:dashboard:my_dashboard", + "id": "isolatedtype:my_isolated_object", "index": ".kibana", "source": { - "dashboard": { - "description": "Space 2", - "title": "This is the second test space" - }, "namespace": "space_2", - "type": "dashboard", + "type": "isolatedtype", "updated_at": "2017-09-21T18:49:16.270Z" }, "type": "_doc" @@ -74,15 +70,11 @@ { "type": "_doc", "value": { - "id": "space_1:dashboard:my_dashboard", + "id": "isolatedtype:my_isolated_object", "index": ".kibana", "source": { - "dashboard": { - "description": "Space 1", - "title": "This is the second test space" - }, "namespace": "space_1", - "type": "dashboard", + "type": "isolatedtype", "updated_at": "2017-09-21T18:49:16.270Z" }, "type": "_doc" @@ -92,14 +84,10 @@ { "type": "_doc", "value": { - "id": "dashboard:my_dashboard", + "id": "isolatedtype:my_isolated_object", "index": ".kibana", "source": { - "dashboard": { - "description": "Default Space", - "title": "This is the default test space" - }, - "type": "dashboard", + "type": "isolatedtype", "updated_at": "2017-09-21T18:49:16.270Z" }, "type": "_doc" @@ -109,9 +97,10 @@ { "type": "_doc", "value": { - "id": "dashboard:cts_dashboard", + "id": "dashboard:cts_dashboard_default", "index": ".kibana", "source": { + "originId": "cts_dashboard", "dashboard": { "description": "Copy to Space Dashboard from the default space", "title": "This is the default test space CTS dashboard" @@ -130,7 +119,8 @@ "name": "CTS Vis 3" }], "type": "dashboard", - "updated_at": "2017-09-21T18:49:16.270Z" + "updated_at": "2017-09-21T18:49:16.270Z", + "namespaces": ["default"] }, "type": "_doc" } @@ -227,9 +217,10 @@ { "type": "_doc", "value": { - "id": "space_1:dashboard:cts_dashboard", + "id": "dashboard:cts_dashboard_space_1", "index": ".kibana", "source": { + "originId": "cts_dashboard", "dashboard": { "description": "Copy to Space Dashboard from space_1 space", "title": "This is the space_1 test space CTS dashboard" @@ -253,7 +244,7 @@ ], "type": "dashboard", "updated_at": "2017-09-21T18:49:16.270Z", - "namespace": "space_1" + "namespaces": ["space_1"] }, "type": "_doc" } diff --git a/x-pack/test/spaces_api_integration/common/fixtures/spaces_test_plugin/server/plugin.ts b/x-pack/test/spaces_api_integration/common/fixtures/spaces_test_plugin/server/plugin.ts index a0021e9eedb5e3..88c168b6f62979 100644 --- a/x-pack/test/spaces_api_integration/common/fixtures/spaces_test_plugin/server/plugin.ts +++ b/x-pack/test/spaces_api_integration/common/fixtures/spaces_test_plugin/server/plugin.ts @@ -29,6 +29,23 @@ export class Plugin { }, }, }); + core.savedObjects.registerType({ + name: 'isolatedtype', + hidden: false, + namespaceType: 'single', + management: { + icon: 'beaker', + importableAndExportable: true, + getTitle(obj) { + return obj.attributes.title; + }, + }, + mappings: { + properties: { + title: { type: 'text' }, + }, + }, + }); } public start() { diff --git a/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts b/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts index 23136838f3002e..644200a0636ec5 100644 --- a/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts +++ b/x-pack/test/spaces_api_integration/common/suites/copy_to_space.ts @@ -64,9 +64,8 @@ interface SpaceBucket { } const INITIAL_COUNTS: Record> = { - [DEFAULT_SPACE_ID]: { dashboard: 2, visualization: 3, 'index-pattern': 1 }, - space_1: { dashboard: 2, visualization: 3, 'index-pattern': 1 }, - space_2: { dashboard: 1 }, + [DEFAULT_SPACE_ID]: { dashboard: 1, visualization: 3, 'index-pattern': 1 }, + space_1: { dashboard: 1, visualization: 3, 'index-pattern': 1 }, }; const UUID_PATTERN = new RegExp( /^[0-9A-F]{8}-[0-9A-F]{4}-4[0-9A-F]{3}-[89AB][0-9A-F]{3}-[0-9A-F]{12}$/i @@ -148,18 +147,23 @@ export function copyToSpaceTestSuiteFactory( (spaceId: string, destination: string, expectedDashboardCount: number) => async (resp: TestResponse) => { const result = resp.body as CopyResponse; + + const dashboardDestinationId = result[destination].successResults![0].destinationId; + expect(dashboardDestinationId).to.match(UUID_PATTERN); // this was copied to space 2 and hit an unresolvable conflict, so the object ID was regenerated silently / the destinationId is a UUID + expect(result).to.eql({ [destination]: { success: true, successCount: 1, successResults: [ { - id: 'cts_dashboard', + id: `cts_dashboard_${spaceId}`, type: 'dashboard', meta: { title: `This is the ${spaceId} test space CTS dashboard`, icon: 'dashboardApp', }, + destinationId: dashboardDestinationId, }, ], }, @@ -172,7 +176,7 @@ export function copyToSpaceTestSuiteFactory( }; const expectNoConflictsWithoutReferencesResult = (spaceId: string = DEFAULT_SPACE_ID) => - createExpectNoConflictsWithoutReferencesForSpace(spaceId, getDestinationWithoutConflicts(), 2); + createExpectNoConflictsWithoutReferencesForSpace(spaceId, getDestinationWithoutConflicts(), 1); const expectNoConflictsForNonExistentSpaceResult = (spaceId: string = DEFAULT_SPACE_ID) => createExpectNoConflictsWithoutReferencesForSpace(spaceId, 'non_existent_space', 1); @@ -191,6 +195,8 @@ export function copyToSpaceTestSuiteFactory( expect(vis2DestinationId).to.match(UUID_PATTERN); // this was copied to space 2 and hit an unresolvable conflict, so the object ID was regenerated silently / the destinationId is a UUID const vis3DestinationId = result[destination].successResults![3].destinationId; expect(vis3DestinationId).to.match(UUID_PATTERN); // this was copied to space 2 and hit an unresolvable conflict, so the object ID was regenerated silently / the destinationId is a UUID + const dashboardDestinationId = result[destination].successResults![4].destinationId; + expect(dashboardDestinationId).to.match(UUID_PATTERN); // this was copied to space 2 and hit an unresolvable conflict, so the object ID was regenerated silently / the destinationId is a UUID expect(result).to.eql({ [destination]: { @@ -225,12 +231,13 @@ export function copyToSpaceTestSuiteFactory( destinationId: vis3DestinationId, }, { - id: 'cts_dashboard', + id: `cts_dashboard_${spaceId}`, type: 'dashboard', meta: { icon: 'dashboardApp', title: `This is the ${spaceId} test space CTS dashboard`, }, + destinationId: dashboardDestinationId, }, ], }, @@ -238,7 +245,7 @@ export function copyToSpaceTestSuiteFactory( // Query ES to ensure that we copied everything we expected await assertSpaceCounts(destination, { - dashboard: 2, + dashboard: 1, visualization: 3, 'index-pattern': 1, }); @@ -353,13 +360,14 @@ export function copyToSpaceTestSuiteFactory( destinationId: `cts_vis_3_${destination}`, // this conflicted with another visualization in the destination space because of a shared originId }, { - id: 'cts_dashboard', + id: `cts_dashboard_${spaceId}`, type: 'dashboard', meta: { icon: 'dashboardApp', title: `This is the ${spaceId} test space CTS dashboard`, }, overwrite: true, + destinationId: `cts_dashboard_${destination}`, // this conflicted with another dashboard in the destination space because of a shared originId }, ], }, @@ -367,7 +375,7 @@ export function copyToSpaceTestSuiteFactory( // Query ES to ensure that we copied everything we expected await assertSpaceCounts(destination, { - dashboard: 2, + dashboard: 1, visualization: 5, 'index-pattern': 1, }); @@ -403,8 +411,11 @@ export function copyToSpaceTestSuiteFactory( ]; const expectedErrors = [ { - error: { type: 'conflict' }, - id: 'cts_dashboard', + error: { + type: 'conflict', + destinationId: `cts_dashboard_${destination}`, // this conflicted with another dashboard in the destination space because of a shared originId + }, + id: `cts_dashboard_${spaceId}`, title: `This is the ${spaceId} test space CTS dashboard`, type: 'dashboard', meta: { @@ -662,7 +673,7 @@ export function copyToSpaceTestSuiteFactory( ) ); - const dashboardObject = { type: 'dashboard', id: 'cts_dashboard' }; + const dashboardObject = { type: 'dashboard', id: `cts_dashboard_${spaceId}` }; it(`should return ${tests.noConflictsWithoutReferences.statusCode} when copying to space without conflicts or references`, async () => { const destination = getDestinationWithoutConflicts(); diff --git a/x-pack/test/spaces_api_integration/common/suites/delete.ts b/x-pack/test/spaces_api_integration/common/suites/delete.ts index 4bf44d88db8e05..f6fe05682e2da2 100644 --- a/x-pack/test/spaces_api_integration/common/suites/delete.ts +++ b/x-pack/test/spaces_api_integration/common/suites/delete.ts @@ -65,28 +65,28 @@ export function deleteTestSuiteFactory( const expectedBuckets = [ { key: 'default', - doc_count: 8, + doc_count: 7, countByType: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'visualization', doc_count: 3 }, - { key: 'dashboard', doc_count: 2 }, { key: 'space', doc_count: 2 }, // since space objects are namespace-agnostic, they appear in the "default" agg bucket + { key: 'dashboard', doc_count: 1 }, { key: 'index-pattern', doc_count: 1 }, // legacy-url-alias objects cannot exist for the default space ], }, }, { - doc_count: 7, + doc_count: 6, key: 'space_1', countByType: { doc_count_error_upper_bound: 0, sum_other_doc_count: 0, buckets: [ { key: 'visualization', doc_count: 3 }, - { key: 'dashboard', doc_count: 2 }, + { key: 'dashboard', doc_count: 1 }, { key: 'index-pattern', doc_count: 1 }, { key: 'legacy-url-alias', doc_count: 1 }, // alias (1) ], diff --git a/x-pack/test/spaces_api_integration/common/suites/get_shareable_references.ts b/x-pack/test/spaces_api_integration/common/suites/get_shareable_references.ts index ed704a9a8bdcc5..883c1230f5d102 100644 --- a/x-pack/test/spaces_api_integration/common/suites/get_shareable_references.ts +++ b/x-pack/test/spaces_api_integration/common/suites/get_shareable_references.ts @@ -43,7 +43,7 @@ const { export const TEST_CASE_OBJECTS: Record = deepFreeze({ SHAREABLE_TYPE: { type: 'sharedtype', id: CASES.EACH_SPACE.id }, // contains references to four other objects SHAREABLE_TYPE_DOES_NOT_EXIST: { type: 'sharedtype', id: 'does-not-exist' }, - NON_SHAREABLE_TYPE: { type: 'dashboard', id: 'my_dashboard' }, // one of these exists in each space + NON_SHAREABLE_TYPE: { type: 'isolatedtype', id: 'my_isolated_object' }, // one of these exists in each space }); // Expected results for each space are defined here since they are used in multiple test suites export const EXPECTED_RESULTS: Record = { diff --git a/x-pack/test/spaces_api_integration/common/suites/resolve_copy_to_space_conflicts.ts b/x-pack/test/spaces_api_integration/common/suites/resolve_copy_to_space_conflicts.ts index 72130743b69d95..1d9d5325cbabf5 100644 --- a/x-pack/test/spaces_api_integration/common/suites/resolve_copy_to_space_conflicts.ts +++ b/x-pack/test/spaces_api_integration/common/suites/resolve_copy_to_space_conflicts.ts @@ -63,7 +63,7 @@ export function resolveCopyToSpaceConflictsSuite( }; const getDashboardAtSpace = async (spaceId: string): Promise> => { return supertestWithAuth - .get(`${getUrlPrefix(spaceId)}/api/saved_objects/dashboard/cts_dashboard`) + .get(`${getUrlPrefix(spaceId)}/api/saved_objects/dashboard/cts_dashboard_${spaceId}`) .then((response: any) => response.body); }; @@ -124,12 +124,13 @@ export function resolveCopyToSpaceConflictsSuite( successCount: 1, successResults: [ { - id: 'cts_dashboard', + id: `cts_dashboard_${sourceSpaceId}`, type: 'dashboard', meta: { title: `This is the ${sourceSpaceId} test space CTS dashboard`, icon: 'dashboardApp', }, + destinationId: `cts_dashboard_${destinationSpaceId}`, // this conflicted with another dashboard in the destination space because of a shared originId overwrite: true, }, ], @@ -204,8 +205,11 @@ export function resolveCopyToSpaceConflictsSuite( successCount: 0, errors: [ { - error: { type: 'conflict' }, - id: 'cts_dashboard', + error: { + type: 'conflict', + destinationId: `cts_dashboard_${destination}`, // this conflicted with another visualization in the destination space because of a shared originId + }, + id: `cts_dashboard_${sourceSpaceId}`, type: 'dashboard', title: `This is the ${sourceSpaceId} test space CTS dashboard`, meta: { @@ -442,7 +446,7 @@ export function resolveCopyToSpaceConflictsSuite( ) ); - const dashboardObject = { type: 'dashboard', id: 'cts_dashboard' }; + const dashboardObject = { type: 'dashboard', id: `cts_dashboard_${spaceId}` }; const visualizationObject = { type: 'visualization', id: `cts_vis_3_${spaceId}` }; const indexPatternObject = { type: 'index-pattern', id: `cts_ip_1_${spaceId}` }; @@ -514,7 +518,15 @@ export function resolveCopyToSpaceConflictsSuite( objects: [dashboardObject], includeReferences: false, createNewCopies: false, - retries: { [destination]: [{ ...dashboardObject, overwrite: true }] }, + retries: { + [destination]: [ + { + ...dashboardObject, + destinationId: `cts_dashboard_${destination}`, + overwrite: true, + }, + ], + }, }) .expect(tests.withoutReferencesOverwriting.statusCode) .then(tests.withoutReferencesOverwriting.response); @@ -530,7 +542,15 @@ export function resolveCopyToSpaceConflictsSuite( objects: [dashboardObject], includeReferences: false, createNewCopies: false, - retries: { [destination]: [{ ...dashboardObject, overwrite: false }] }, + retries: { + [destination]: [ + { + ...dashboardObject, + destinationId: `cts_dashboard_${destination}`, + overwrite: false, + }, + ], + }, }) .expect(tests.withoutReferencesNotOverwriting.statusCode) .then(tests.withoutReferencesNotOverwriting.response); @@ -546,7 +566,17 @@ export function resolveCopyToSpaceConflictsSuite( objects: [dashboardObject], includeReferences: false, createNewCopies: false, - retries: { [destination]: [{ ...dashboardObject, overwrite: true }] }, + retries: { + [destination]: [ + { + ...dashboardObject, + destinationId: `cts_dashboard_${destination}`, + // realistically a retry wouldn't use a destinationId, because it wouldn't have an origin conflict with another + // object in a non-existent space, but for the simplicity of testing we'll use this here + overwrite: true, + }, + ], + }, }) .expect(tests.nonExistentSpace.statusCode) .then(tests.nonExistentSpace.response); From de2ca1822665eeefa76c6fca2c98d1f9fd995e83 Mon Sep 17 00:00:00 2001 From: Chris Donaher Date: Mon, 25 Oct 2021 17:40:36 -0600 Subject: [PATCH 48/66] Insights telemetry collection -- Alert Status Updates (#115471) * Added security plugin to signals route * Added insights payload construction to status route * Pass cloud plugin setup to route to test if cloud is enabled * Incorrectly getting username from authenticated user * Test needs cloud setup passed to mock * Mistakenly added sender to migration * Just pass cloudEnabled boolean to route * Remove cloud specific checks from telemetry forwarding * Populate sessionId from request, hash+salt with clusterID * Converted payload construction to map * Added logger to route, found that ui sometimes passes alert_ids in query * Properly pass logger into test * Change deep nested query field access to lodash get * Fixed some import issues * Addressed some comments from @pjhamptom * Added fields to mock to ensure that the testTelemetrySender has the proper interface * Wrapped awaits in Promise.all, abstract and remove async fetchClusterInfo calls since clusterInfo is immutable * Missed some references to fetchClusterInfo() * Removed references to rules, changed 'page' to 'route', made insights functions not methods Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../routes/signals/open_close_signals.test.ts | 14 +++- .../signals/open_close_signals_route.ts | 41 +++++++++- .../server/lib/telemetry/__mocks__/index.ts | 3 +- .../server/lib/telemetry/constants.ts | 2 + .../server/lib/telemetry/insights/index.ts | 7 ++ .../server/lib/telemetry/insights/insights.ts | 82 +++++++++++++++++++ .../server/lib/telemetry/receiver.ts | 8 +- .../server/lib/telemetry/sender.ts | 18 ++-- .../security_solution/server/plugin.ts | 1 + .../security_solution/server/routes/index.ts | 4 +- 10 files changed, 166 insertions(+), 14 deletions(-) create mode 100644 x-pack/plugins/security_solution/server/lib/telemetry/insights/index.ts create mode 100644 x-pack/plugins/security_solution/server/lib/telemetry/insights/insights.ts diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts index 07c3bc37e7d721..39ccf9f158422f 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals.test.ts @@ -15,16 +15,21 @@ import { getSuccessfulSignalUpdateResponse, } from '../__mocks__/request_responses'; import { requestContextMock, serverMock, requestMock } from '../__mocks__'; +import { SetupPlugins } from '../../../../plugin'; +import { createMockTelemetryEventsSender } from '../../../telemetry/__mocks__'; import { setSignalsStatusRoute } from './open_close_signals_route'; // eslint-disable-next-line @kbn/eslint/no-restricted-paths import { elasticsearchClientMock } from 'src/core/server/elasticsearch/client/mocks'; +import { loggingSystemMock } from 'src/core/server/mocks'; describe('set signal status', () => { let server: ReturnType; let { context } = requestContextMock.createTools(); + let logger: ReturnType; beforeEach(() => { server = serverMock.create(); + logger = loggingSystemMock.createLogger(); ({ context } = requestContextMock.createTools()); context.core.elasticsearch.client.asCurrentUser.updateByQuery.mockResolvedValue( @@ -32,8 +37,13 @@ describe('set signal status', () => { getSuccessfulSignalUpdateResponse() ) ); - - setSignalsStatusRoute(server.router); + const telemetrySenderMock = createMockTelemetryEventsSender(); + const securityMock = { + authc: { + getCurrentUser: jest.fn().mockReturnValue({ user: { username: 'my-username' } }), + }, + } as unknown as SetupPlugins['security']; + setSignalsStatusRoute(server.router, logger, securityMock, telemetrySenderMock); }); describe('status on signal', () => { diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts index e54cc94b886f66..c29a9d9a5d7eb2 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/signals/open_close_signals_route.ts @@ -5,8 +5,10 @@ * 2.0. */ +import { get } from 'lodash'; import { transformError } from '@kbn/securitysolution-es-utils'; import { ALERT_WORKFLOW_STATUS } from '@kbn/rule-data-utils'; +import { Logger } from 'src/core/server'; import { setSignalStatusValidateTypeDependents } from '../../../../../common/detection_engine/schemas/request/set_signal_status_type_dependents'; import { SetSignalsStatusSchemaDecoded, @@ -15,10 +17,21 @@ import { import type { SecuritySolutionPluginRouter } from '../../../../types'; import { DETECTION_ENGINE_SIGNALS_STATUS_URL } from '../../../../../common/constants'; import { buildSiemResponse } from '../utils'; - +import { TelemetryEventsSender } from '../../../telemetry/sender'; +import { INSIGHTS_CHANNEL } from '../../../telemetry/constants'; +import { SetupPlugins } from '../../../../plugin'; import { buildRouteValidation } from '../../../../utils/build_validation/route_validation'; +import { + getSessionIDfromKibanaRequest, + createAlertStatusPayloads, +} from '../../../telemetry/insights'; -export const setSignalsStatusRoute = (router: SecuritySolutionPluginRouter) => { +export const setSignalsStatusRoute = ( + router: SecuritySolutionPluginRouter, + logger: Logger, + security: SetupPlugins['security'], + sender: TelemetryEventsSender +) => { router.post( { path: DETECTION_ENGINE_SIGNALS_STATUS_URL, @@ -46,6 +59,30 @@ export const setSignalsStatusRoute = (router: SecuritySolutionPluginRouter) => { return siemResponse.error({ statusCode: 404 }); } + const clusterId = sender.getClusterID(); + const [isTelemetryOptedIn, username] = await Promise.all([ + sender.isTelemetryOptedIn(), + security?.authc.getCurrentUser(request)?.username, + ]); + if (isTelemetryOptedIn && clusterId) { + // Sometimes the ids are in the query not passed in the request? + const toSendAlertIds = get(query, 'bool.filter.terms._id') || signalIds; + // Get Context for Insights Payloads + const sessionId = getSessionIDfromKibanaRequest(clusterId, request); + if (username && toSendAlertIds && sessionId && status) { + const insightsPayloads = createAlertStatusPayloads( + clusterId, + toSendAlertIds, + sessionId, + username, + DETECTION_ENGINE_SIGNALS_STATUS_URL, + status + ); + logger.debug(`Sending Insights Payloads ${JSON.stringify(insightsPayloads)}`); + await sender.sendOnDemand(INSIGHTS_CHANNEL, insightsPayloads); + } + } + let queryObject; if (signalIds) { queryObject = { ids: { values: signalIds } }; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts b/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts index 45ceb98ed0dc10..b6657e77533641 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/__mocks__/index.ts @@ -21,12 +21,14 @@ export const createMockTelemetryEventsSender = ( setup: jest.fn(), start: jest.fn(), stop: jest.fn(), + getClusterID: jest.fn(), fetchTelemetryUrl: jest.fn(), queueTelemetryEvents: jest.fn(), processEvents: jest.fn(), isTelemetryOptedIn: jest.fn().mockReturnValue(enableTelemetry ?? jest.fn()), sendIfDue: jest.fn(), sendEvents: jest.fn(), + sendOnDemand: jest.fn(), } as unknown as jest.Mocked; }; @@ -35,7 +37,6 @@ export const createMockTelemetryReceiver = ( ): jest.Mocked => { return { start: jest.fn(), - fetchClusterInfo: jest.fn(), fetchLicenseInfo: jest.fn(), copyLicenseFields: jest.fn(), fetchFleetAgents: jest.fn(), diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts b/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts index ec1505ec314d1d..af02c98f32c551 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/constants.ts @@ -24,3 +24,5 @@ export const LIST_ENDPOINT_EXCEPTION = 'endpoint_exception'; export const LIST_ENDPOINT_EVENT_FILTER = 'endpoint_event_filter'; export const LIST_TRUSTED_APPLICATION = 'trusted_application'; + +export const INSIGHTS_CHANNEL = 'security-insights-v1'; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/insights/index.ts b/x-pack/plugins/security_solution/server/lib/telemetry/insights/index.ts new file mode 100644 index 00000000000000..8f300c6089d296 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/telemetry/insights/index.ts @@ -0,0 +1,7 @@ +/* + * 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. + */ +export { getSessionIDfromKibanaRequest, createAlertStatusPayloads } from './insights'; diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/insights/insights.ts b/x-pack/plugins/security_solution/server/lib/telemetry/insights/insights.ts new file mode 100644 index 00000000000000..367eb928241175 --- /dev/null +++ b/x-pack/plugins/security_solution/server/lib/telemetry/insights/insights.ts @@ -0,0 +1,82 @@ +/* + * 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 moment from 'moment'; +import { KibanaRequest } from 'src/core/server'; +import { sha256 } from 'js-sha256'; + +interface AlertContext { + alert_id: string; +} + +interface AlertStatusAction { + alert_status: string; + action_timestamp: string; +} + +export interface InsightsPayload { + state: { + route: string; + cluster_id: string; + user_id: string; + session_id: string; + context: AlertContext; + }; + action: AlertStatusAction; +} +export function getSessionIDfromKibanaRequest(clusterId: string, request: KibanaRequest): string { + const rawCookieHeader = request.headers.cookie; + if (!rawCookieHeader) { + return ''; + } + const cookieHeaders = Array.isArray(rawCookieHeader) ? rawCookieHeader : [rawCookieHeader]; + let tokenPackage: string | undefined; + + cookieHeaders + .flatMap((rawHeader) => rawHeader.split('; ')) + .forEach((rawCookie) => { + const [cookieName, cookieValue] = rawCookie.split('='); + if (cookieName === 'sid') tokenPackage = cookieValue; + }); + + if (tokenPackage) { + return getClusterHashSalt(clusterId, tokenPackage); + } else { + return ''; + } +} + +function getClusterHashSalt(clusterId: string, toHash: string): string { + const concatValue = toHash + clusterId; + const sha = sha256.create().update(concatValue).hex(); + return sha; +} + +export function createAlertStatusPayloads( + clusterId: string, + alertIds: string[], + sessionId: string, + username: string, + route: string, + status: string +): InsightsPayload[] { + return alertIds.map((alertId) => ({ + state: { + route, + cluster_id: clusterId, + user_id: getClusterHashSalt(clusterId, username), + session_id: sessionId, + context: { + alert_id: alertId, + }, + }, + action: { + alert_status: status, + action_timestamp: moment().toISOString(), + }, + })); +} diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts b/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts index 94aa6c867304f0..5246b649ebaa17 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/receiver.ts @@ -38,6 +38,7 @@ export class TelemetryReceiver { private exceptionListClient?: ExceptionListClient; private soClient?: SavedObjectsClientContract; private kibanaIndex?: string; + private clusterInfo?: ESClusterInfo; private readonly max_records = 10_000; constructor(logger: Logger) { @@ -57,6 +58,11 @@ export class TelemetryReceiver { this.exceptionListClient = exceptionListClient; this.soClient = core?.savedObjects.createInternalRepository() as unknown as SavedObjectsClientContract; + this.clusterInfo = await this.fetchClusterInfo(); + } + + public getClusterInfo(): ESClusterInfo | undefined { + return this.clusterInfo; } public async fetchFleetAgents() { @@ -304,7 +310,7 @@ export class TelemetryReceiver { }; } - public async fetchClusterInfo(): Promise { + private async fetchClusterInfo(): Promise { if (this.esClient === undefined || this.esClient === null) { throw Error('elasticsearch client is unavailable: cannot retrieve cluster infomation'); } diff --git a/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts b/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts index 7c9906d0eae48c..3a8d503c9311f8 100644 --- a/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts +++ b/x-pack/plugins/security_solution/server/lib/telemetry/sender.ts @@ -67,6 +67,10 @@ export class TelemetryEventsSender { } } + public getClusterID(): string | undefined { + return this.receiver?.getClusterInfo()?.cluster_uuid; + } + public start( telemetryStart?: TelemetryPluginStart, taskManager?: TaskManagerStartContract, @@ -149,9 +153,10 @@ export class TelemetryEventsSender { return; } - const [telemetryUrl, clusterInfo, licenseInfo] = await Promise.all([ + const clusterInfo = this.receiver?.getClusterInfo(); + + const [telemetryUrl, licenseInfo] = await Promise.all([ this.fetchTelemetryUrl('alerts-endpoint'), - this.receiver?.fetchClusterInfo(), this.receiver?.fetchLicenseInfo(), ]); @@ -198,10 +203,10 @@ export class TelemetryEventsSender { * @param toSend telemetry events */ public async sendOnDemand(channel: string, toSend: unknown[]) { + const clusterInfo = this.receiver?.getClusterInfo(); try { - const [telemetryUrl, clusterInfo, licenseInfo] = await Promise.all([ + const [telemetryUrl, licenseInfo] = await Promise.all([ this.fetchTelemetryUrl(channel), - this.receiver?.fetchClusterInfo(), this.receiver?.fetchLicenseInfo(), ]); @@ -255,6 +260,7 @@ export class TelemetryEventsSender { const ndjson = transformDataToNdjson(events); try { + this.logger.debug(`Sending ${events.length} telemetry events to ${channel}`); const resp = await axios.post(telemetryUrl, ndjson, { headers: { 'Content-Type': 'application/x-ndjson', @@ -275,9 +281,7 @@ export class TelemetryEventsSender { }); this.logger.debug(`Events sent!. Response: ${resp.status} ${JSON.stringify(resp.data)}`); } catch (err) { - this.logger.warn( - `Error sending events: ${err.response.status} ${JSON.stringify(err.response.data)}` - ); + this.logger.debug(`Error sending events: ${err}`); this.telemetryUsageCounter?.incrementCounter({ counterName: createUsageCounterLabel(usageLabelPrefix.concat(['payloads', channel])), counterType: 'docs_lost', diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 39aa1fb069f20e..e9f2e305b65560 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -236,6 +236,7 @@ export class Plugin implements ISecuritySolutionPlugin { config, plugins.encryptedSavedObjects?.canEncrypt === true, plugins.security, + this.telemetryEventsSender, plugins.ml, logger, isRuleRegistryEnabled, diff --git a/x-pack/plugins/security_solution/server/routes/index.ts b/x-pack/plugins/security_solution/server/routes/index.ts index 26dbd80a03db4d..60c5e8a62d7c55 100644 --- a/x-pack/plugins/security_solution/server/routes/index.ts +++ b/x-pack/plugins/security_solution/server/routes/index.ts @@ -55,6 +55,7 @@ import { persistPinnedEventRoute } from '../lib/timeline/routes/pinned_events'; import { SetupPlugins } from '../plugin'; import { ConfigType } from '../config'; +import { TelemetryEventsSender } from '../lib/telemetry/sender'; import { installPrepackedTimelinesRoute } from '../lib/timeline/routes/prepackaged_timelines/install_prepackaged_timelines'; import { previewRulesRoute } from '../lib/detection_engine/routes/rules/preview_rules_route'; import { CreateRuleOptions } from '../lib/detection_engine/rule_types/types'; @@ -67,6 +68,7 @@ export const initRoutes = ( config: ConfigType, hasEncryptionKey: boolean, security: SetupPlugins['security'], + telemetrySender: TelemetryEventsSender, ml: SetupPlugins['ml'], logger: Logger, isRuleRegistryEnabled: boolean, @@ -120,7 +122,7 @@ export const initRoutes = ( // Detection Engine Signals routes that have the REST endpoints of /api/detection_engine/signals // POST /api/detection_engine/signals/status // Example usage can be found in security_solution/server/lib/detection_engine/scripts/signals - setSignalsStatusRoute(router); + setSignalsStatusRoute(router, logger, security, telemetrySender); querySignalsRoute(router, config); getSignalsMigrationStatusRoute(router); createSignalsMigrationRoute(router, security); From 2dba0d18f10cd55e6f2341f57ff31d990c63554f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B8ren=20Louv-Jansen?= Date: Tue, 26 Oct 2021 03:20:15 +0200 Subject: [PATCH 49/66] [APM] Rename `traceData` to `synthtraceEsClient` (#116215) --- x-pack/test/apm_api_integration/common/config.ts | 4 ++-- .../common/{trace_data.ts => synthtrace_es_client.ts} | 2 +- .../apm_api_integration/tests/error_rate/service_apis.ts | 6 +++--- .../test/apm_api_integration/tests/latency/service_apis.ts | 6 +++--- .../tests/observability_overview/observability_overview.ts | 6 +++--- .../tests/service_overview/instances_main_statistics.ts | 6 +++--- .../test/apm_api_integration/tests/services/throughput.ts | 6 +++--- .../tests/throughput/dependencies_apis.ts | 6 +++--- .../apm_api_integration/tests/throughput/service_apis.ts | 6 +++--- .../transactions/transactions_groups_detailed_statistics.ts | 6 +++--- 10 files changed, 27 insertions(+), 27 deletions(-) rename x-pack/test/apm_api_integration/common/{trace_data.ts => synthtrace_es_client.ts} (96%) diff --git a/x-pack/test/apm_api_integration/common/config.ts b/x-pack/test/apm_api_integration/common/config.ts index 574cfe811bc677..978f3f0d68673f 100644 --- a/x-pack/test/apm_api_integration/common/config.ts +++ b/x-pack/test/apm_api_integration/common/config.ts @@ -15,7 +15,7 @@ import { createApmUser, APM_TEST_PASSWORD, ApmUser } from './authentication'; import { APMFtrConfigName } from '../configs'; import { createApmApiClient } from './apm_api_supertest'; import { registry } from './registry'; -import { traceData } from './trace_data'; +import { synthtraceEsClient } from './synthtrace_es_client'; interface Config { name: APMFtrConfigName; @@ -77,7 +77,7 @@ export function createTestConfig(config: Config) { servers, services: { ...services, - traceData, + synthtraceEsClient, apmApiClient: async (context: InheritedFtrProviderContext) => { const security = context.getService('security'); await security.init(); diff --git a/x-pack/test/apm_api_integration/common/trace_data.ts b/x-pack/test/apm_api_integration/common/synthtrace_es_client.ts similarity index 96% rename from x-pack/test/apm_api_integration/common/trace_data.ts rename to x-pack/test/apm_api_integration/common/synthtrace_es_client.ts index 4e813efab29130..68f5c2b08b5181 100644 --- a/x-pack/test/apm_api_integration/common/trace_data.ts +++ b/x-pack/test/apm_api_integration/common/synthtrace_es_client.ts @@ -16,7 +16,7 @@ import pLimit from 'p-limit'; import { inspect } from 'util'; import { InheritedFtrProviderContext } from './ftr_provider_context'; -export async function traceData(context: InheritedFtrProviderContext) { +export async function synthtraceEsClient(context: InheritedFtrProviderContext) { const es = context.getService('es'); return { index: (events: any[]) => { diff --git a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts b/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts index ac81b6d5a4412a..76f8d20c8ada80 100644 --- a/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/error_rate/service_apis.ts @@ -15,7 +15,7 @@ import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); - const traceData = getService('traceData'); + const synthtraceEsClient = getService('synthtraceEsClient'); const serviceName = 'synth-go'; const start = new Date('2021-01-01T00:00:00.000Z').getTime(); @@ -128,7 +128,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { const transactionNameProductList = 'GET /api/product/list'; const transactionNameProductId = 'GET /api/product/:id'; - await traceData.index([ + await synthtraceEsClient.index([ ...timerange(start, end) .interval('1m') .rate(GO_PROD_LIST_RATE) @@ -176,7 +176,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]); }); - after(() => traceData.clean()); + after(() => synthtraceEsClient.clean()); describe('compare error rate value between service inventory, error rate chart, service inventory and transactions apis', () => { before(async () => { diff --git a/x-pack/test/apm_api_integration/tests/latency/service_apis.ts b/x-pack/test/apm_api_integration/tests/latency/service_apis.ts index c6ecf9e4a4abab..d3ec68c51782d2 100644 --- a/x-pack/test/apm_api_integration/tests/latency/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/latency/service_apis.ts @@ -15,7 +15,7 @@ import { registry } from '../../common/registry'; export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); - const traceData = getService('traceData'); + const synthtraceEsClient = getService('synthtraceEsClient'); const serviceName = 'synth-go'; const start = new Date('2021-01-01T00:00:00.000Z').getTime(); @@ -129,7 +129,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { const serviceGoDevInstance = service(serviceName, 'development', 'go').instance( 'instance-b' ); - await traceData.index([ + await synthtraceEsClient.index([ ...timerange(start, end) .interval('1m') .rate(GO_PROD_RATE) @@ -153,7 +153,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]); }); - after(() => traceData.clean()); + after(() => synthtraceEsClient.clean()); describe('compare latency value between service inventory, latency chart, service inventory and transactions apis', () => { before(async () => { diff --git a/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts b/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts index af95f981a3dc5f..e4aad4f3f69755 100644 --- a/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts +++ b/x-pack/test/apm_api_integration/tests/observability_overview/observability_overview.ts @@ -15,7 +15,7 @@ import { roundNumber } from '../../utils'; export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); - const traceData = getService('traceData'); + const synthtraceEsClient = getService('synthtraceEsClient'); const start = new Date('2021-01-01T00:00:00.000Z').getTime(); const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; @@ -99,7 +99,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { 'instance-c' ); - await traceData.index([ + await synthtraceEsClient.index([ ...timerange(start, end) .interval('1m') .rate(GO_PROD_RATE) @@ -133,7 +133,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]); }); - after(() => traceData.clean()); + after(() => synthtraceEsClient.clean()); describe('compare throughput values', () => { let throughputValues: PromiseReturnType; diff --git a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts index 68979795f9dcf0..1e9051b64a90bf 100644 --- a/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/service_overview/instances_main_statistics.ts @@ -21,7 +21,7 @@ import { SERVICE_NODE_NAME_MISSING } from '../../../../plugins/apm/common/servic export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); - const traceData = getService('traceData'); + const synthtraceEsClient = getService('synthtraceEsClient'); const archiveName = 'apm_8.0.0'; const { start, end } = archives[archiveName]; @@ -320,7 +320,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ); } - return traceData.index([ + return synthtraceEsClient.index([ ...interval.rate(GO_A_INSTANCE_RATE_SUCCESS).flatMap((timestamp) => goInstanceA .transaction('GET /api/product/list') @@ -361,7 +361,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); after(async () => { - return traceData.clean(); + return synthtraceEsClient.clean(); }); describe('for the go service', () => { diff --git a/x-pack/test/apm_api_integration/tests/services/throughput.ts b/x-pack/test/apm_api_integration/tests/services/throughput.ts index e98ab60af8ca49..abc7988af823d4 100644 --- a/x-pack/test/apm_api_integration/tests/services/throughput.ts +++ b/x-pack/test/apm_api_integration/tests/services/throughput.ts @@ -23,7 +23,7 @@ type ThroughputReturn = APIReturnType<'GET /internal/apm/services/{serviceName}/ export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); - const traceData = getService('traceData'); + const synthtraceEsClient = getService('synthtraceEsClient'); const serviceName = 'synth-go'; const start = new Date('2021-01-01T00:00:00.000Z').getTime(); @@ -81,7 +81,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { 'instance-c' ); - await traceData.index([ + await synthtraceEsClient.index([ ...timerange(start, end) .interval('1m') .rate(GO_PROD_RATE) @@ -115,7 +115,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]); }); - after(() => traceData.clean()); + after(() => synthtraceEsClient.clean()); describe('compare transactions and metrics based throughput', () => { let throughputMetrics: ThroughputReturn; diff --git a/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts b/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts index 4df40d1d85d564..22b4486181e629 100644 --- a/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts +++ b/x-pack/test/apm_api_integration/tests/throughput/dependencies_apis.ts @@ -15,7 +15,7 @@ import { roundNumber } from '../../utils'; export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); - const traceData = getService('traceData'); + const synthtraceEsClient = getService('synthtraceEsClient'); const start = new Date('2021-01-01T00:00:00.000Z').getTime(); const end = new Date('2021-01-01T00:15:00.000Z').getTime() - 1; @@ -101,7 +101,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { 'instance-c' ); - await traceData.index([ + await synthtraceEsClient.index([ ...timerange(start, end) .interval('1m') .rate(GO_PROD_RATE) @@ -159,7 +159,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]); }); - after(() => traceData.clean()); + after(() => synthtraceEsClient.clean()); describe('verify top dependencies', () => { before(async () => { diff --git a/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts b/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts index 00e5e57c546dd7..ea5252d3490ca0 100644 --- a/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts +++ b/x-pack/test/apm_api_integration/tests/throughput/service_apis.ts @@ -15,7 +15,7 @@ import { roundNumber } from '../../utils'; export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); - const traceData = getService('traceData'); + const synthtraceEsClient = getService('synthtraceEsClient'); const serviceName = 'synth-go'; const start = new Date('2021-01-01T00:00:00.000Z').getTime(); @@ -115,7 +115,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { const serviceGoDevInstance = service(serviceName, 'development', 'go').instance( 'instance-b' ); - await traceData.index([ + await synthtraceEsClient.index([ ...timerange(start, end) .interval('1m') .rate(GO_PROD_RATE) @@ -139,7 +139,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]); }); - after(() => traceData.clean()); + after(() => synthtraceEsClient.clean()); describe('compare throughput value between service inventory, throughput chart, service inventory and transactions apis', () => { before(async () => { diff --git a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts index acdd12f3501bff..fe4058004691b8 100644 --- a/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts +++ b/x-pack/test/apm_api_integration/tests/transactions/transactions_groups_detailed_statistics.ts @@ -20,7 +20,7 @@ type TransactionsGroupsDetailedStatistics = export default function ApiTest({ getService }: FtrProviderContext) { const apmApiClient = getService('apmApiClient'); - const traceData = getService('traceData'); + const synthtraceEsClient = getService('synthtraceEsClient'); const serviceName = 'synth-go'; const start = new Date('2021-01-01T00:00:00.000Z').getTime(); @@ -87,7 +87,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { const transactionName = 'GET /api/product/list'; - await traceData.index([ + await synthtraceEsClient.index([ ...timerange(start, end) .interval('1m') .rate(GO_PROD_RATE) @@ -113,7 +113,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { ]); }); - after(() => traceData.clean()); + after(() => synthtraceEsClient.clean()); describe('without comparisons', () => { let transactionsStatistics: TransactionsGroupsDetailedStatistics; From fd659b762fa4ead26b8663a30e762bebe7348efd Mon Sep 17 00:00:00 2001 From: Jason Rhodes Date: Mon, 25 Oct 2021 23:29:29 -0400 Subject: [PATCH 50/66] Change to infra-monitoring-ui for CODEOWNERS (#116234) logs-metrics-ui and stack-monitoring ui teams have merged into one infra-monitoring-ui team inside of observability --- .github/CODEOWNERS | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ec03acc752d55d..a324b9f429b395 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -95,15 +95,15 @@ # Observability Shared /x-pack/plugins/observability/ @elastic/observability-ui -# Logs and Metrics (Infra) -/x-pack/plugins/infra/ @elastic/logs-metrics-ui -/x-pack/plugins/infra/server/routes/log* @elastic/logs-metrics-ui @elastic/logs-ui -/x-pack/plugins/infra/public/pages/logs/ @elastic/logs-metrics-ui @elastic/logs-ui -/x-pack/plugins/infra/server/routes/metrics* @elastic/logs-metrics-ui @elastic/metrics-ui -/x-pack/plugins/infra/public/pages/metrics/ @elastic/logs-metrics-ui @elastic/metrics-ui - -# Stack Monitoring -/x-pack/plugins/monitoring/ @elastic/stack-monitoring-ui @elastic/logs-metrics-ui @elastic/metrics-ui +# Infra Monitoring +/x-pack/plugins/infra/ @elastic/infra-monitoring-ui +/x-pack/test/functional/apps/infra @elastic/infra-monitoring-ui +/x-pack/test/api_integration/apis/infra @elastic/infra-monitoring-ui + +# Elastic Stack Monitoring +/x-pack/plugins/monitoring/ @elastic/infra-monitoring-ui +/x-pack/test/functional/apps/monitoring @elastic/infra-monitoring-ui +/x-pack/test/api_integration/apis/monitoring @elastic/infra-monitoring-ui # Fleet /x-pack/plugins/fleet/ @elastic/fleet From 8ce1c1f9bb81d320379fb590c317538bccb2cea6 Mon Sep 17 00:00:00 2001 From: Joe Portner <5295965+jportner@users.noreply.github.com> Date: Mon, 25 Oct 2021 23:39:05 -0400 Subject: [PATCH 51/66] Make maps share-capable (#116221) --- x-pack/plugins/maps/server/saved_objects/map.ts | 3 ++- x-pack/test/api_integration/apis/maps/migrations.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/maps/server/saved_objects/map.ts b/x-pack/plugins/maps/server/saved_objects/map.ts index 24effd651a31b0..b13f24fc6ba1cb 100644 --- a/x-pack/plugins/maps/server/saved_objects/map.ts +++ b/x-pack/plugins/maps/server/saved_objects/map.ts @@ -13,7 +13,8 @@ import { savedObjectMigrations } from './saved_object_migrations'; export const mapSavedObjects: SavedObjectsType = { name: 'map', hidden: false, - namespaceType: 'single', + namespaceType: 'multiple-isolated', + convertToMultiNamespaceTypeVersion: '8.0.0', mappings: { properties: { description: { type: 'text' }, diff --git a/x-pack/test/api_integration/apis/maps/migrations.js b/x-pack/test/api_integration/apis/maps/migrations.js index 47747467ae550c..f8b603ac38fde1 100644 --- a/x-pack/test/api_integration/apis/maps/migrations.js +++ b/x-pack/test/api_integration/apis/maps/migrations.js @@ -44,7 +44,7 @@ export default function ({ getService }) { type: 'index-pattern', }, ]); - expect(resp.body.migrationVersion).to.eql({ map: '7.14.0' }); + expect(resp.body.migrationVersion).to.eql({ map: '8.0.0' }); // migrtionVersion is derived from both "migrations" and "convertToMultiNamespaceVersion" fields when the object is registered expect(resp.body.attributes.layerListJSON.includes('indexPatternRefName')).to.be(true); }); }); From 8c6ef2054f7b3d8dfe4c042789a63badec269fec Mon Sep 17 00:00:00 2001 From: Scotty Bollinger Date: Tue, 26 Oct 2021 01:17:35 -0500 Subject: [PATCH 52/66] Fix bug where number rendered as date (#116224) --- .../__mocks__/content_sources.mock.ts | 2 +- .../example_result_detail_card.test.tsx | 14 ++++++++++++++ .../example_result_detail_card.tsx | 5 ++++- .../display_settings/result_detail.test.tsx | 5 ++++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts index 48cbf4ba00d87c..7222edad568224 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/__mocks__/content_sources.mock.ts @@ -376,7 +376,7 @@ export const exampleResult = { source: 'custom', }, ], - schemaFields: {}, + schemaFields: { cats: 'text', dogs: 'text' }, }; export const mostRecentIndexJob = { diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx index 5a15ef641be99e..eeb7f6b54f2c0e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.test.tsx @@ -45,6 +45,7 @@ describe('ExampleResultDetailCard', () => { ...exampleResult, searchResultConfig: { detailFields: [{ fieldName: 'date', label: 'Date' }] }, exampleDocuments: [{ date }], + schemaFields: { date: 'date' }, }); const wrapper = shallow(); @@ -52,4 +53,17 @@ describe('ExampleResultDetailCard', () => { new Date(Date.parse(date)).toLocaleString() ); }); + + it('shows non-formatted value when not a date field', () => { + const value = '9999'; + setMockValues({ + ...exampleResult, + searchResultConfig: { detailFields: [{ fieldName: 'value', label: 'Value' }] }, + exampleDocuments: [{ value }], + schemaFields: { value: 'text' }, + }); + const wrapper = shallow(); + + expect(wrapper.find(EuiText).children().text()).toContain(value); + }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx index 8b0a72ac23e39f..734e370e4c53df 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/display_settings/example_result_detail_card.tsx @@ -12,6 +12,7 @@ import { useValues } from 'kea'; import { EuiFlexGroup, EuiFlexItem, EuiSpacer, EuiText, EuiTitle } from '@elastic/eui'; +import { SchemaType } from '../../../../../shared/schema/types'; import { URL_LABEL } from '../../../../constants'; import { getAsLocalDateTimeString } from '../../../../utils'; @@ -26,6 +27,7 @@ export const ExampleResultDetailCard: React.FC = () => { titleFieldHover, urlFieldHover, exampleDocuments, + schemaFields, } = useValues(DisplaySettingsLogic); const result = exampleDocuments[0]; @@ -63,7 +65,8 @@ export const ExampleResultDetailCard: React.FC = () => { {detailFields.length > 0 ? ( detailFields.map(({ fieldName, label }, index) => { const value = result[fieldName]; - const dateValue = getAsLocalDateTimeString(value); + const fieldType = (schemaFields as { [key: string]: SchemaType })[fieldName]; + const dateValue = fieldType === SchemaType.Date && getAsLocalDateTimeString(value); return (
{ - const { searchResultConfig, exampleDocuments } = exampleResult; + const { searchResultConfig, exampleDocuments, schemaFields } = exampleResult; const availableFieldOptions = [ { value: 'foo', @@ -70,6 +70,7 @@ describe('ResultDetail', () => { searchResultConfig, availableFieldOptions, exampleDocuments, + schemaFields, }); }); @@ -94,6 +95,7 @@ describe('ResultDetail', () => { }, availableFieldOptions, exampleDocuments, + schemaFields, }); const wrapper = shallow(); @@ -122,6 +124,7 @@ describe('ResultDetail', () => { }, availableFieldOptions, exampleDocuments, + schemaFields, }); const wrapper = mount(); From 2c5ecd9b3f6198eac9f4b1eb2913cd866988f84d Mon Sep 17 00:00:00 2001 From: Deepak Sreekumar Date: Tue, 26 Oct 2021 11:54:27 +0530 Subject: [PATCH 53/66] chore: rename functions in aggregated_transactions helper (#116001) * Renamed methods and fixed imports * Fixed lint errors * Renamed file Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../chart_preview/get_transaction_duration.ts | 25 +++++++------------ .../get_transaction_error_rate.ts | 14 ++++------- ...egister_transaction_duration_alert_type.ts | 10 ++++---- ...ister_transaction_error_rate_alert_type.ts | 4 +-- .../lib/environments/get_all_environments.ts | 6 ++--- .../lib/environments/get_environments.ts | 6 ++--- ...t_is_using_transaction_events.test.ts.snap | 0 .../get_is_using_transaction_events.test.ts | 0 .../get_is_using_transaction_events.ts | 0 .../index.ts | 6 ++--- .../get_service_count.ts | 6 ++--- .../get_transactions_per_minute.ts | 12 ++++----- .../get_service_map_service_node_info.ts | 18 ++++++------- .../get_derived_service_annotations.ts | 18 +++++-------- .../server/lib/services/get_service_agent.ts | 6 ++--- .../get_service_instance_metadata_details.ts | 12 ++++----- ...ervice_instances_transaction_statistics.ts | 22 ++++++---------- .../services/get_service_metadata_details.ts | 6 ++--- .../services/get_service_metadata_icons.ts | 6 ++--- ...e_transaction_group_detailed_statistics.ts | 16 ++++++------ .../get_service_transaction_groups.ts | 16 ++++++------ .../services/get_service_transaction_types.ts | 14 ++++------- .../get_service_transaction_stats.ts | 16 ++++++------ ...service_transaction_detailed_statistics.ts | 16 ++++++------ .../apm/server/lib/services/get_throughput.ts | 16 ++++-------- .../agent_configuration/get_service_names.ts | 6 ++--- .../server/lib/suggestions/get_suggestions.ts | 6 ++--- .../server/lib/transaction_groups/fetcher.ts | 14 ++++------- .../lib/transaction_groups/get_error_rate.ts | 16 ++++-------- .../get_transaction_group_stats.ts | 6 ++--- .../transactions/get_latency_charts/index.ts | 25 +++++++------------ .../apm/server/projections/services.ts | 6 ++--- .../plugins/apm/server/routes/environments.ts | 2 +- .../server/routes/fallback_to_transactions.ts | 2 +- .../server/routes/observability_overview.ts | 2 +- .../plugins/apm/server/routes/service_map.ts | 2 +- x-pack/plugins/apm/server/routes/services.ts | 2 +- .../routes/settings/agent_configuration.ts | 2 +- .../routes/settings/anomaly_detection.ts | 2 +- .../plugins/apm/server/routes/suggestions.ts | 2 +- x-pack/plugins/apm/server/routes/traces.ts | 2 +- .../plugins/apm/server/routes/transactions.ts | 2 +- 42 files changed, 143 insertions(+), 227 deletions(-) rename x-pack/plugins/apm/server/lib/helpers/{aggregated_transactions => transactions}/__snapshots__/get_is_using_transaction_events.test.ts.snap (100%) rename x-pack/plugins/apm/server/lib/helpers/{aggregated_transactions => transactions}/get_is_using_transaction_events.test.ts (100%) rename x-pack/plugins/apm/server/lib/helpers/{aggregated_transactions => transactions}/get_is_using_transaction_events.ts (100%) rename x-pack/plugins/apm/server/lib/helpers/{aggregated_transactions => transactions}/index.ts (92%) diff --git a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_duration.ts b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_duration.ts index 1f8b88b3db3e74..1359f4b9259738 100644 --- a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_duration.ts +++ b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_duration.ts @@ -14,11 +14,11 @@ import { import { environmentQuery } from '../../../../common/utils/environment_query'; import { AlertParams } from '../../../routes/alerts/chart_preview'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, getSearchAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, + getProcessorEventForTransactions, +} from '../../helpers/transactions'; import { Setup } from '../../helpers/setup_request'; export async function getTransactionDurationChartPreview({ @@ -52,17 +52,14 @@ export async function getTransactionDurationChartPreview({ : []), ...rangeQuery(start, end), ...environmentQuery(environment), - ...getDocumentTypeFilterForAggregatedTransactions( - searchAggregatedTransactions - ), + ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), ] as QueryDslQueryContainer[], }, }; - const transactionDurationField = - getTransactionDurationFieldForAggregatedTransactions( - searchAggregatedTransactions - ); + const transactionDurationField = getTransactionDurationFieldForTransactions( + searchAggregatedTransactions + ); const aggs = { timeseries: { @@ -90,11 +87,7 @@ export async function getTransactionDurationChartPreview({ }; const params = { apm: { - events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), - ], + events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, query, aggs }, }; diff --git a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_rate.ts b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_rate.ts index 1690c92b23e666..d3f03c597e8fb8 100644 --- a/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_rate.ts +++ b/x-pack/plugins/apm/server/lib/alerts/chart_preview/get_transaction_error_rate.ts @@ -13,10 +13,10 @@ import { import { environmentQuery } from '../../../../common/utils/environment_query'; import { AlertParams } from '../../../routes/alerts/chart_preview'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, getSearchAggregatedTransactions, -} from '../../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getProcessorEventForTransactions, +} from '../../helpers/transactions'; import { Setup } from '../../helpers/setup_request'; import { calculateFailedTransactionRate, @@ -45,11 +45,7 @@ export async function getTransactionErrorRateChartPreview({ const params = { apm: { - events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), - ], + events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, @@ -62,7 +58,7 @@ export async function getTransactionErrorRateChartPreview({ : []), ...rangeQuery(start, end), ...environmentQuery(environment), - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), ], diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts index df4de254346c92..698bbcdbdb84a8 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_duration_alert_type.ts @@ -41,9 +41,9 @@ import { ProcessorEvent } from '../../../common/processor_event'; import { environmentQuery } from '../../../common/utils/environment_query'; import { getDurationFormatter } from '../../../common/utils/formatters'; import { - getDocumentTypeFilterForAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, +} from '../helpers/transactions'; import { getApmIndices } from '../settings/apm_indices/get_apm_indices'; import { apmActionVariables } from './action_variables'; import { alertingEsClient } from './alerting_es_client'; @@ -122,7 +122,7 @@ export function registerTransactionDurationAlertType({ ? indices.metric : indices.transaction; - const field = getTransactionDurationFieldForAggregatedTransactions( + const field = getTransactionDurationFieldForTransactions( searchAggregatedTransactions ); @@ -140,7 +140,7 @@ export function registerTransactionDurationAlertType({ }, }, }, - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), { term: { [SERVICE_NAME]: alertParams.serviceName } }, diff --git a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts index 598487d02625a7..5ba7ed5321d703 100644 --- a/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts +++ b/x-pack/plugins/apm/server/lib/alerts/register_transaction_error_rate_alert_type.ts @@ -46,7 +46,7 @@ import { apmActionVariables } from './action_variables'; import { alertingEsClient } from './alerting_es_client'; import { RegisterRuleDependencies } from './register_apm_alerts'; import { SearchAggregatedTransactionSetting } from '../../../common/aggregated_transactions'; -import { getDocumentTypeFilterForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getDocumentTypeFilterForTransactions } from '../helpers/transactions'; import { asPercent } from '../../../../observability/common/utils/formatters'; const ALERT_EVALUATION_THRESHOLD: typeof ALERT_EVALUATION_THRESHOLD_TYPED = @@ -131,7 +131,7 @@ export function registerTransactionErrorRateAlertType({ }, }, }, - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), { diff --git a/x-pack/plugins/apm/server/lib/environments/get_all_environments.ts b/x-pack/plugins/apm/server/lib/environments/get_all_environments.ts index 1ddc3f7ed888c9..d6c53aeea078ee 100644 --- a/x-pack/plugins/apm/server/lib/environments/get_all_environments.ts +++ b/x-pack/plugins/apm/server/lib/environments/get_all_environments.ts @@ -12,7 +12,7 @@ import { SERVICE_ENVIRONMENT, } from '../../../common/elasticsearch_fieldnames'; import { ENVIRONMENT_NOT_DEFINED } from '../../../common/environment_filter_values'; -import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../helpers/transactions'; /** * This is used for getting *all* environments, and does not filter by range. @@ -45,9 +45,7 @@ export async function getAllEnvironments({ const params = { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.error, ProcessorEvent.metric, ], diff --git a/x-pack/plugins/apm/server/lib/environments/get_environments.ts b/x-pack/plugins/apm/server/lib/environments/get_environments.ts index 08f6f089e8d083..678cfd891ae575 100644 --- a/x-pack/plugins/apm/server/lib/environments/get_environments.ts +++ b/x-pack/plugins/apm/server/lib/environments/get_environments.ts @@ -12,7 +12,7 @@ import { import { ENVIRONMENT_NOT_DEFINED } from '../../../common/environment_filter_values'; import { ProcessorEvent } from '../../../common/processor_event'; import { rangeQuery } from '../../../../observability/server'; -import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; /** @@ -51,9 +51,7 @@ export async function getEnvironments({ const params = { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.metric, ProcessorEvent.error, ], diff --git a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/__snapshots__/get_is_using_transaction_events.test.ts.snap b/x-pack/plugins/apm/server/lib/helpers/transactions/__snapshots__/get_is_using_transaction_events.test.ts.snap similarity index 100% rename from x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/__snapshots__/get_is_using_transaction_events.test.ts.snap rename to x-pack/plugins/apm/server/lib/helpers/transactions/__snapshots__/get_is_using_transaction_events.test.ts.snap diff --git a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.test.ts b/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.test.ts similarity index 100% rename from x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.test.ts rename to x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.test.ts diff --git a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.ts b/x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts similarity index 100% rename from x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/get_is_using_transaction_events.ts rename to x-pack/plugins/apm/server/lib/helpers/transactions/get_is_using_transaction_events.ts diff --git a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/index.ts b/x-pack/plugins/apm/server/lib/helpers/transactions/index.ts similarity index 92% rename from x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/index.ts rename to x-pack/plugins/apm/server/lib/helpers/transactions/index.ts index a58a95dd43fcc3..f16e03ddc3ea47 100644 --- a/x-pack/plugins/apm/server/lib/helpers/aggregated_transactions/index.ts +++ b/x-pack/plugins/apm/server/lib/helpers/transactions/index.ts @@ -77,7 +77,7 @@ export async function getSearchAggregatedTransactions({ ); } -export function getTransactionDurationFieldForAggregatedTransactions( +export function getTransactionDurationFieldForTransactions( searchAggregatedTransactions: boolean ) { return searchAggregatedTransactions @@ -85,7 +85,7 @@ export function getTransactionDurationFieldForAggregatedTransactions( : TRANSACTION_DURATION; } -export function getDocumentTypeFilterForAggregatedTransactions( +export function getDocumentTypeFilterForTransactions( searchAggregatedTransactions: boolean ) { return searchAggregatedTransactions @@ -93,7 +93,7 @@ export function getDocumentTypeFilterForAggregatedTransactions( : []; } -export function getProcessorEventForAggregatedTransactions( +export function getProcessorEventForTransactions( searchAggregatedTransactions: boolean ): ProcessorEvent.metric | ProcessorEvent.transaction { return searchAggregatedTransactions diff --git a/x-pack/plugins/apm/server/lib/observability_overview/get_service_count.ts b/x-pack/plugins/apm/server/lib/observability_overview/get_service_count.ts index a181b1a41fbc70..3eb11f668115d6 100644 --- a/x-pack/plugins/apm/server/lib/observability_overview/get_service_count.ts +++ b/x-pack/plugins/apm/server/lib/observability_overview/get_service_count.ts @@ -9,7 +9,7 @@ import { ProcessorEvent } from '../../../common/processor_event'; import { rangeQuery } from '../../../../observability/server'; import { SERVICE_NAME } from '../../../common/elasticsearch_fieldnames'; import { Setup } from '../helpers/setup_request'; -import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../helpers/transactions'; export async function getServiceCount({ setup, @@ -27,9 +27,7 @@ export async function getServiceCount({ const params = { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.error, ProcessorEvent.metric, ], diff --git a/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts b/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts index 8c64670f5d2e97..829afa8330164e 100644 --- a/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts +++ b/x-pack/plugins/apm/server/lib/observability_overview/get_transactions_per_minute.ts @@ -13,9 +13,9 @@ import { TRANSACTION_TYPE } from '../../../common/elasticsearch_fieldnames'; import { rangeQuery } from '../../../../observability/server'; import { Setup } from '../helpers/setup_request'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; import { calculateThroughputWithInterval, calculateThroughputWithRange, @@ -43,9 +43,7 @@ export async function getTransactionsPerMinute({ { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ], }, body: { @@ -54,7 +52,7 @@ export async function getTransactionsPerMinute({ bool: { filter: [ ...rangeQuery(start, end), - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), ], diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts index 78ca3fad63189a..43147684ef3f78 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_service_node_info.ts @@ -23,10 +23,10 @@ import { rangeQuery } from '../../../../observability/server'; import { environmentQuery } from '../../../common/utils/environment_query'; import { withApmSpan } from '../../utils/with_apm_span'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; import { percentCgroupMemoryUsedScript, @@ -131,11 +131,7 @@ async function getTransactionStats({ const params = { apm: { - events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), - ], + events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, @@ -143,7 +139,7 @@ async function getTransactionStats({ bool: { filter: [ ...filter, - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), { @@ -161,7 +157,7 @@ async function getTransactionStats({ aggs: { duration: { avg: { - field: getTransactionDurationFieldForAggregatedTransactions( + field: getTransactionDurationFieldForTransactions( searchAggregatedTransactions ), }, diff --git a/x-pack/plugins/apm/server/lib/services/annotations/get_derived_service_annotations.ts b/x-pack/plugins/apm/server/lib/services/annotations/get_derived_service_annotations.ts index 3af9b557dd1272..22b37e33a26e2d 100644 --- a/x-pack/plugins/apm/server/lib/services/annotations/get_derived_service_annotations.ts +++ b/x-pack/plugins/apm/server/lib/services/annotations/get_derived_service_annotations.ts @@ -15,9 +15,9 @@ import { import { rangeQuery } from '../../../../../observability/server'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, -} from '../../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getProcessorEventForTransactions, +} from '../../helpers/transactions'; import { Setup } from '../../helpers/setup_request'; export async function getDerivedServiceAnnotations({ @@ -39,9 +39,7 @@ export async function getDerivedServiceAnnotations({ const filter: ESFilter[] = [ { term: { [SERVICE_NAME]: serviceName } }, - ...getDocumentTypeFilterForAggregatedTransactions( - searchAggregatedTransactions - ), + ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), ...environmentQuery(environment), ]; @@ -50,9 +48,7 @@ export async function getDerivedServiceAnnotations({ await apmEventClient.search('get_derived_service_annotations', { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ], }, body: { @@ -83,9 +79,7 @@ export async function getDerivedServiceAnnotations({ { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ], }, body: { diff --git a/x-pack/plugins/apm/server/lib/services/get_service_agent.ts b/x-pack/plugins/apm/server/lib/services/get_service_agent.ts index a9bb3c8f3103f9..5ef29437d73d6a 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_agent.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_agent.ts @@ -13,7 +13,7 @@ import { } from '../../../common/elasticsearch_fieldnames'; import { rangeQuery } from '../../../../observability/server'; import { Setup } from '../helpers/setup_request'; -import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../helpers/transactions'; interface ServiceAgent { agent?: { @@ -46,9 +46,7 @@ export async function getServiceAgent({ apm: { events: [ ProcessorEvent.error, - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.metric, ], }, diff --git a/x-pack/plugins/apm/server/lib/services/get_service_instance_metadata_details.ts b/x-pack/plugins/apm/server/lib/services/get_service_instance_metadata_details.ts index ba122ea5ad0e62..d349ca3ce0399c 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_instance_metadata_details.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_instance_metadata_details.ts @@ -15,9 +15,9 @@ import { rangeQuery } from '../../../../observability/server'; import { Setup } from '../helpers/setup_request'; import { maybe } from '../../../common/utils/maybe'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; export async function getServiceInstanceMetadataDetails({ serviceName, @@ -84,16 +84,14 @@ export async function getServiceInstanceMetadataDetails({ 'get_service_instance_metadata_details_application_transaction_metric', { apm: { - events: [getProcessorEventForAggregatedTransactions(true)], + events: [getProcessorEventForTransactions(true)], }, body: { terminate_after: 1, size: 1, query: { bool: { - filter: filter.concat( - getDocumentTypeFilterForAggregatedTransactions(true) - ), + filter: filter.concat(getDocumentTypeFilterForTransactions(true)), }, }, }, diff --git a/x-pack/plugins/apm/server/lib/services/get_service_instances/get_service_instances_transaction_statistics.ts b/x-pack/plugins/apm/server/lib/services/get_service_instances/get_service_instances_transaction_statistics.ts index ec76e0d35e5c00..b0f64036a18457 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_instances/get_service_instances_transaction_statistics.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_instances/get_service_instances_transaction_statistics.ts @@ -17,10 +17,10 @@ import { Coordinate } from '../../../../typings/timeseries'; import { kqlQuery, rangeQuery } from '../../../../../observability/server'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, + getProcessorEventForTransactions, +} from '../../helpers/transactions'; import { calculateThroughput } from '../../helpers/calculate_throughput'; import { getBucketSizeForAggregatedTransactions } from '../../helpers/get_bucket_size_for_aggregated_transactions'; import { @@ -89,7 +89,7 @@ export async function getServiceInstancesTransactionStatistics< } ); - const field = getTransactionDurationFieldForAggregatedTransactions( + const field = getTransactionDurationFieldForTransactions( searchAggregatedTransactions ); @@ -109,15 +109,11 @@ export async function getServiceInstancesTransactionStatistics< filter: [ { term: { [SERVICE_NAME]: serviceName } }, { term: { [TRANSACTION_TYPE]: transactionType } }, - ...getDocumentTypeFilterForAggregatedTransactions( - searchAggregatedTransactions - ), + ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), ...rangeQuery(start, end), ...environmentQuery(environment), ...kqlQuery(kuery), - ...getDocumentTypeFilterForAggregatedTransactions( - searchAggregatedTransactions - ), + ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), ...(isComparisonSearch && serviceNodeIds ? [{ terms: { [SERVICE_NODE_NAME]: serviceNodeIds } }] : []), @@ -154,9 +150,7 @@ export async function getServiceInstancesTransactionStatistics< { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ], }, body: { size: 0, query, aggs }, diff --git a/x-pack/plugins/apm/server/lib/services/get_service_metadata_details.ts b/x-pack/plugins/apm/server/lib/services/get_service_metadata_details.ts index 7a39e953ad4963..e2852a51b0c060 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_metadata_details.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_metadata_details.ts @@ -22,7 +22,7 @@ import { import { ContainerType } from '../../../common/service_metadata'; import { rangeQuery } from '../../../../observability/server'; import { TransactionRaw } from '../../../typings/es_schemas/raw/transaction_raw'; -import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; import { should } from './get_service_metadata_icons'; @@ -81,9 +81,7 @@ export async function getServiceMetadataDetails({ const params = { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.error, ProcessorEvent.metric, ], diff --git a/x-pack/plugins/apm/server/lib/services/get_service_metadata_icons.ts b/x-pack/plugins/apm/server/lib/services/get_service_metadata_icons.ts index 26a3090946ff86..2c93a298cb134f 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_metadata_icons.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_metadata_icons.ts @@ -18,7 +18,7 @@ import { import { ContainerType } from '../../../common/service_metadata'; import { rangeQuery } from '../../../../observability/server'; import { TransactionRaw } from '../../../typings/es_schemas/raw/transaction_raw'; -import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; type ServiceMetadataIconsRaw = Pick< @@ -63,9 +63,7 @@ export async function getServiceMetadataIcons({ const params = { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.error, ProcessorEvent.metric, ], diff --git a/x-pack/plugins/apm/server/lib/services/get_service_transaction_group_detailed_statistics.ts b/x-pack/plugins/apm/server/lib/services/get_service_transaction_group_detailed_statistics.ts index feab6d78f02c81..35256e6a7ecd64 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_transaction_group_detailed_statistics.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_transaction_group_detailed_statistics.ts @@ -19,10 +19,10 @@ import { kqlQuery, rangeQuery } from '../../../../observability/server'; import { environmentQuery } from '../../../common/utils/environment_query'; import { Coordinate } from '../../../typings/timeseries'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; import { getBucketSizeForAggregatedTransactions } from '../helpers/get_bucket_size_for_aggregated_transactions'; import { getLatencyAggregation, @@ -72,7 +72,7 @@ export async function getServiceTransactionGroupDetailedStatistics({ searchAggregatedTransactions, }); - const field = getTransactionDurationFieldForAggregatedTransactions( + const field = getTransactionDurationFieldForTransactions( searchAggregatedTransactions ); @@ -81,9 +81,7 @@ export async function getServiceTransactionGroupDetailedStatistics({ { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ], }, body: { @@ -93,7 +91,7 @@ export async function getServiceTransactionGroupDetailedStatistics({ filter: [ { term: { [SERVICE_NAME]: serviceName } }, { term: { [TRANSACTION_TYPE]: transactionType } }, - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), ...rangeQuery(start, end), diff --git a/x-pack/plugins/apm/server/lib/services/get_service_transaction_groups.ts b/x-pack/plugins/apm/server/lib/services/get_service_transaction_groups.ts index fbc1e2880495be..7f624693a3b9ca 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_transaction_groups.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_transaction_groups.ts @@ -16,10 +16,10 @@ import { LatencyAggregationType } from '../../../common/latency_aggregation_type import { rangeQuery, kqlQuery } from '../../../../observability/server'; import { environmentQuery } from '../../../common/utils/environment_query'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; import { calculateThroughput } from '../helpers/calculate_throughput'; import { getLatencyAggregation, @@ -59,7 +59,7 @@ export async function getServiceTransactionGroups({ const { apmEventClient, config } = setup; const bucketSize = config.ui.transactionGroupBucketSize; - const field = getTransactionDurationFieldForAggregatedTransactions( + const field = getTransactionDurationFieldForTransactions( searchAggregatedTransactions ); @@ -68,9 +68,7 @@ export async function getServiceTransactionGroups({ { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ], }, body: { @@ -80,7 +78,7 @@ export async function getServiceTransactionGroups({ filter: [ { term: { [SERVICE_NAME]: serviceName } }, { term: { [TRANSACTION_TYPE]: transactionType } }, - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), ...rangeQuery(start, end), diff --git a/x-pack/plugins/apm/server/lib/services/get_service_transaction_types.ts b/x-pack/plugins/apm/server/lib/services/get_service_transaction_types.ts index 9e3d39e7f28010..1c2d1c9207bc33 100644 --- a/x-pack/plugins/apm/server/lib/services/get_service_transaction_types.ts +++ b/x-pack/plugins/apm/server/lib/services/get_service_transaction_types.ts @@ -12,9 +12,9 @@ import { import { rangeQuery } from '../../../../observability/server'; import { Setup } from '../helpers/setup_request'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; export async function getServiceTransactionTypes({ setup, @@ -33,18 +33,14 @@ export async function getServiceTransactionTypes({ const params = { apm: { - events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), - ], + events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, query: { bool: { filter: [ - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), { term: { [SERVICE_NAME]: serviceName } }, diff --git a/x-pack/plugins/apm/server/lib/services/get_services/get_service_transaction_stats.ts b/x-pack/plugins/apm/server/lib/services/get_services/get_service_transaction_stats.ts index 24d2640024d287..36903f9ca229f8 100644 --- a/x-pack/plugins/apm/server/lib/services/get_services/get_service_transaction_stats.ts +++ b/x-pack/plugins/apm/server/lib/services/get_services/get_service_transaction_stats.ts @@ -19,10 +19,10 @@ import { import { environmentQuery } from '../../../../common/utils/environment_query'; import { AgentName } from '../../../../typings/es_schemas/ui/fields/agent'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, + getProcessorEventForTransactions, +} from '../../helpers/transactions'; import { calculateThroughput } from '../../helpers/calculate_throughput'; import { calculateFailedTransactionRate, @@ -56,7 +56,7 @@ export async function getServiceTransactionStats({ const metrics = { avg_duration: { avg: { - field: getTransactionDurationFieldForAggregatedTransactions( + field: getTransactionDurationFieldForTransactions( searchAggregatedTransactions ), }, @@ -69,9 +69,7 @@ export async function getServiceTransactionStats({ { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ], }, body: { @@ -79,7 +77,7 @@ export async function getServiceTransactionStats({ query: { bool: { filter: [ - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), ...rangeQuery(start, end), diff --git a/x-pack/plugins/apm/server/lib/services/get_services_detailed_statistics/get_service_transaction_detailed_statistics.ts b/x-pack/plugins/apm/server/lib/services/get_services_detailed_statistics/get_service_transaction_detailed_statistics.ts index 14a37600bb4c3f..686555e7764ab1 100644 --- a/x-pack/plugins/apm/server/lib/services/get_services_detailed_statistics/get_service_transaction_detailed_statistics.ts +++ b/x-pack/plugins/apm/server/lib/services/get_services_detailed_statistics/get_service_transaction_detailed_statistics.ts @@ -18,10 +18,10 @@ import { import { environmentQuery } from '../../../../common/utils/environment_query'; import { getOffsetInMs } from '../../../../common/utils/get_offset_in_ms'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, + getProcessorEventForTransactions, +} from '../../helpers/transactions'; import { calculateThroughput } from '../../helpers/calculate_throughput'; import { getBucketSizeForAggregatedTransactions } from '../../helpers/get_bucket_size_for_aggregated_transactions'; import { Setup } from '../../helpers/setup_request'; @@ -61,7 +61,7 @@ export async function getServiceTransactionDetailedStatistics({ const metrics = { avg_duration: { avg: { - field: getTransactionDurationFieldForAggregatedTransactions( + field: getTransactionDurationFieldForTransactions( searchAggregatedTransactions ), }, @@ -74,9 +74,7 @@ export async function getServiceTransactionDetailedStatistics({ { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ], }, body: { @@ -84,7 +82,7 @@ export async function getServiceTransactionDetailedStatistics({ query: { bool: { filter: [ - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), ...rangeQuery(startWithOffset, endWithOffset), diff --git a/x-pack/plugins/apm/server/lib/services/get_throughput.ts b/x-pack/plugins/apm/server/lib/services/get_throughput.ts index 669203ad198b9a..e31e9dd3b8c9f3 100644 --- a/x-pack/plugins/apm/server/lib/services/get_throughput.ts +++ b/x-pack/plugins/apm/server/lib/services/get_throughput.ts @@ -14,9 +14,9 @@ import { import { kqlQuery, rangeQuery } from '../../../../observability/server'; import { environmentQuery } from '../../../common/utils/environment_query'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; import { calculateThroughputWithInterval } from '../helpers/calculate_throughput'; @@ -52,9 +52,7 @@ export async function getThroughput({ const filter: ESFilter[] = [ { term: { [SERVICE_NAME]: serviceName } }, { term: { [TRANSACTION_TYPE]: transactionType } }, - ...getDocumentTypeFilterForAggregatedTransactions( - searchAggregatedTransactions - ), + ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), ...rangeQuery(start, end), ...environmentQuery(environment), ...kqlQuery(kuery), @@ -70,11 +68,7 @@ export async function getThroughput({ const params = { apm: { - events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), - ], + events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, diff --git a/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_service_names.ts b/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_service_names.ts index 282eacbec66d1b..06bd900872a20f 100644 --- a/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_service_names.ts +++ b/x-pack/plugins/apm/server/lib/settings/agent_configuration/get_service_names.ts @@ -10,7 +10,7 @@ import { Setup } from '../../helpers/setup_request'; import { PromiseReturnType } from '../../../../../observability/typings/common'; import { SERVICE_NAME } from '../../../../common/elasticsearch_fieldnames'; import { ALL_OPTION_VALUE } from '../../../../common/agent_configuration/all_option'; -import { getProcessorEventForAggregatedTransactions } from '../../helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../../helpers/transactions'; export type AgentConfigurationServicesAPIResponse = PromiseReturnType< typeof getServiceNames @@ -30,9 +30,7 @@ export async function getServiceNames({ const params = { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.error, ProcessorEvent.metric, ], diff --git a/x-pack/plugins/apm/server/lib/suggestions/get_suggestions.ts b/x-pack/plugins/apm/server/lib/suggestions/get_suggestions.ts index acd44366ef4c36..5ea28debc4437e 100644 --- a/x-pack/plugins/apm/server/lib/suggestions/get_suggestions.ts +++ b/x-pack/plugins/apm/server/lib/suggestions/get_suggestions.ts @@ -6,7 +6,7 @@ */ import { ProcessorEvent } from '../../../common/processor_event'; -import { getProcessorEventForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; export async function getSuggestions({ @@ -27,9 +27,7 @@ export async function getSuggestions({ const response = await apmEventClient.termsEnum('get_suggestions', { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.error, ProcessorEvent.metric, ], diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts b/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts index dc7cc0f804469e..f082483c0c1091 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/fetcher.ts @@ -22,9 +22,9 @@ import { environmentQuery } from '../../../common/utils/environment_query'; import { joinByKey } from '../../../common/utils/join_by_key'; import { withApmSpan } from '../../utils/with_apm_span'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; import { Setup } from '../helpers/setup_request'; import { getAverages, getCounts, getSums } from './get_transaction_group_stats'; @@ -75,11 +75,7 @@ function getRequest(topTraceOptions: TopTraceOptions) { return { apm: { - events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), - ], + events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, @@ -87,7 +83,7 @@ function getRequest(topTraceOptions: TopTraceOptions) { bool: { filter: [ ...transactionNameFilter, - ...getDocumentTypeFilterForAggregatedTransactions( + ...getDocumentTypeFilterForTransactions( searchAggregatedTransactions ), ...rangeQuery(start, end), diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts index d57b0400abed9a..e85bd61ac440af 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_error_rate.ts @@ -17,9 +17,9 @@ import { kqlQuery, rangeQuery } from '../../../../observability/server'; import { environmentQuery } from '../../../common/utils/environment_query'; import { Coordinate } from '../../../typings/timeseries'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, -} from '../helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getProcessorEventForTransactions, +} from '../helpers/transactions'; import { getBucketSizeForAggregatedTransactions } from '../helpers/get_bucket_size_for_aggregated_transactions'; import { Setup } from '../helpers/setup_request'; import { @@ -71,9 +71,7 @@ export async function getErrorRate({ }, ...transactionNamefilter, ...transactionTypefilter, - ...getDocumentTypeFilterForAggregatedTransactions( - searchAggregatedTransactions - ), + ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), ...rangeQuery(start, end), ...environmentQuery(environment), ...kqlQuery(kuery), @@ -83,11 +81,7 @@ export async function getErrorRate({ const params = { apm: { - events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), - ], + events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_group_stats.ts b/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_group_stats.ts index 980d8f10610c8f..8769a572e33a01 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_group_stats.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/get_transaction_group_stats.ts @@ -10,7 +10,7 @@ import { estypes } from '@elastic/elasticsearch'; import { TRANSACTION_TYPE } from '../../../common/elasticsearch_fieldnames'; import { arrayUnionToCallable } from '../../../common/utils/array_union_to_callable'; import { TransactionGroupRequestBase, TransactionGroupSetup } from './fetcher'; -import { getTransactionDurationFieldForAggregatedTransactions } from '../helpers/aggregated_transactions'; +import { getTransactionDurationFieldForTransactions } from '../helpers/transactions'; interface MetricParams { request: TransactionGroupRequestBase; @@ -46,7 +46,7 @@ export async function getAverages({ const params = mergeRequestWithAggs(request, { avg: { avg: { - field: getTransactionDurationFieldForAggregatedTransactions( + field: getTransactionDurationFieldForTransactions( searchAggregatedTransactions ), }, @@ -110,7 +110,7 @@ export async function getSums({ const params = mergeRequestWithAggs(request, { sum: { sum: { - field: getTransactionDurationFieldForAggregatedTransactions( + field: getTransactionDurationFieldForTransactions( searchAggregatedTransactions ), }, diff --git a/x-pack/plugins/apm/server/lib/transactions/get_latency_charts/index.ts b/x-pack/plugins/apm/server/lib/transactions/get_latency_charts/index.ts index 01e2d905bbf21f..c4bae841764cf7 100644 --- a/x-pack/plugins/apm/server/lib/transactions/get_latency_charts/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/get_latency_charts/index.ts @@ -17,10 +17,10 @@ import { offsetPreviousPeriodCoordinates } from '../../../../common/utils/offset import { kqlQuery, rangeQuery } from '../../../../../observability/server'; import { environmentQuery } from '../../../../common/utils/environment_query'; import { - getDocumentTypeFilterForAggregatedTransactions, - getProcessorEventForAggregatedTransactions, - getTransactionDurationFieldForAggregatedTransactions, -} from '../../../lib/helpers/aggregated_transactions'; + getDocumentTypeFilterForTransactions, + getTransactionDurationFieldForTransactions, + getProcessorEventForTransactions, +} from '../../../lib/helpers/transactions'; import { Setup } from '../../../lib/helpers/setup_request'; import { getBucketSizeForAggregatedTransactions } from '../../helpers/get_bucket_size_for_aggregated_transactions'; import { @@ -63,9 +63,7 @@ function searchLatency({ const filter: ESFilter[] = [ { term: { [SERVICE_NAME]: serviceName } }, - ...getDocumentTypeFilterForAggregatedTransactions( - searchAggregatedTransactions - ), + ...getDocumentTypeFilterForTransactions(searchAggregatedTransactions), ...rangeQuery(start, end), ...environmentQuery(environment), ...kqlQuery(kuery), @@ -79,18 +77,13 @@ function searchLatency({ filter.push({ term: { [TRANSACTION_TYPE]: transactionType } }); } - const transactionDurationField = - getTransactionDurationFieldForAggregatedTransactions( - searchAggregatedTransactions - ); + const transactionDurationField = getTransactionDurationFieldForTransactions( + searchAggregatedTransactions + ); const params = { apm: { - events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), - ], + events: [getProcessorEventForTransactions(searchAggregatedTransactions)], }, body: { size: 0, diff --git a/x-pack/plugins/apm/server/projections/services.ts b/x-pack/plugins/apm/server/projections/services.ts index afa6f4ba752f0e..139c86acd5144b 100644 --- a/x-pack/plugins/apm/server/projections/services.ts +++ b/x-pack/plugins/apm/server/projections/services.ts @@ -9,7 +9,7 @@ import { Setup } from '../../server/lib/helpers/setup_request'; import { SERVICE_NAME } from '../../common/elasticsearch_fieldnames'; import { rangeQuery, kqlQuery } from '../../../observability/server'; import { ProcessorEvent } from '../../common/processor_event'; -import { getProcessorEventForAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; +import { getProcessorEventForTransactions } from '../lib/helpers/transactions'; export function getServicesProjection({ kuery, @@ -27,9 +27,7 @@ export function getServicesProjection({ return { apm: { events: [ - getProcessorEventForAggregatedTransactions( - searchAggregatedTransactions - ), + getProcessorEventForTransactions(searchAggregatedTransactions), ProcessorEvent.metric as const, ProcessorEvent.error as const, ], diff --git a/x-pack/plugins/apm/server/routes/environments.ts b/x-pack/plugins/apm/server/routes/environments.ts index 59e75f6f9c3411..e54ad79f177c4f 100644 --- a/x-pack/plugins/apm/server/routes/environments.ts +++ b/x-pack/plugins/apm/server/routes/environments.ts @@ -7,7 +7,7 @@ import * as t from 'io-ts'; import { maxSuggestions } from '../../../observability/common'; -import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../lib/helpers/transactions'; import { setupRequest } from '../lib/helpers/setup_request'; import { getEnvironments } from '../lib/environments/get_environments'; import { rangeRt } from './default_api_types'; diff --git a/x-pack/plugins/apm/server/routes/fallback_to_transactions.ts b/x-pack/plugins/apm/server/routes/fallback_to_transactions.ts index ba74cc0b7a88ae..99c6a290e34b1b 100644 --- a/x-pack/plugins/apm/server/routes/fallback_to_transactions.ts +++ b/x-pack/plugins/apm/server/routes/fallback_to_transactions.ts @@ -6,7 +6,7 @@ */ import * as t from 'io-ts'; -import { getIsUsingTransactionEvents } from '../lib/helpers/aggregated_transactions/get_is_using_transaction_events'; +import { getIsUsingTransactionEvents } from '../lib/helpers/transactions/get_is_using_transaction_events'; import { setupRequest } from '../lib/helpers/setup_request'; import { createApmServerRoute } from './create_apm_server_route'; import { createApmServerRouteRepository } from './create_apm_server_route_repository'; diff --git a/x-pack/plugins/apm/server/routes/observability_overview.ts b/x-pack/plugins/apm/server/routes/observability_overview.ts index 0dbebd061e8be5..2aff798f9ad0b3 100644 --- a/x-pack/plugins/apm/server/routes/observability_overview.ts +++ b/x-pack/plugins/apm/server/routes/observability_overview.ts @@ -12,7 +12,7 @@ import { getServiceCount } from '../lib/observability_overview/get_service_count import { getTransactionsPerMinute } from '../lib/observability_overview/get_transactions_per_minute'; import { getHasData } from '../lib/observability_overview/has_data'; import { rangeRt } from './default_api_types'; -import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../lib/helpers/transactions'; import { withApmSpan } from '../utils/with_apm_span'; import { createApmServerRouteRepository } from './create_apm_server_route_repository'; import { createApmServerRoute } from './create_apm_server_route'; diff --git a/x-pack/plugins/apm/server/routes/service_map.ts b/x-pack/plugins/apm/server/routes/service_map.ts index 17fb9d7c98c5f9..038f909d7b3348 100644 --- a/x-pack/plugins/apm/server/routes/service_map.ts +++ b/x-pack/plugins/apm/server/routes/service_map.ts @@ -10,7 +10,7 @@ import * as t from 'io-ts'; import { isActivePlatinumLicense } from '../../common/license_check'; import { invalidLicenseMessage } from '../../common/service_map'; import { notifyFeatureUsage } from '../feature'; -import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../lib/helpers/transactions'; import { setupRequest } from '../lib/helpers/setup_request'; import { getServiceMap } from '../lib/service_map/get_service_map'; import { getServiceMapBackendNodeInfo } from '../lib/service_map/get_service_map_backend_node_info'; diff --git a/x-pack/plugins/apm/server/routes/services.ts b/x-pack/plugins/apm/server/routes/services.ts index f1f29dc2f036ca..257aec216eb06c 100644 --- a/x-pack/plugins/apm/server/routes/services.ts +++ b/x-pack/plugins/apm/server/routes/services.ts @@ -11,7 +11,7 @@ import * as t from 'io-ts'; import { uniq } from 'lodash'; import { latencyAggregationTypeRt } from '../../common/latency_aggregation_types'; import { ProfilingValueType } from '../../common/profiling'; -import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../lib/helpers/transactions'; import { setupRequest } from '../lib/helpers/setup_request'; import { getServiceAnnotations } from '../lib/services/annotations'; import { getServices } from '../lib/services/get_services'; diff --git a/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts b/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts index a904e5e03b5310..0488d0ebd01bdb 100644 --- a/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts +++ b/x-pack/plugins/apm/server/routes/settings/agent_configuration.ts @@ -24,7 +24,7 @@ import { serviceRt, agentConfigurationIntakeRt, } from '../../../common/agent_configuration/runtime_types/agent_configuration_intake_rt'; -import { getSearchAggregatedTransactions } from '../../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../../lib/helpers/transactions'; import { createApmServerRouteRepository } from '../create_apm_server_route_repository'; import { syncAgentConfigsToApmPackagePolicies } from '../../lib/fleet/sync_agent_configs_to_apm_package_policies'; diff --git a/x-pack/plugins/apm/server/routes/settings/anomaly_detection.ts b/x-pack/plugins/apm/server/routes/settings/anomaly_detection.ts index 78db4e0c14b36f..f614f35810c57b 100644 --- a/x-pack/plugins/apm/server/routes/settings/anomaly_detection.ts +++ b/x-pack/plugins/apm/server/routes/settings/anomaly_detection.ts @@ -16,7 +16,7 @@ import { createAnomalyDetectionJobs } from '../../lib/anomaly_detection/create_a import { setupRequest } from '../../lib/helpers/setup_request'; import { getAllEnvironments } from '../../lib/environments/get_all_environments'; import { hasLegacyJobs } from '../../lib/anomaly_detection/has_legacy_jobs'; -import { getSearchAggregatedTransactions } from '../../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../../lib/helpers/transactions'; import { notifyFeatureUsage } from '../../feature'; import { withApmSpan } from '../../utils/with_apm_span'; import { createApmServerRouteRepository } from '../create_apm_server_route_repository'; diff --git a/x-pack/plugins/apm/server/routes/suggestions.ts b/x-pack/plugins/apm/server/routes/suggestions.ts index 8b82601650a481..4834d894f364ac 100644 --- a/x-pack/plugins/apm/server/routes/suggestions.ts +++ b/x-pack/plugins/apm/server/routes/suggestions.ts @@ -8,7 +8,7 @@ import * as t from 'io-ts'; import { maxSuggestions } from '../../../observability/common'; import { getSuggestions } from '../lib/suggestions/get_suggestions'; -import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../lib/helpers/transactions'; import { setupRequest } from '../lib/helpers/setup_request'; import { createApmServerRoute } from './create_apm_server_route'; import { createApmServerRouteRepository } from './create_apm_server_route_repository'; diff --git a/x-pack/plugins/apm/server/routes/traces.ts b/x-pack/plugins/apm/server/routes/traces.ts index a71b7eefeed3fe..cc800c348b165b 100644 --- a/x-pack/plugins/apm/server/routes/traces.ts +++ b/x-pack/plugins/apm/server/routes/traces.ts @@ -11,7 +11,7 @@ import { getTraceItems } from '../lib/traces/get_trace_items'; import { getTopTransactionGroupList } from '../lib/transaction_groups'; import { createApmServerRoute } from './create_apm_server_route'; import { environmentRt, kueryRt, rangeRt } from './default_api_types'; -import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../lib/helpers/transactions'; import { getRootTransactionByTraceId } from '../lib/transactions/get_transaction_by_trace'; import { createApmServerRouteRepository } from './create_apm_server_route_repository'; import { getTransaction } from '../lib/transactions/get_transaction'; diff --git a/x-pack/plugins/apm/server/routes/transactions.ts b/x-pack/plugins/apm/server/routes/transactions.ts index 0e24d64d8c6c7f..56b7ead2254d3a 100644 --- a/x-pack/plugins/apm/server/routes/transactions.ts +++ b/x-pack/plugins/apm/server/routes/transactions.ts @@ -11,7 +11,7 @@ import { LatencyAggregationType, latencyAggregationTypeRt, } from '../../common/latency_aggregation_types'; -import { getSearchAggregatedTransactions } from '../lib/helpers/aggregated_transactions'; +import { getSearchAggregatedTransactions } from '../lib/helpers/transactions'; import { setupRequest } from '../lib/helpers/setup_request'; import { getServiceTransactionGroups } from '../lib/services/get_service_transaction_groups'; import { getServiceTransactionGroupDetailedStatisticsPeriods } from '../lib/services/get_service_transaction_group_detailed_statistics'; From e956964c06d693dfb0deeb872342d0ae1808822d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ester=20Mart=C3=AD=20Vilaseca?= Date: Tue, 26 Oct 2021 08:26:48 +0200 Subject: [PATCH 54/66] Add page title to index advanced page (#116134) --- .../pages/elasticsearch/index_advanced_page.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx index c51027636b287c..1982b7de87cae9 100644 --- a/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/elasticsearch/index_advanced_page.tsx @@ -87,7 +87,13 @@ export const ElasticsearchIndexAdvancedPage: React.FC = ({ clust }, [clusterUuid, services.data?.query.timefilter.timefilter, services.http, index]); return ( - + ( From 27866cec6ea512d592f046973960dbb0f9fc7019 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 26 Oct 2021 07:41:01 +0100 Subject: [PATCH 55/66] [ML] Adding datafeed api tests (#116133) * [ML] Adding datafeed api tests * updating tests * adding more AD tests * adding test include * renaming function --- .../get_stats_with_spaces.ts | 174 ++++++++++++++++++ .../ml/anomaly_detectors/get_with_spaces.ts | 68 ++++++- .../apis/ml/anomaly_detectors/index.ts | 1 + .../ml/datafeeds/get_stats_with_spaces.ts | 121 ++++++++++++ .../apis/ml/datafeeds/get_with_spaces.ts | 119 ++++++++++++ .../apis/ml/datafeeds/index.ts | 15 ++ x-pack/test/api_integration/apis/ml/index.ts | 1 + 7 files changed, 489 insertions(+), 10 deletions(-) create mode 100644 x-pack/test/api_integration/apis/ml/anomaly_detectors/get_stats_with_spaces.ts create mode 100644 x-pack/test/api_integration/apis/ml/datafeeds/get_stats_with_spaces.ts create mode 100644 x-pack/test/api_integration/apis/ml/datafeeds/get_with_spaces.ts create mode 100644 x-pack/test/api_integration/apis/ml/datafeeds/index.ts diff --git a/x-pack/test/api_integration/apis/ml/anomaly_detectors/get_stats_with_spaces.ts b/x-pack/test/api_integration/apis/ml/anomaly_detectors/get_stats_with_spaces.ts new file mode 100644 index 00000000000000..d15b1ab60f9ffc --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/anomaly_detectors/get_stats_with_spaces.ts @@ -0,0 +1,174 @@ +/* + * 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 expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { USER } from '../../../../functional/services/ml/security_common'; +import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; + +export default ({ getService }: FtrProviderContext) => { + const ml = getService('ml'); + const spacesService = getService('spaces'); + const supertest = getService('supertestWithoutAuth'); + + const jobIdSpace1 = 'fq_single_space1'; + const jobIdWildcardSpace1 = 'fq_single_space1*'; + const jobGroupSpace1 = 'space1_group'; + const jobGroupWildcardSpace1 = 'space1_group*'; + const idSpace1 = 'space1'; + const idSpace2 = 'space2'; + + async function getJobStatsById( + jobOrGroup: string | undefined, + expectedStatusCode: number, + space?: string + ) { + const { body } = await supertest + .get( + `${space ? `/s/${space}` : ''}/api/ml/anomaly_detectors${ + jobOrGroup ? `/${jobOrGroup}` : '' + }/_stats` + ) + .auth( + USER.ML_VIEWER_ALL_SPACES, + ml.securityCommon.getPasswordForUser(USER.ML_VIEWER_ALL_SPACES) + ) + .set(COMMON_REQUEST_HEADERS) + .expect(expectedStatusCode); + + return body; + } + + describe('GET anomaly_detectors stats with spaces', () => { + before(async () => { + await spacesService.create({ id: idSpace1, name: 'space_one', disabledFeatures: [] }); + await spacesService.create({ id: idSpace2, name: 'space_two', disabledFeatures: [] }); + + const jobConfig = ml.commonConfig.getADFqSingleMetricJobConfig(jobIdSpace1); + await ml.api.createAnomalyDetectionJob({ ...jobConfig, groups: [jobGroupSpace1] }, idSpace1); + + await ml.testResources.setKibanaTimeZoneToUTC(); + }); + + after(async () => { + await spacesService.delete(idSpace1); + await spacesService.delete(idSpace2); + await ml.api.cleanMlIndices(); + await ml.testResources.cleanMLSavedObjects(); + }); + + it('should fail with non-existing job', async () => { + await getJobStatsById('non-existing-job', 404); + }); + + it('should return empty list with non-existing job wildcard', async () => { + const body = await getJobStatsById('non-existing-job*', 200); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 0, + `response job stats list should be empty (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should fail with job from different space', async () => { + await getJobStatsById(jobIdSpace1, 404, idSpace2); + }); + + it('should return all job stats when not specifying id', async () => { + const body = await getJobStatsById(undefined, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 1, + `response job stats list should contain correct job (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return empty list when not specifying id in difference space', async () => { + const body = await getJobStatsById(undefined, 200, idSpace2); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 0, + `response job stats list should be empty (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return job stats with job id from correct space', async () => { + const body = await getJobStatsById(jobIdSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 1, + `response job stats list should contain correct job (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return job stats with job wildcard from correct space', async () => { + const body = await getJobStatsById(jobIdWildcardSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 1, + `response job stats list should contain correct job (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return empty list with job wildcard from different space', async () => { + const body = await getJobStatsById(jobIdWildcardSpace1, 200, idSpace2); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 0, + `response job stats list should be empty (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return job stats by group from same space', async () => { + const body = await getJobStatsById(jobGroupSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 1, + `response job stats list should have one element (got ${JSON.stringify(body.jobs)})` + ); + expect(body.jobs[0].job_id).to.eql( + jobIdSpace1, + `response job id should be ${jobIdSpace1} (got ${body.jobs[0].job_id})` + ); + }); + + it('should return job stats by group wildcard from same space', async () => { + const body = await getJobStatsById(jobGroupWildcardSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 1, + `response job stats list should have one element (got ${JSON.stringify(body.jobs)})` + ); + expect(body.jobs[0].job_id).to.eql( + jobIdSpace1, + `response job id should be ${jobIdSpace1} (got ${body.jobs[0].job_id})` + ); + }); + + it('should fail with group from different space', async () => { + await getJobStatsById(jobGroupSpace1, 404, idSpace2); + }); + + it('should return empty list with group wildcard from different space', async () => { + const body = await getJobStatsById(jobGroupWildcardSpace1, 200, idSpace2); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 0, + `response job stats list should be empty (got ${JSON.stringify(body.jobs)})` + ); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/anomaly_detectors/get_with_spaces.ts b/x-pack/test/api_integration/apis/ml/anomaly_detectors/get_with_spaces.ts index 5392b0ef44c8ae..2bebea5e63ea16 100644 --- a/x-pack/test/api_integration/apis/ml/anomaly_detectors/get_with_spaces.ts +++ b/x-pack/test/api_integration/apis/ml/anomaly_detectors/get_with_spaces.ts @@ -22,9 +22,17 @@ export default ({ getService }: FtrProviderContext) => { const idSpace1 = 'space1'; const idSpace2 = 'space2'; - async function runRequest(jobOrGroup: string, expectedStatusCode: number, space?: string) { + async function getJobById( + jobOrGroup: string | undefined, + expectedStatusCode: number, + space?: string + ) { const { body } = await supertest - .get(`${space ? `/s/${space}` : ''}/api/ml/anomaly_detectors/${jobOrGroup}`) + .get( + `${space ? `/s/${space}` : ''}/api/ml/anomaly_detectors${ + jobOrGroup ? `/${jobOrGroup}` : '' + }` + ) .auth( USER.ML_VIEWER_ALL_SPACES, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER_ALL_SPACES) @@ -54,11 +62,11 @@ export default ({ getService }: FtrProviderContext) => { }); it('should fail with non-existing job', async () => { - await runRequest('non-existing-job', 404); + await getJobById('non-existing-job', 404); }); it('should return empty list with non-existing job wildcard', async () => { - const body = await runRequest('non-existing-job*', 200); + const body = await getJobById('non-existing-job*', 200); expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); expect(body.jobs.length).to.eql( @@ -68,11 +76,51 @@ export default ({ getService }: FtrProviderContext) => { }); it('should fail with job from different space', async () => { - await runRequest(jobIdSpace1, 404, idSpace2); + await getJobById(jobIdSpace1, 404, idSpace2); + }); + + it('should return all jobs when not specifying id', async () => { + const body = await getJobById(undefined, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 1, + `response jobs list should contain correct job (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return empty list when not specifying id in difference space', async () => { + const body = await getJobById(undefined, 200, idSpace2); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 0, + `response jobs list should be empty (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return job with job id from correct space', async () => { + const body = await getJobById(jobIdSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 1, + `response jobs list should contain correct job (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return job with job wildcard from correct space', async () => { + const body = await getJobById(jobIdWildcardSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.jobs.length).to.eql( + 1, + `response jobs list should contain correct job (got ${JSON.stringify(body.jobs)})` + ); }); it('should return empty list with job wildcard from different space', async () => { - const body = await runRequest(jobIdWildcardSpace1, 200, idSpace2); + const body = await getJobById(jobIdWildcardSpace1, 200, idSpace2); expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); expect(body.jobs.length).to.eql( @@ -82,7 +130,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should return job by group from same space', async () => { - const body = await runRequest(jobGroupSpace1, 200, idSpace1); + const body = await getJobById(jobGroupSpace1, 200, idSpace1); expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); expect(body.jobs.length).to.eql( @@ -96,7 +144,7 @@ export default ({ getService }: FtrProviderContext) => { }); it('should return job by group wildcard from same space', async () => { - const body = await runRequest(jobGroupWildcardSpace1, 200, idSpace1); + const body = await getJobById(jobGroupWildcardSpace1, 200, idSpace1); expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); expect(body.jobs.length).to.eql( @@ -110,11 +158,11 @@ export default ({ getService }: FtrProviderContext) => { }); it('should fail with group from different space', async () => { - await runRequest(jobGroupSpace1, 404, idSpace2); + await getJobById(jobGroupSpace1, 404, idSpace2); }); it('should return empty list with group wildcard from different space', async () => { - const body = await runRequest(jobGroupWildcardSpace1, 200, idSpace2); + const body = await getJobById(jobGroupWildcardSpace1, 200, idSpace2); expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); expect(body.jobs.length).to.eql( diff --git a/x-pack/test/api_integration/apis/ml/anomaly_detectors/index.ts b/x-pack/test/api_integration/apis/ml/anomaly_detectors/index.ts index 86649ece225519..101273405f121f 100644 --- a/x-pack/test/api_integration/apis/ml/anomaly_detectors/index.ts +++ b/x-pack/test/api_integration/apis/ml/anomaly_detectors/index.ts @@ -12,6 +12,7 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./create')); loadTestFile(require.resolve('./get')); loadTestFile(require.resolve('./get_with_spaces')); + loadTestFile(require.resolve('./get_stats_with_spaces')); loadTestFile(require.resolve('./open_with_spaces')); loadTestFile(require.resolve('./close_with_spaces')); loadTestFile(require.resolve('./delete_with_spaces')); diff --git a/x-pack/test/api_integration/apis/ml/datafeeds/get_stats_with_spaces.ts b/x-pack/test/api_integration/apis/ml/datafeeds/get_stats_with_spaces.ts new file mode 100644 index 00000000000000..aaa60aabdfbd04 --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/datafeeds/get_stats_with_spaces.ts @@ -0,0 +1,121 @@ +/* + * 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 expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { USER } from '../../../../functional/services/ml/security_common'; +import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; + +export default ({ getService }: FtrProviderContext) => { + const ml = getService('ml'); + const spacesService = getService('spaces'); + const supertest = getService('supertestWithoutAuth'); + + const jobIdSpace1 = 'fq_single_space1'; + const datafeedIdSpace1 = `datafeed-${jobIdSpace1}`; + const datafeedIdWildcardSpace1 = `datafeed-${jobIdSpace1}*`; + const idSpace1 = 'space1'; + const idSpace2 = 'space2'; + + async function getDatafeedStatsById( + datafeedId: string | undefined, + expectedStatusCode: number, + space?: string + ) { + const { body } = await supertest + .get( + `${space ? `/s/${space}` : ''}/api/ml/datafeeds${datafeedId ? `/${datafeedId}` : ''}/_stats` + ) + .auth( + USER.ML_VIEWER_ALL_SPACES, + ml.securityCommon.getPasswordForUser(USER.ML_VIEWER_ALL_SPACES) + ) + .set(COMMON_REQUEST_HEADERS) + .expect(expectedStatusCode); + + return body; + } + + describe('GET datafeed stats with spaces', () => { + before(async () => { + await spacesService.create({ id: idSpace1, name: 'space_one', disabledFeatures: [] }); + await spacesService.create({ id: idSpace2, name: 'space_two', disabledFeatures: [] }); + + const jobConfig = ml.commonConfig.getADFqSingleMetricJobConfig(jobIdSpace1); + await ml.api.createAnomalyDetectionJob(jobConfig, idSpace1); + const datafeedConfig = ml.commonConfig.getADFqDatafeedConfig(jobIdSpace1); + await ml.api.createDatafeed(datafeedConfig, idSpace1); + + await ml.testResources.setKibanaTimeZoneToUTC(); + }); + + after(async () => { + await spacesService.delete(idSpace1); + await spacesService.delete(idSpace2); + await ml.api.cleanMlIndices(); + await ml.testResources.cleanMLSavedObjects(); + }); + + it('should fail with non-existing datafeed', async () => { + await getDatafeedStatsById('non-existing-datafeed', 404); + }); + + it('should return datafeed stats with datafeed id from correct space', async () => { + const body = await getDatafeedStatsById(datafeedIdSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 1, + `response datafeeds list should contain correct datafeed (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return datafeed stats with datafeed wildcard from correct space', async () => { + const body = await getDatafeedStatsById(datafeedIdWildcardSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 1, + `response datafeeds list should contain correct datafeed (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return all datafeed stats when not specifying id', async () => { + const body = await getDatafeedStatsById(undefined, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 1, + `response datafeeds list should contain correct datafeed (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return empty list with non-existing datafeed wildcard', async () => { + const body = await getDatafeedStatsById('non-existing-datafeed*', 200); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 0, + `response datafeed list should be empty (got ${JSON.stringify(body.datafeeds)})` + ); + }); + + it('should fail with datafeed from different space', async () => { + await getDatafeedStatsById(datafeedIdSpace1, 404, idSpace2); + }); + + it('should return empty list with datafeed wildcard from different space', async () => { + const body = await getDatafeedStatsById(datafeedIdWildcardSpace1, 200, idSpace2); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 0, + `response datafeed list should be empty (got ${JSON.stringify(body.datafeeds)})` + ); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/datafeeds/get_with_spaces.ts b/x-pack/test/api_integration/apis/ml/datafeeds/get_with_spaces.ts new file mode 100644 index 00000000000000..a1b045832789ec --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/datafeeds/get_with_spaces.ts @@ -0,0 +1,119 @@ +/* + * 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 expect from '@kbn/expect'; +import { FtrProviderContext } from '../../../ftr_provider_context'; +import { USER } from '../../../../functional/services/ml/security_common'; +import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; + +export default ({ getService }: FtrProviderContext) => { + const ml = getService('ml'); + const spacesService = getService('spaces'); + const supertest = getService('supertestWithoutAuth'); + + const jobIdSpace1 = 'fq_single_space1'; + const datafeedIdSpace1 = `datafeed-${jobIdSpace1}`; + const datafeedIdWildcardSpace1 = `datafeed-${jobIdSpace1}*`; + const idSpace1 = 'space1'; + const idSpace2 = 'space2'; + + async function getDatafeedById( + datafeedId: string | undefined, + expectedStatusCode: number, + space?: string + ) { + const { body } = await supertest + .get(`${space ? `/s/${space}` : ''}/api/ml/datafeeds${datafeedId ? `/${datafeedId}` : ''}`) + .auth( + USER.ML_VIEWER_ALL_SPACES, + ml.securityCommon.getPasswordForUser(USER.ML_VIEWER_ALL_SPACES) + ) + .set(COMMON_REQUEST_HEADERS) + .expect(expectedStatusCode); + + return body; + } + + describe('GET datafeeds with spaces', () => { + before(async () => { + await spacesService.create({ id: idSpace1, name: 'space_one', disabledFeatures: [] }); + await spacesService.create({ id: idSpace2, name: 'space_two', disabledFeatures: [] }); + + const jobConfig = ml.commonConfig.getADFqSingleMetricJobConfig(jobIdSpace1); + await ml.api.createAnomalyDetectionJob(jobConfig, idSpace1); + const datafeedConfig = ml.commonConfig.getADFqDatafeedConfig(jobIdSpace1); + await ml.api.createDatafeed(datafeedConfig, idSpace1); + + await ml.testResources.setKibanaTimeZoneToUTC(); + }); + + after(async () => { + await spacesService.delete(idSpace1); + await spacesService.delete(idSpace2); + await ml.api.cleanMlIndices(); + await ml.testResources.cleanMLSavedObjects(); + }); + + it('should fail with non-existing datafeed', async () => { + await getDatafeedById('non-existing-datafeed', 404); + }); + + it('should return datafeed with datafeed id from correct space', async () => { + const body = await getDatafeedById(datafeedIdSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 1, + `response datafeeds list should contain correct datafeed (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return datafeed with datafeed wildcard from correct space', async () => { + const body = await getDatafeedById(datafeedIdWildcardSpace1, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 1, + `response datafeeds list should contain correct datafeed (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return all datafeeds when not specifying id', async () => { + const body = await getDatafeedById(undefined, 200, idSpace1); + + expect(body.count).to.eql(1, `response count should be 1 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 1, + `response datafeeds list should contain correct datafeed (got ${JSON.stringify(body.jobs)})` + ); + }); + + it('should return empty list with non-existing datafeed wildcard', async () => { + const body = await getDatafeedById('non-existing-datafeed*', 200); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 0, + `response datafeed list should be empty (got ${JSON.stringify(body.datafeeds)})` + ); + }); + + it('should fail with datafeed from different space', async () => { + await getDatafeedById(datafeedIdSpace1, 404, idSpace2); + }); + + it('should return empty list with datafeed wildcard from different space', async () => { + const body = await getDatafeedById(datafeedIdWildcardSpace1, 200, idSpace2); + + expect(body.count).to.eql(0, `response count should be 0 (got ${body.count})`); + expect(body.datafeeds.length).to.eql( + 0, + `response datafeed list should be empty (got ${JSON.stringify(body.datafeeds)})` + ); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/datafeeds/index.ts b/x-pack/test/api_integration/apis/ml/datafeeds/index.ts new file mode 100644 index 00000000000000..4e92c9969a8f4f --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/datafeeds/index.ts @@ -0,0 +1,15 @@ +/* + * 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 { FtrProviderContext } from '../../../ftr_provider_context'; + +export default function ({ loadTestFile }: FtrProviderContext) { + describe('anomaly detectors', function () { + loadTestFile(require.resolve('./get_with_spaces')); + loadTestFile(require.resolve('./get_stats_with_spaces')); + }); +} diff --git a/x-pack/test/api_integration/apis/ml/index.ts b/x-pack/test/api_integration/apis/ml/index.ts index 9b530873ad165d..06910e8fac67e8 100644 --- a/x-pack/test/api_integration/apis/ml/index.ts +++ b/x-pack/test/api_integration/apis/ml/index.ts @@ -72,6 +72,7 @@ export default function ({ getService, loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./annotations')); loadTestFile(require.resolve('./anomaly_detectors')); loadTestFile(require.resolve('./calendars')); + loadTestFile(require.resolve('./datafeeds')); loadTestFile(require.resolve('./data_frame_analytics')); loadTestFile(require.resolve('./data_visualizer')); loadTestFile(require.resolve('./fields_service')); From 9c3c489e481c5fe9992584a3a1db2e37ce8f3bf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20S=C3=A1nchez?= Date: Tue, 26 Oct 2021 09:21:58 +0200 Subject: [PATCH 56/66] Hide or button if needed (#116124) --- .../builder/exception_items_renderer.tsx | 3 ++ .../components/builder/logic_buttons.test.tsx | 19 +++++++++++++ .../components/builder/logic_buttons.tsx | 28 +++++++++++-------- .../view/components/form/index.tsx | 3 +- 4 files changed, 40 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx index 1b25a2cb91e85b..280dd8acbc7e55 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/exception_items_renderer.tsx @@ -81,6 +81,7 @@ export interface ExceptionBuilderProps { isAndDisabled: boolean; isNestedDisabled: boolean; isOrDisabled: boolean; + isOrHidden?: boolean; listId: string; listNamespaceType: NamespaceType; listType: ExceptionListType; @@ -103,6 +104,7 @@ export const ExceptionBuilderComponent = ({ isAndDisabled, isNestedDisabled, isOrDisabled, + isOrHidden = false, listId, listNamespaceType, listType, @@ -433,6 +435,7 @@ export const ExceptionBuilderComponent = ({ { expect(wrapper.find('[data-test-subj="exceptionsNestedButton"] button')).toHaveLength(0); }); + test('it hides "or" button', () => { + const wrapper = mount( + + ); + + expect(wrapper.find('[data-test-subj="exceptionsOrButton"] button')).toHaveLength(0); + }); + test('it invokes "onOrClicked" when "or" button is clicked', () => { const onOrClicked = jest.fn(); diff --git a/x-pack/plugins/lists/public/exceptions/components/builder/logic_buttons.tsx b/x-pack/plugins/lists/public/exceptions/components/builder/logic_buttons.tsx index 3846b844bb55a6..aa308ecdc3452d 100644 --- a/x-pack/plugins/lists/public/exceptions/components/builder/logic_buttons.tsx +++ b/x-pack/plugins/lists/public/exceptions/components/builder/logic_buttons.tsx @@ -20,6 +20,7 @@ interface BuilderLogicButtonsProps { isNested: boolean; isNestedDisabled: boolean; isOrDisabled: boolean; + isOrHidden?: boolean; showNestedButton: boolean; onAddClickWhenNested: () => void; onAndClicked: () => void; @@ -32,6 +33,7 @@ export const BuilderLogicButtons: React.FC = ({ isNested, isNestedDisabled = true, isOrDisabled = false, + isOrHidden = false, showNestedButton = false, onAddClickWhenNested, onAndClicked, @@ -50,18 +52,20 @@ export const BuilderLogicButtons: React.FC = ({ {i18n.AND} - - - {i18n.OR} - - + {!isOrHidden && ( + + + {i18n.OR} + + + )} {showNestedButton && ( = memo( listNamespaceType: 'agnostic', ruleName: RULE_NAME, indexPatterns, - isOrDisabled: true, // TODO: pending to be validated + isOrDisabled: true, + isOrHidden: true, isAndDisabled: false, isNestedDisabled: false, dataTestSubj: 'alert-exception-builder', From 669e0a1555257ee31da2f44b020e6efcac88ed92 Mon Sep 17 00:00:00 2001 From: Thom Heymann <190132+thomheymann@users.noreply.github.com> Date: Tue, 26 Oct 2021 08:34:13 +0100 Subject: [PATCH 57/66] Add not ready response to interactive setup (#116138) --- src/plugins/interactive_setup/common/index.ts | 2 +- src/plugins/interactive_setup/common/types.ts | 22 ++++--- src/plugins/interactive_setup/public/app.tsx | 23 +++++++ .../public/enrollment_token_form.test.tsx | 14 +++++ .../public/enrollment_token_form.tsx | 14 +++++ .../interactive_setup/server/routes/index.ts | 2 + .../server/routes/status.test.ts | 62 +++++++++++++++++++ .../interactive_setup/server/routes/status.ts | 33 ++++++++++ 8 files changed, 161 insertions(+), 11 deletions(-) create mode 100644 src/plugins/interactive_setup/server/routes/status.test.ts create mode 100644 src/plugins/interactive_setup/server/routes/status.ts diff --git a/src/plugins/interactive_setup/common/index.ts b/src/plugins/interactive_setup/common/index.ts index 0ba439eeb76162..352c95c73aee62 100644 --- a/src/plugins/interactive_setup/common/index.ts +++ b/src/plugins/interactive_setup/common/index.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -export type { InteractiveSetupViewState, EnrollmentToken, Certificate, PingResult } from './types'; +export type { EnrollmentToken, Certificate, PingResult, StatusResult } from './types'; export { ElasticsearchConnectionStatus } from './elasticsearch_connection_status'; export { ERROR_CONFIGURE_FAILURE, diff --git a/src/plugins/interactive_setup/common/types.ts b/src/plugins/interactive_setup/common/types.ts index de3f54dbf9a28a..4f30faf19a3d34 100644 --- a/src/plugins/interactive_setup/common/types.ts +++ b/src/plugins/interactive_setup/common/types.ts @@ -10,16 +10,6 @@ import type { PeerCertificate } from 'tls'; import type { ElasticsearchConnectionStatus } from './elasticsearch_connection_status'; -/** - * A set of state details that interactive setup view retrieves from the Kibana server. - */ -export interface InteractiveSetupViewState { - /** - * Current status of the Elasticsearch connection. - */ - elasticsearchConnectionStatus: ElasticsearchConnectionStatus; -} - /** * The token that allows one to configure Kibana instance to communicate with an existing Elasticsearch cluster that * has security features enabled. @@ -66,3 +56,15 @@ export interface PingResult { */ certificateChain?: Certificate[]; } + +export interface StatusResult { + /** + * Full certificate chain of cluster at requested address. Only present if cluster uses HTTPS. + */ + connectionStatus: ElasticsearchConnectionStatus; + + /** + * Indicates whether Kibana is currently on hold and cannot proceed to `setup` yet. + */ + isSetupOnHold: boolean; +} diff --git a/src/plugins/interactive_setup/public/app.tsx b/src/plugins/interactive_setup/public/app.tsx index 0f1c1b04d7c90a..89218df4208bc3 100644 --- a/src/plugins/interactive_setup/public/app.tsx +++ b/src/plugins/interactive_setup/public/app.tsx @@ -11,14 +11,17 @@ import './app.scss'; import { EuiIcon, EuiPanel, EuiSpacer, EuiTitle } from '@elastic/eui'; import type { FunctionComponent } from 'react'; import React, { useState } from 'react'; +import useAsync from 'react-use/lib/useAsync'; import { FormattedMessage } from '@kbn/i18n/react'; +import type { StatusResult } from '../common'; import { ClusterAddressForm } from './cluster_address_form'; import type { ClusterConfigurationFormProps } from './cluster_configuration_form'; import { ClusterConfigurationForm } from './cluster_configuration_form'; import { EnrollmentTokenForm } from './enrollment_token_form'; import { ProgressIndicator } from './progress_indicator'; +import { useKibana } from './use_kibana'; export interface AppProps { onSuccess?(): void; @@ -28,6 +31,26 @@ export const App: FunctionComponent = ({ onSuccess }) => { const [page, setPage] = useState<'token' | 'manual' | 'success'>('token'); const [cluster, setCluster] = useState>(); + const { http } = useKibana(); + const state = useAsync( + () => http.get('/internal/interactive_setup/status'), + [http] + ); + + if (state.loading) { + return null; + } + + if (!state.value || state.value.connectionStatus === 'configured' || !state.value.isSetupOnHold) { + return ( +
+        
+      
+ ); + } return (
diff --git a/src/plugins/interactive_setup/public/enrollment_token_form.test.tsx b/src/plugins/interactive_setup/public/enrollment_token_form.test.tsx index a6a18984ddd948..30983c68e1cf9b 100644 --- a/src/plugins/interactive_setup/public/enrollment_token_form.test.tsx +++ b/src/plugins/interactive_setup/public/enrollment_token_form.test.tsx @@ -89,6 +89,20 @@ describe('decodeEnrollmentToken', () => { }); }); + it('should sort IPv4 before IPv6 addresses', () => { + expect( + decodeEnrollmentToken( + btoa( + JSON.stringify({ ...token, adr: ['[::1]:9200', '127.0.0.1:9200', '10.17.1.163:9200'] }) + ) + ) + ).toEqual( + expect.objectContaining({ + adr: ['https://127.0.0.1:9200', 'https://10.17.1.163:9200', 'https://[::1]:9200'], + }) + ); + }); + it('should not decode an invalid token', () => { expect(decodeEnrollmentToken(JSON.stringify(token))).toBeUndefined(); expect( diff --git a/src/plugins/interactive_setup/public/enrollment_token_form.tsx b/src/plugins/interactive_setup/public/enrollment_token_form.tsx index 4b692ed4efcc88..e5a3aca8fd4e24 100644 --- a/src/plugins/interactive_setup/public/enrollment_token_form.tsx +++ b/src/plugins/interactive_setup/public/enrollment_token_form.tsx @@ -205,6 +205,7 @@ export function decodeEnrollmentToken(enrollmentToken: string): EnrollmentToken ) { return; } + json.adr.sort(compareAddresses); return { ...json, adr: json.adr.map((host) => `https://${host}`), @@ -212,3 +213,16 @@ export function decodeEnrollmentToken(enrollmentToken: string): EnrollmentToken }; } catch (error) {} // eslint-disable-line no-empty } + +/** + * Compares two Elasticsearch addresses. Sorts IPv4 addresses before IPv6 addresses. + */ +export function compareAddresses(a: string, b: string) { + if (a.indexOf('[') === -1 && b.indexOf('[') !== -1) { + return -1; + } + if (a.indexOf('[') !== -1 && b.indexOf('[') === -1) { + return 1; + } + return 0; +} diff --git a/src/plugins/interactive_setup/server/routes/index.ts b/src/plugins/interactive_setup/server/routes/index.ts index fb9e06c4c2a18d..f1f6b34fb689c4 100644 --- a/src/plugins/interactive_setup/server/routes/index.ts +++ b/src/plugins/interactive_setup/server/routes/index.ts @@ -16,6 +16,7 @@ import type { VerificationCode } from '../verification_code'; import { defineConfigureRoute } from './configure'; import { defineEnrollRoutes } from './enroll'; import { definePingRoute } from './ping'; +import { defineStatusRoute } from './status'; import { defineVerifyRoute } from './verify'; /** @@ -39,4 +40,5 @@ export function defineRoutes(params: RouteDefinitionParams) { defineEnrollRoutes(params); definePingRoute(params); defineVerifyRoute(params); + defineStatusRoute(params); } diff --git a/src/plugins/interactive_setup/server/routes/status.test.ts b/src/plugins/interactive_setup/server/routes/status.test.ts new file mode 100644 index 00000000000000..b40c765a8a53a9 --- /dev/null +++ b/src/plugins/interactive_setup/server/routes/status.test.ts @@ -0,0 +1,62 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { IRouter, RequestHandler, RequestHandlerContext } from 'src/core/server'; +import { kibanaResponseFactory } from 'src/core/server'; +import { httpServerMock } from 'src/core/server/mocks'; + +import { routeDefinitionParamsMock } from './index.mock'; +import { defineStatusRoute } from './status'; + +describe('Status routes', () => { + let router: jest.Mocked; + let mockRouteParams: ReturnType; + let mockContext: RequestHandlerContext; + beforeEach(() => { + mockRouteParams = routeDefinitionParamsMock.create(); + mockRouteParams.preboot.isSetupOnHold.mockReturnValue(false); + router = mockRouteParams.router; + + mockContext = {} as unknown as RequestHandlerContext; + + defineStatusRoute(mockRouteParams); + }); + + describe('#status', () => { + let routeHandler: RequestHandler; + + beforeEach(() => { + const [, statusRouteHandler] = router.get.mock.calls.find( + ([{ path }]) => path === '/internal/interactive_setup/status' + )!; + + routeHandler = statusRouteHandler; + }); + + it('should return connection status', async () => { + const mockRequest = httpServerMock.createKibanaRequest(); + + await expect(routeHandler(mockContext, mockRequest, kibanaResponseFactory)).resolves + .toMatchInlineSnapshot(` + KibanaResponse { + "options": Object { + "body": Object { + "connectionStatus": "configured", + "isSetupOnHold": false, + }, + }, + "payload": Object { + "connectionStatus": "configured", + "isSetupOnHold": false, + }, + "status": 200, + } + `); + }); + }); +}); diff --git a/src/plugins/interactive_setup/server/routes/status.ts b/src/plugins/interactive_setup/server/routes/status.ts new file mode 100644 index 00000000000000..51b98732853efe --- /dev/null +++ b/src/plugins/interactive_setup/server/routes/status.ts @@ -0,0 +1,33 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { first } from 'rxjs/operators'; + +import type { RouteDefinitionParams } from '.'; + +export function defineStatusRoute({ router, elasticsearch, preboot }: RouteDefinitionParams) { + router.get( + { + path: '/internal/interactive_setup/status', + validate: false, + options: { authRequired: false }, + }, + async (context, request, response) => { + // `connectionStatus$` is a `ReplaySubject` with a buffer size of 1 so `first()` operator will + // always return the most recently emitted value. We can't use `connectionStatus$.toPromise()` + // directly since the stream hasn't ended so it would never resolve. + const connectionStatus = await elasticsearch.connectionStatus$.pipe(first()).toPromise(); + return response.ok({ + body: { + connectionStatus, + isSetupOnHold: preboot.isSetupOnHold(), + }, + }); + } + ); +} From 79c43fbfff751341a4dfdc7f3ad1c5076102ed30 Mon Sep 17 00:00:00 2001 From: Thom Heymann <190132+thomheymann@users.noreply.github.com> Date: Tue, 26 Oct 2021 08:34:57 +0100 Subject: [PATCH 58/66] Enable interactive setup by default (#116141) --- src/plugins/interactive_setup/server/config.test.ts | 4 ++-- src/plugins/interactive_setup/server/config.ts | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/plugins/interactive_setup/server/config.test.ts b/src/plugins/interactive_setup/server/config.test.ts index b8ae673ad28f91..50e47735ad3c84 100644 --- a/src/plugins/interactive_setup/server/config.test.ts +++ b/src/plugins/interactive_setup/server/config.test.ts @@ -15,7 +15,7 @@ describe('config schema', () => { "connectionCheck": Object { "interval": "PT5S", }, - "enabled": false, + "enabled": true, } `); }); @@ -27,7 +27,7 @@ describe('config schema', () => { "connectionCheck": Object { "interval": "PT1S", }, - "enabled": false, + "enabled": true, } `); }); diff --git a/src/plugins/interactive_setup/server/config.ts b/src/plugins/interactive_setup/server/config.ts index 9986f16e9ce933..1b1a9525e35279 100644 --- a/src/plugins/interactive_setup/server/config.ts +++ b/src/plugins/interactive_setup/server/config.ts @@ -12,7 +12,7 @@ import { schema } from '@kbn/config-schema'; export type ConfigType = TypeOf; export const ConfigSchema = schema.object({ - enabled: schema.boolean({ defaultValue: false }), + enabled: schema.boolean({ defaultValue: true }), connectionCheck: schema.object({ interval: schema.duration({ defaultValue: '5s', From 30c72111ae2ce1da0d58dbd37aa000af639671a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?David=20S=C3=A1nchez?= Date: Tue, 26 Oct 2021 09:43:58 +0200 Subject: [PATCH 59/66] Set required to false until the input is not visited (#116099) --- .../view/components/condition_entry_input/index.tsx | 10 +++++++--- .../view/components/create_trusted_app_form.test.tsx | 12 ++++++++++-- .../view/components/create_trusted_app_form.tsx | 2 +- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/condition_entry_input/index.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/condition_entry_input/index.tsx index d052138d309ac4..f487a38401ef03 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/condition_entry_input/index.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/condition_entry_input/index.tsx @@ -5,7 +5,7 @@ * 2.0. */ -import React, { ChangeEventHandler, memo, useCallback, useMemo } from 'react'; +import React, { ChangeEventHandler, memo, useCallback, useMemo, useState } from 'react'; import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { @@ -100,6 +100,7 @@ export const ConditionEntryInput = memo( 'data-test-subj': dataTestSubj, }) => { const getTestId = useTestIdGenerator(dataTestSubj); + const [isVisited, setIsVisited] = useState(false); const fieldOptions = useMemo>>(() => { const getDropdownDisplay = (field: ConditionEntryField) => ( @@ -155,7 +156,10 @@ export const ConditionEntryInput = memo( if (onVisited) { onVisited(entry); } - }, [entry, onVisited]); + if (!isVisited) { + setIsVisited(true); + } + }, [entry, onVisited, isVisited]); return ( @@ -199,7 +203,7 @@ export const ConditionEntryInput = memo( type: entry.type, })} fullWidth - required + required={isVisited} onChange={handleValueUpdate} onBlur={handleValueOnBlur} data-test-subj={getTestId('value')} diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx index d3b4a541bd18d7..f05d018fe8e9a4 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.test.tsx @@ -153,7 +153,11 @@ describe('When using the Trusted App Form', () => { describe('and the form is rendered', () => { beforeEach(() => render()); - it('should show Name as required', () => { + it('should show Name as required after blur', () => { + expect(getNameField().required).toBe(false); + reactTestingLibrary.act(() => { + fireEvent.blur(getNameField()); + }); expect(getNameField().required).toBe(true); }); @@ -224,7 +228,11 @@ describe('When using the Trusted App Form', () => { ]); }); - it('should show the value field as required', () => { + it('should show the value field as required after blur', () => { + expect(getConditionValue(getCondition()).required).toEqual(false); + reactTestingLibrary.act(() => { + fireEvent.blur(getConditionValue(getCondition())); + }); expect(getConditionValue(getCondition()).required).toEqual(true); }); diff --git a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx index d4f456ab8e0395..da925ddd8a6c18 100644 --- a/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/trusted_apps/view/components/create_trusted_app_form.tsx @@ -478,7 +478,7 @@ export const CreateTrustedAppForm = memo( onChange={handleDomChangeEvents} onBlur={handleDomBlurEvents} fullWidth - required + required={wasVisited?.name} maxLength={256} data-test-subj={getTestId('nameTextField')} /> From 3fb1c1de725f331de881567be7e4e5c45351d558 Mon Sep 17 00:00:00 2001 From: Khristinin Nikita Date: Tue, 26 Oct 2021 10:26:54 +0200 Subject: [PATCH 60/66] New field for integrations field (#116175) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/security_solution/common/cti/constants.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/security_solution/common/cti/constants.ts b/x-pack/plugins/security_solution/common/cti/constants.ts index e63385a15062ff..b33541c5057d8e 100644 --- a/x-pack/plugins/security_solution/common/cti/constants.ts +++ b/x-pack/plugins/security_solution/common/cti/constants.ts @@ -59,11 +59,13 @@ export const DEFAULT_EVENT_ENRICHMENT_FROM = 'now-30d'; export const DEFAULT_EVENT_ENRICHMENT_TO = 'now'; export const CTI_DATASET_KEY_MAP: { [key: string]: string } = { - 'Abuse URL': 'ti_abusech.url', - 'Abuse Malware': 'ti_abusech.malware', - 'Malware Bazaar': 'ti_abusech.malwarebazaar', + 'AbuseCH URL': 'ti_abusech.url', + 'AbuseCH Malware': 'ti_abusech.malware', + 'AbuseCH MalwareBazaar': 'ti_abusech.malwarebazaar', 'AlienVault OTX': 'ti_otx.threat', 'Anomali Limo': 'ti_anomali.limo', - 'Anomali ThreatStream': 'ti_anomali.threatstream', + 'Anomali Threatstream': 'ti_anomali.threatstream', MISP: 'ti_misp.threat', + ThreatQuotient: 'ti_threatq.threat', + Cybersixgill: 'ti_cybersixgill.threat', }; From 32460183831e21eca81403a328ca31456539c2c7 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Tue, 26 Oct 2021 10:29:50 +0200 Subject: [PATCH 61/66] [Uptime] TLS and TLS legacy alert translation mismatch (#116113) --- .../translations/translations/ja-JP.json | 2 -- .../translations/translations/zh-CN.json | 2 -- x-pack/plugins/uptime/common/translations.ts | 24 +++++++++---------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index a8d3b4a5f3e27b..aa1ac61f3b0404 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -25423,7 +25423,6 @@ "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "このアラートで監視されるモニターの条件を示す式", "xpack.uptime.alerts.tls.criteriaExpression.description": "タイミング", "xpack.uptime.alerts.tls.criteriaExpression.value": "任意のモニター", - "xpack.uptime.alerts.tls.defaultActionMessage": "期限切れになるか古くなりすぎた{count} TLS個のTLS証明書証明書を検知しました。\n{expiringConditionalOpen}\n期限切れになる証明書数:{expiringCount}\n期限切れになる証明書:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n{agingConditionalOpen}\n古い証明書数:{agingCount}\n古い証明書:{agingCommonNameAndDate}\n{agingConditionalClose}\n", "xpack.uptime.alerts.tls.description": "アップタイム監視の TLS 証明書の有効期限が近いときにアラートを発行します。", "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "証明書有効期限の TLS アラートをトリガーするしきい値を示す式", "xpack.uptime.alerts.tls.expirationExpression.description": "証明書が", @@ -25432,7 +25431,6 @@ "xpack.uptime.alerts.tls.expiringLabel": "まもなく期限切れ", "xpack.uptime.alerts.tls.invalidLabel": "無効", "xpack.uptime.alerts.tls.legacy.clientName": "アップタイムTLS(レガシー)", - "xpack.uptime.alerts.tls.legacy.defaultActionMessage": "発行者{issuer}の検出されたTLS証明書{commonName}は{status}です。証明書{summary}\n", "xpack.uptime.alerts.tls.legacy.description": "アップタイム監視の TLS 証明書の有効期限が近いときにアラートを発行します。このアラートは将来のバージョンで廃止予定です。", "xpack.uptime.alerts.tls.settingsPageNav.text": "これらのしきい値は{settingsPageLink}で編集できます。", "xpack.uptime.alerts.tls.validAfterExpiredString": "{relativeDate}日前、{date}に期限切れになりました。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 4bd2a5907abf3c..1de08dd3bbd341 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -25854,7 +25854,6 @@ "xpack.uptime.alerts.tls.criteriaExpression.ariaLabel": "显示此告警监视的监测条件的表达式", "xpack.uptime.alerts.tls.criteriaExpression.description": "当", "xpack.uptime.alerts.tls.criteriaExpression.value": "任意监测", - "xpack.uptime.alerts.tls.defaultActionMessage": "已检测到 {count} 个即将过期或即将过时的 TLS 证书。\n{expiringConditionalOpen}\n即将过期的证书计数:{expiringCount}\n即将过期的证书:{expiringCommonNameAndDate}\n{expiringConditionalClose}\n{agingConditionalOpen}\n过时的证书计数:{agingCount}\n过时的证书:{agingCommonNameAndDate}\n{agingConditionalClose}\n", "xpack.uptime.alerts.tls.description": "运行时间监测的 TLS 证书即将过期时告警。", "xpack.uptime.alerts.tls.expirationExpression.ariaLabel": "显示将触发证书过期 TLS 告警的阈值的表达式", "xpack.uptime.alerts.tls.expirationExpression.description": "具有将在", @@ -25863,7 +25862,6 @@ "xpack.uptime.alerts.tls.expiringLabel": "将到期", "xpack.uptime.alerts.tls.invalidLabel": "无效", "xpack.uptime.alerts.tls.legacy.clientName": "Uptime TLS(旧版)", - "xpack.uptime.alerts.tls.legacy.defaultActionMessage": "检测到来自颁发者 {issuer} 的 TLS 证书 {commonName} 的状态为 {status}。证书 {summary}\n", "xpack.uptime.alerts.tls.legacy.description": "运行时间监测的 TLS 证书即将过期时告警。未来的版本将弃用此告警。", "xpack.uptime.alerts.tls.settingsPageNav.text": "可以在 {settingsPageLink}上编辑这些阈值。", "xpack.uptime.alerts.tls.validAfterExpiredString": "已于 {relativeDate} 天前,即 {date}到期。", diff --git a/x-pack/plugins/uptime/common/translations.ts b/x-pack/plugins/uptime/common/translations.ts index 5211438b8ec45d..2b414f22f8c195 100644 --- a/x-pack/plugins/uptime/common/translations.ts +++ b/x-pack/plugins/uptime/common/translations.ts @@ -39,7 +39,7 @@ export const MonitorStatusTranslations = { }; export const TlsTranslations = { - defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.legacy.defaultActionMessage', { + defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.defaultActionMessage', { defaultMessage: `Detected TLS certificate {commonName} from issuer {issuer} is {status}. Certificate {summary} `, values: { @@ -49,17 +49,16 @@ export const TlsTranslations = { status: '{{state.status}}', }, }), - name: i18n.translate('xpack.uptime.alerts.tls.legacy.clientName', { - defaultMessage: 'Uptime TLS (Legacy)', + name: i18n.translate('xpack.uptime.alerts.tls.clientName', { + defaultMessage: 'Uptime TLS', }), - description: i18n.translate('xpack.uptime.alerts.tls.legacy.description', { - defaultMessage: - 'Alert when the TLS certificate of an Uptime monitor is about to expire. This alert will be deprecated in a future version.', + description: i18n.translate('xpack.uptime.alerts.tls.description', { + defaultMessage: 'Alert when the TLS certificate of an Uptime monitor is about to expire.', }), }; export const TlsTranslationsLegacy = { - defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.defaultActionMessage', { + defaultActionMessage: i18n.translate('xpack.uptime.alerts.tls.legacy.defaultActionMessage', { defaultMessage: `Detected {count} TLS certificates expiring or becoming too old. {expiringConditionalOpen} Expiring cert count: {expiringCount} @@ -82,11 +81,12 @@ Aging Certificates: {agingCommonNameAndDate} agingConditionalClose: '{{/state.hasAging}}', }, }), - name: i18n.translate('xpack.uptime.alerts.tls.clientName', { - defaultMessage: 'Uptime TLS', + name: i18n.translate('xpack.uptime.alerts.tls.legacy.clientName', { + defaultMessage: 'Uptime TLS (Legacy)', }), - description: i18n.translate('xpack.uptime.alerts.tls.description', { - defaultMessage: 'Alert when the TLS certificate of an Uptime monitor is about to expire.', + description: i18n.translate('xpack.uptime.alerts.tls.legacy.description', { + defaultMessage: + 'Alert when the TLS certificate of an Uptime monitor is about to expire. This alert will be deprecated in a future version.', }), }; @@ -109,6 +109,6 @@ Response times as high as {slowestAnomalyResponse} have been detected from locat defaultMessage: 'Uptime Duration Anomaly', }), description: i18n.translate('xpack.uptime.alerts.durationAnomaly.description', { - defaultMessage: 'Alert when the Uptime monitor duration is anaomalous.', + defaultMessage: 'Alert when the Uptime monitor duration is anomalous.', }), }; From 73dd334c0963c83b604932696d4ffbdd96617a08 Mon Sep 17 00:00:00 2001 From: Mark Hopkin Date: Tue, 26 Oct 2021 09:33:10 +0100 Subject: [PATCH 62/66] [Fleet] Use data stream name in query to get data stream info (#115805) * reduce number of backing indices we query * remove unused import * revert to using data stream name --- .../server/routes/data_streams/handlers.ts | 26 +++++++------------ 1 file changed, 10 insertions(+), 16 deletions(-) diff --git a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts index 073ff7806d9fed..050b1a2441fede 100644 --- a/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts +++ b/x-pack/plugins/fleet/server/routes/data_streams/handlers.ts @@ -6,7 +6,7 @@ */ import type { estypes } from '@elastic/elasticsearch'; import { keyBy, keys, merge } from 'lodash'; -import type { RequestHandler, SavedObjectsBulkGetObject } from 'src/core/server'; +import type { RequestHandler } from 'src/core/server'; import type { DataStream } from '../../types'; import { KibanaSavedObjectType } from '../../../common'; @@ -15,7 +15,6 @@ import { getPackageSavedObjects } from '../../services/epm/packages/get'; import { defaultIngestErrorHandler } from '../../errors'; const DATA_STREAM_INDEX_PATTERN = 'logs-*-*,metrics-*-*,traces-*-*,synthetics-*-*'; - interface ESDataStreamInfo { name: string; timestamp_field: { @@ -94,17 +93,12 @@ export const getListHandler: RequestHandler = async (context, request, response) const allDashboardSavedObjectsResponse = await context.core.savedObjects.client.bulkGet<{ title?: string; }>( - Object.values(dashboardIdsByPackageName).reduce( - (allDashboards, dashboardIds) => { - return allDashboards.concat( - dashboardIds.map((id) => ({ - id, - type: KibanaSavedObjectType.dashboard, - fields: ['title'], - })) - ); - }, - [] + Object.values(dashboardIdsByPackageName).flatMap((dashboardIds) => + dashboardIds.map((id) => ({ + id, + type: KibanaSavedObjectType.dashboard, + fields: ['title'], + })) ) ); // Ignore dashboards not found @@ -142,12 +136,12 @@ export const getListHandler: RequestHandler = async (context, request, response) const { body: { aggregations: dataStreamAggs }, } = await esClient.search({ - index: dataStream.indices.map((index) => index.index_name), + index: dataStream.name, body: { size: 0, query: { bool: { - must: [ + filter: [ { exists: { field: 'data_stream.namespace', @@ -234,7 +228,7 @@ export const getListHandler: RequestHandler = async (context, request, response) return dataStreamResponse; }); - // Return final data streams objects sorted by last activity, decending + // Return final data streams objects sorted by last activity, descending // After filtering out data streams that are missing dataset/namespace/type fields body.data_streams = (await Promise.all(dataStreamPromises)) .filter(({ dataset, namespace, type }) => dataset && namespace && type) From d7f202937f85ac2af4643e846aee85c61fbb323f Mon Sep 17 00:00:00 2001 From: Esteban Beltran Date: Tue, 26 Oct 2021 10:49:32 +0200 Subject: [PATCH 63/66] [Security Solution] Validate ipv4/CIDR with format x.x.x.x/xx (#116127) --- .../pages/host_isolation_exceptions/utils.ts | 19 ++++++--- .../view/components/form.test.tsx | 39 +++++++++++++------ 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/utils.ts b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/utils.ts index bfb1ac048e2864..aecdfd9f0c4647 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/utils.ts +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/utils.ts @@ -31,11 +31,20 @@ export function createEmptyHostIsolationException(): CreateExceptionListItemSche }; } +/** + * Validates that an IP is a valid ipv4 or CIDR. + * The initial regex validates the format for x.x.x.x/xx + * Then ipaddr is used for a deeper ipv4 validation + */ export function isValidIPv4OrCIDR(maybeIp: string): boolean { - try { - ipaddr.IPv4.parseCIDR(maybeIp); - return true; - } catch (e) { - return ipaddr.IPv4.isValid(maybeIp); + const ipv4re = /^([0-9]{1,3}\.){3}[0-9]{1,3}(\/([0-9]|[1-2][0-9]|3[0-2]))?$/; + if (ipv4re.test(maybeIp)) { + try { + ipaddr.IPv4.parseCIDR(maybeIp); + return true; + } catch (e) { + return ipaddr.IPv4.isValid(maybeIp); + } } + return false; } diff --git a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx index 826f7bf6c4d8a9..eb8294a1f46588 100644 --- a/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx +++ b/x-pack/plugins/security_solution/public/management/pages/host_isolation_exceptions/view/components/form.test.tsx @@ -44,6 +44,7 @@ describe('When on the host isolation exceptions add entry form', () => { newException = createEmptyHostIsolationException(); renderResult = render(newException); }); + it('should render the form with empty inputs', () => { expect(renderResult.getByTestId('hostIsolationExceptions-form-name-input')).toHaveValue(''); expect(renderResult.getByTestId('hostIsolationExceptions-form-ip-input')).toHaveValue(''); @@ -51,20 +52,31 @@ describe('When on the host isolation exceptions add entry form', () => { renderResult.getByTestId('hostIsolationExceptions-form-description-input') ).toHaveValue(''); }); - it('should call onError with true when a wrong ip value is introduced', () => { - const ipInput = renderResult.getByTestId('hostIsolationExceptions-form-ip-input'); - userEvent.type(ipInput, 'not an ip'); - expect(onError).toHaveBeenCalledWith(true); - }); - it('should call onError with false when a correct values are introduced', () => { - const ipInput = renderResult.getByTestId('hostIsolationExceptions-form-ip-input'); - const nameInput = renderResult.getByTestId('hostIsolationExceptions-form-name-input'); - userEvent.type(nameInput, 'test name'); - userEvent.type(ipInput, '10.0.0.1'); + it.each(['not an ip', '100', '900.0.0.1', 'x.x.x.x', '10.0.0'])( + 'should call onError with true when a wrong ip value is introduced. Case: "%s"', + (value: string) => { + const nameInput = renderResult.getByTestId('hostIsolationExceptions-form-name-input'); + const ipInput = renderResult.getByTestId('hostIsolationExceptions-form-ip-input'); + userEvent.type(nameInput, 'test name'); + userEvent.type(ipInput, value); + expect(onError).toHaveBeenCalledWith(true); + } + ); + + it.each(['192.168.0.1', '10.0.0.1', '100.90.1.1/24', '192.168.200.6/30'])( + 'should call onError with false when a correct ip value is introduced. Case: "%s"', + (value: string) => { + const ipInput = renderResult.getByTestId('hostIsolationExceptions-form-ip-input'); + const nameInput = renderResult.getByTestId('hostIsolationExceptions-form-name-input'); + + userEvent.type(nameInput, 'test name'); + userEvent.type(ipInput, value); + + expect(onError).toHaveBeenLastCalledWith(false); + } + ); - expect(onError).toHaveBeenLastCalledWith(false); - }); it('should call onChange when a value is introduced in a field', () => { const ipInput = renderResult.getByTestId('hostIsolationExceptions-form-ip-input'); userEvent.type(ipInput, '10.0.0.1'); @@ -76,6 +88,7 @@ describe('When on the host isolation exceptions add entry form', () => { }); }); }); + describe('When editing an existing exception', () => { let existingException: UpdateExceptionListItemSchema; beforeEach(() => { @@ -96,6 +109,7 @@ describe('When on the host isolation exceptions add entry form', () => { }; renderResult = render(existingException); }); + it('should render the form with pre-filled inputs', () => { expect(renderResult.getByTestId('hostIsolationExceptions-form-name-input')).toHaveValue( 'name edit me' @@ -107,6 +121,7 @@ describe('When on the host isolation exceptions add entry form', () => { renderResult.getByTestId('hostIsolationExceptions-form-description-input') ).toHaveValue('initial description'); }); + it('should call onChange when a value is introduced in a field', () => { const ipInput = renderResult.getByTestId('hostIsolationExceptions-form-ip-input'); userEvent.clear(ipInput); From 8d195db519f1cba6ca49a73a880adbb7855a2d49 Mon Sep 17 00:00:00 2001 From: Lucca Miranda <42002892+luckened@users.noreply.github.com> Date: Tue, 26 Oct 2021 06:01:26 -0300 Subject: [PATCH 64/66] chore: rename getApmHref to getLegacyApmHref (#115689) * chore: rename getApmHref to getLegacyApmHref * chore: lint Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../apm/dev_docs/routing_and_linking.md | 2 +- .../components/app/service_map/Controls.tsx | 4 ++-- .../routing/templates/settings_template.tsx | 20 +++++++++++++------ .../components/shared/Links/apm/APMLink.tsx | 6 +++--- .../Links/apm/agentConfigurationLinks.tsx | 4 ++-- .../Links/apm/transaction_detail_link.tsx | 4 ++-- .../Links/apm/transaction_overview_link.tsx | 4 ++-- .../anomaly_detection_setup_link.tsx | 4 ++-- .../shared/apm_header_action_menu/index.tsx | 4 ++-- .../actions_popover/integration_group.tsx | 4 ++-- .../get_apm_href.test.ts | 10 +++++----- .../observability_integration/get_apm_href.ts | 2 +- .../helper/observability_integration/index.ts | 2 +- 13 files changed, 39 insertions(+), 31 deletions(-) diff --git a/x-pack/plugins/apm/dev_docs/routing_and_linking.md b/x-pack/plugins/apm/dev_docs/routing_and_linking.md index af22bcdbdfa113..a1fdff3821c4c1 100644 --- a/x-pack/plugins/apm/dev_docs/routing_and_linking.md +++ b/x-pack/plugins/apm/dev_docs/routing_and_linking.md @@ -69,7 +69,7 @@ const serviceOverviewLink = apmRouter.link('/services/:serviceName', { path: { s If you're not in React context, you can also import `apmRouter` directly and call its `link` function - but you have to prepend the basePath manually in that case. -We also have the [`getAPMHref` function and `APMLink` component](../public/components/shared/Links/apm/APMLink.tsx), but we should consider them deprecated, in favor of `router.link`. Other components inside that directory contain other functions and components that provide the same functionality for linking to more specific sections inside the APM plugin. +We also have the [`getLegacyApmHref` function and `APMLink` component](../public/components/shared/Links/apm/APMLink.tsx), but we should consider them deprecated, in favor of `router.link`. Other components inside that directory contain other functions and components that provide the same functionality for linking to more specific sections inside the APM plugin. ### Cross-app linking diff --git a/x-pack/plugins/apm/public/components/app/service_map/Controls.tsx b/x-pack/plugins/apm/public/components/app/service_map/Controls.tsx index dd34110a8ffc6d..69644216fc2674 100644 --- a/x-pack/plugins/apm/public/components/app/service_map/Controls.tsx +++ b/x-pack/plugins/apm/public/components/app/service_map/Controls.tsx @@ -12,7 +12,7 @@ import { euiStyled } from '../../../../../../../src/plugins/kibana_react/common' import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; import { useTheme } from '../../../hooks/use_theme'; import { useUrlParams } from '../../../context/url_params_context/use_url_params'; -import { getAPMHref } from '../../shared/Links/apm/APMLink'; +import { getLegacyApmHref } from '../../shared/Links/apm/APMLink'; import { APMQueryParams } from '../../shared/Links/url_helpers'; import { CytoscapeContext } from './Cytoscape'; import { getAnimationOptions, getNodeHeight } from './cytoscape_options'; @@ -112,7 +112,7 @@ export function Controls() { const [zoom, setZoom] = useState((cy && cy.zoom()) || 1); const duration = parseInt(theme.eui.euiAnimSpeedFast, 10); const downloadUrl = useDebugDownloadUrl(cy); - const viewFullMapUrl = getAPMHref({ + const viewFullMapUrl = getLegacyApmHref({ basePath, path: '/service-map', search: `kuery=${encodeURIComponent(kuery)}`, diff --git a/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx b/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx index a76b4647315134..ecca2ddb07ec30 100644 --- a/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx +++ b/x-pack/plugins/apm/public/components/routing/templates/settings_template.tsx @@ -13,7 +13,7 @@ import { useHistory } from 'react-router-dom'; import { CoreStart } from 'kibana/public'; import { ApmMainTemplate } from './apm_main_template'; import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; -import { getAPMHref } from '../../shared/Links/apm/APMLink'; +import { getLegacyApmHref } from '../../shared/Links/apm/APMLink'; type Tab = NonNullable[0] & { key: @@ -69,7 +69,7 @@ function getTabs({ label: i18n.translate('xpack.apm.settings.agentConfig', { defaultMessage: 'Agent Configuration', }), - href: getAPMHref({ + href: getLegacyApmHref({ basePath, path: `/settings/agent-configuration`, search, @@ -80,7 +80,7 @@ function getTabs({ label: i18n.translate('xpack.apm.settings.anomalyDetection', { defaultMessage: 'Anomaly detection', }), - href: getAPMHref({ + href: getLegacyApmHref({ basePath, path: `/settings/anomaly-detection`, search, @@ -92,21 +92,29 @@ function getTabs({ label: i18n.translate('xpack.apm.settings.customizeApp', { defaultMessage: 'Customize app', }), - href: getAPMHref({ basePath, path: `/settings/customize-ui`, search }), + href: getLegacyApmHref({ + basePath, + path: `/settings/customize-ui`, + search, + }), }, { key: 'apm-indices', label: i18n.translate('xpack.apm.settings.indices', { defaultMessage: 'Indices', }), - href: getAPMHref({ basePath, path: `/settings/apm-indices`, search }), + href: getLegacyApmHref({ + basePath, + path: `/settings/apm-indices`, + search, + }), }, { key: 'schema', label: i18n.translate('xpack.apm.settings.schema', { defaultMessage: 'Schema', }), - href: getAPMHref({ basePath, path: `/settings/schema`, search }), + href: getLegacyApmHref({ basePath, path: `/settings/schema`, search }), }, ]; diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx index 7c9f6479bfc6a0..fbf4dff24fbf49 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/APMLink.tsx @@ -54,13 +54,13 @@ export function useAPMHref({ ...query, }; - return getAPMHref({ basePath, path, query: nextQuery, search }); + return getLegacyApmHref({ basePath, path, query: nextQuery, search }); } /** * Get an APM link for a path. */ -export function getAPMHref({ +export function getLegacyApmHref({ basePath, path = '', search, @@ -91,7 +91,7 @@ export function APMLink({ path = '', query, mergeQuery, ...rest }: Props) { const mergedQuery = mergeQuery ? mergeQuery(query ?? {}) : query; - const href = getAPMHref({ basePath, path, search, query: mergedQuery }); + const href = getLegacyApmHref({ basePath, path, search, query: mergedQuery }); return ; } diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/agentConfigurationLinks.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/agentConfigurationLinks.tsx index 58c510eff13a44..c45ab22682ef46 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/agentConfigurationLinks.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/agentConfigurationLinks.tsx @@ -7,14 +7,14 @@ import { IBasePath } from 'kibana/public'; import { AgentConfigurationIntake } from '../../../../../common/agent_configuration/configuration_types'; -import { getAPMHref } from './APMLink'; +import { getLegacyApmHref } from './APMLink'; export function editAgentConfigurationHref( configService: AgentConfigurationIntake['service'], search: string, basePath: IBasePath ) { - return getAPMHref({ + return getLegacyApmHref({ basePath, path: '/settings/agent-configuration/edit', search, diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx index 2f6016466e37e5..06db6c9d423829 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_detail_link.tsx @@ -9,7 +9,7 @@ import React from 'react'; import { useLocation } from 'react-router-dom'; import { EuiLink } from '@elastic/eui'; import { pickBy, identity } from 'lodash'; -import { getAPMHref, APMLinkExtendProps } from './APMLink'; +import { getLegacyApmHref, APMLinkExtendProps } from './APMLink'; import { useUrlParams } from '../../../../context/url_params_context/use_url_params'; import { pickKeys } from '../../../../../common/utils/pick_keys'; import { APMQueryParams } from '../url_helpers'; @@ -43,7 +43,7 @@ export function TransactionDetailLink({ const { urlParams } = useUrlParams(); const { core } = useApmPluginContext(); const location = useLocation(); - const href = getAPMHref({ + const href = getLegacyApmHref({ basePath: core.http.basePath, path: `/services/${serviceName}/transactions/view`, query: { diff --git a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx index e56e4a32d9bad8..d3e40aebc1dafb 100644 --- a/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx +++ b/x-pack/plugins/apm/public/components/shared/Links/apm/transaction_overview_link.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { useLocation } from 'react-router-dom'; import { removeUndefinedProps } from '../../../../context/url_params_context/helpers'; import { useApmPluginContext } from '../../../../context/apm_plugin/use_apm_plugin_context'; -import { APMLinkExtendProps, getAPMHref } from './APMLink'; +import { APMLinkExtendProps, getLegacyApmHref } from './APMLink'; interface Props extends APMLinkExtendProps { serviceName: string; @@ -29,7 +29,7 @@ export function useTransactionsOverviewHref({ const query = { latencyAggregationType, transactionType }; - return getAPMHref({ + return getLegacyApmHref({ basePath: core.http.basePath, path: `/services/${serviceName}/transactions`, query: removeUndefinedProps(query), diff --git a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/anomaly_detection_setup_link.tsx b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/anomaly_detection_setup_link.tsx index 970cc886d30bdb..4891ca896076a8 100644 --- a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/anomaly_detection_setup_link.tsx +++ b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/anomaly_detection_setup_link.tsx @@ -24,7 +24,7 @@ import { useApmParams } from '../../../hooks/use_apm_params'; import { FETCH_STATUS } from '../../../hooks/use_fetcher'; import { useTheme } from '../../../hooks/use_theme'; import { APIReturnType } from '../../../services/rest/createCallApmApi'; -import { getAPMHref } from '../Links/apm/APMLink'; +import { getLegacyApmHref } from '../Links/apm/APMLink'; export type AnomalyDetectionApiResponse = APIReturnType<'GET /internal/apm/settings/anomaly-detection/jobs'>; @@ -47,7 +47,7 @@ export function AnomalyDetectionSetupLink() { return ( {canGetJobs && hasValidLicense ? ( diff --git a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx index 633d03ce8e1df7..655fc2da2b097c 100644 --- a/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/apm_header_action_menu/index.tsx @@ -9,7 +9,7 @@ import { EuiHeaderLink, EuiHeaderLinks } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; import { getAlertingCapabilities } from '../../alerting/get_alerting_capabilities'; -import { getAPMHref } from '../Links/apm/APMLink'; +import { getLegacyApmHref } from '../Links/apm/APMLink'; import { useApmPluginContext } from '../../../context/apm_plugin/use_apm_plugin_context'; import { AlertingPopoverAndFlyout } from './alerting_popover_flyout'; import { AnomalyDetectionSetupLink } from './anomaly_detection_setup_link'; @@ -33,7 +33,7 @@ export function ApmHeaderActionMenu() { const canSaveApmAlerts = capabilities.apm.save && canSaveAlerts; function apmHref(path: string) { - return getAPMHref({ basePath, path, search }); + return getLegacyApmHref({ basePath, path, search }); } function kibanaHref(path: string) { diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx index 2fbb14ea9c2037..5347558ed347e4 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx @@ -11,7 +11,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { IntegrationLink } from './integration_link'; import { - getApmHref, + getLegacyApmHref, getInfraContainerHref, getInfraIpHref, getInfraKubernetesHref, @@ -65,7 +65,7 @@ export const IntegrationGroup = ({ summary }: IntegrationGroupProps) => { description: 'This value is shown to users when they hover over an icon that will take them to the APM app.', })} - href={getApmHref(summary, basePath, dateRangeStart, dateRangeEnd)} + href={getLegacyApmHref(summary, basePath, dateRangeStart, dateRangeEnd)} iconType="apmApp" message={i18n.translate('xpack.uptime.apmIntegrationAction.text', { defaultMessage: 'Show APM Data', diff --git a/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.test.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.test.ts index cc2a88c7ede356..db946fb2469645 100644 --- a/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.test.ts +++ b/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.test.ts @@ -5,10 +5,10 @@ * 2.0. */ -import { getApmHref } from './get_apm_href'; +import { getLegacyApmHref } from './get_apm_href'; import { MonitorSummary, makePing } from '../../../../common/runtime_types'; -describe('getApmHref', () => { +describe('getLegacyApmHref', () => { let summary: MonitorSummary; beforeEach(() => { summary = { @@ -37,14 +37,14 @@ describe('getApmHref', () => { }); it('creates href with base path when present', () => { - const result = getApmHref(summary, 'foo', 'now-15m', 'now'); + const result = getLegacyApmHref(summary, 'foo', 'now-15m', 'now'); expect(result).toMatchInlineSnapshot( `"foo/app/apm#/services?kuery=url.domain:%20%22www.elastic.co%22&rangeFrom=now-15m&rangeTo=now"` ); }); it('does not add a base path or extra slash when base path is empty string', () => { - const result = getApmHref(summary, '', 'now-15m', 'now'); + const result = getLegacyApmHref(summary, '', 'now-15m', 'now'); expect(result).toMatchInlineSnapshot( `"/app/apm#/services?kuery=url.domain:%20%22www.elastic.co%22&rangeFrom=now-15m&rangeTo=now"` ); @@ -57,7 +57,7 @@ describe('getApmHref', () => { }); it('links to the named service', () => { - const result = getApmHref(summary, 'foo', 'now-15m', 'now'); + const result = getLegacyApmHref(summary, 'foo', 'now-15m', 'now'); expect(result).toMatchInlineSnapshot( `"foo/app/apm#/services?kuery=service.name:%20%22${serviceName}%22&rangeFrom=now-15m&rangeTo=now"` ); diff --git a/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts index a4df767ddd7e16..fc5785ceecba1d 100644 --- a/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts +++ b/x-pack/plugins/uptime/public/lib/helper/observability_integration/get_apm_href.ts @@ -8,7 +8,7 @@ import { addBasePath } from './add_base_path'; import { MonitorSummary } from '../../../../common/runtime_types'; -export const getApmHref = ( +export const getLegacyApmHref = ( summary: MonitorSummary, basePath: string, dateRangeStart: string, diff --git a/x-pack/plugins/uptime/public/lib/helper/observability_integration/index.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/index.ts index eeee55c380775d..c739f6d7069230 100644 --- a/x-pack/plugins/uptime/public/lib/helper/observability_integration/index.ts +++ b/x-pack/plugins/uptime/public/lib/helper/observability_integration/index.ts @@ -5,7 +5,7 @@ * 2.0. */ -export { getApmHref } from './get_apm_href'; +export { getLegacyApmHref } from './get_apm_href'; export { getInfraContainerHref, getInfraIpHref, getInfraKubernetesHref } from './get_infra_href'; export { getLoggingContainerHref, From 877db67357fdd0f491a2052e2795eac0d80968ca Mon Sep 17 00:00:00 2001 From: Marta Bondyra Date: Tue, 26 Oct 2021 11:37:49 +0200 Subject: [PATCH 65/66] [Lens] Improve tick placement for binary formatter (#116158) --- .../xy_visualization/expression.test.tsx | 34 +++++++++++++++++++ .../public/xy_visualization/expression.tsx | 8 ++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx index 5f9abba3806cfa..e91f9d54ca86c2 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.test.tsx @@ -1445,6 +1445,40 @@ describe('xy_expression', () => { }); }); + test('sets up correct yScaleType equal to binary_linear for bytes formatting', () => { + const { args, data } = sampleArgs(); + data.tables.first.columns[0].meta = { + type: 'number', + params: { id: 'bytes', params: { pattern: '0,0.00b' } }, + }; + + const wrapper = mountWithIntl( + + ); + + expect(wrapper.find(LineSeries).at(0).prop('yScaleType')).toEqual('linear_binary'); + }); + test('allowBrushingLastHistogramBin should be fakse for ordinal data', () => { const { args, data } = sampleArgs(); diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index 32ca4c982c10e7..a3022e830c8615 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -31,6 +31,7 @@ import { LabelOverflowConstraint, DisplayValueStyle, RecursivePartial, + ScaleType, } from '@elastic/charts'; import { I18nProvider } from '@kbn/i18n/react'; import type { @@ -767,6 +768,8 @@ export function XYChart({ axisConfiguration.series.find((currentSeries) => currentSeries.accessor === accessor) ); + const formatter = table?.columns.find((column) => column.id === accessor)?.meta?.params; + const seriesProps: SeriesSpec = { splitSeriesAccessors: splitAccessor ? [splitAccessor] : [], stackAccessors: isStacked ? [xAccessor as string] : [], @@ -775,7 +778,10 @@ export function XYChart({ yAccessors: [accessor], data: rows, xScaleType: xAccessor ? xScaleType : 'ordinal', - yScaleType, + yScaleType: + formatter?.id === 'bytes' && yScaleType === ScaleType.Linear + ? ScaleType.LinearBinary + : yScaleType, color: ({ yAccessor, seriesKeys }) => { const overwriteColor = getSeriesColor(layer, accessor); if (overwriteColor !== null) { From 0b2d3b7033b876b71b89df763bb68cbff167f68e Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Tue, 26 Oct 2021 04:47:23 -0500 Subject: [PATCH 66/66] Unskip jest handled promise rejections (#116021) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../__jest__/client_integration/home/indices_tab.test.ts | 1 - .../public/components/fleet_package/custom_fields.test.tsx | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts index f95ea373d58b4e..5f5580d2632851 100644 --- a/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts +++ b/x-pack/plugins/index_management/__jest__/client_integration/home/indices_tab.test.ts @@ -22,7 +22,6 @@ import { stubWebWorker } from '@kbn/test/jest'; import { createMemoryHistory } from 'history'; stubWebWorker(); -// unhandled promise rejection https://github.com/elastic/kibana/issues/112699 describe('', () => { let testBed: IndicesTestBed; let server: ReturnType['server']; diff --git a/x-pack/plugins/uptime/public/components/fleet_package/custom_fields.test.tsx b/x-pack/plugins/uptime/public/components/fleet_package/custom_fields.test.tsx index 03bba0f8d2e541..5c24883d588e29 100644 --- a/x-pack/plugins/uptime/public/components/fleet_package/custom_fields.test.tsx +++ b/x-pack/plugins/uptime/public/components/fleet_package/custom_fields.test.tsx @@ -50,8 +50,7 @@ const defaultValidation = centralValidation[DataStream.HTTP]; const defaultHTTPConfig = defaultConfig[DataStream.HTTP]; const defaultTCPConfig = defaultConfig[DataStream.TCP]; -// unhandled promise rejection: https://github.com/elastic/kibana/issues/112699 -describe.skip('', () => { +describe('', () => { const WrappedComponent = ({ validate = defaultValidation, isEditable = false,